【问题标题】:Output tensors to a Model must be Keras tensors模型的输出张量必须是 Keras 张量
【发布时间】:2017-09-23 20:06:51
【问题描述】:

我试图让模型从两个模型输出之间的差异中学习。所以我做了如下代码。但它发生错误读取:

TypeError:模型的输出张量必须是 Keras 张量。成立: 张量("sub:0", shape=(?, 10), dtype=float32)

我找到了包括lambda在内的相关答案,但我无法解决这个问题。 有谁知道这个问题? 可能会看到将张量转换为 keras 的张量。

提前致谢。

from keras.layers import Dense
from keras.models import Model
from keras.models import Sequential

left_branch = Sequential()
left_branch.add(Dense(10, input_dim=784))

right_branch = Sequential()
right_branch.add(Dense(10, input_dim=784))

diff = left_branch.output - right_branch.output

model = Model(inputs=[left_branch.input, right_branch.input], outputs=[diff])
model.compile(optimizer='rmsprop', loss='binary_crossentropy', loss_weights=[1.])

model.summary(line_length=150)

【问题讨论】:

    标签: python keras deep-learning


    【解决方案1】:

    最好让所有操作都由一个层完成,不要像那样减去输出(我不会因为做与文档预期不同的事情而冒隐藏错误的风险):

    from keras.layers import *
    
    def negativeActivation(x):
        return -x
    
    left_branch = Sequential()
    left_branch.add(Dense(10, input_dim=784))
    
    right_branch = Sequential()
    right_branch.add(Dense(10, input_dim=784))
    
    negativeRight = Activation(negativeActivation)(right_branch.output) 
    diff = Add()([left_branch.output,negativeRight])
    
    model = Model(inputs=[left_branch.input, right_branch.input], outputs=diff)
    model.compile(optimizer='rmsprop', loss='binary_crossentropy', loss_weights=[1.])
    

    当加入这样的模型时,我更喜欢使用带有层的Model 方式,而不是使用Sequential

    def negativeActivation(x):
        return -x
    
    leftInput = Input((784,))
    rightInput = Input((784,))
    
    left_branch = Dense(10)(leftInput) #Dense(10) creates a layer
    right_branch = Dense(10)(rightInput) #passing the input creates the output
    
    negativeRight = Activation(negativeActivation)(right_branch) 
    diff = Add()([left_branch,negativeRight])
    
    model = Model(inputs=[leftInput, rightInput], outputs=diff)
    model.compile(optimizer='rmsprop', loss='binary_crossentropy', loss_weights=[1.])
    

    这样,您可以创建具有相同层的其他模型,它们将共享相同的权重:

    leftModel = Model(leftInput,left_branch)
    rightModel = Model(rightInput,right_branch)
    fullModel = Model([leftInput,rightInput],diff)
    

    如果他们共享同一层,则训练其中一个会影响其他人。 例如,您可以通过在编译之前创建left_branch.trainable = False 来训练完整模型中的正确部分(或再次编译以进行训练)。

    【讨论】:

    • :) -- 另外,这个答案不是必需的,但不要像我那样使用Activation,了解Lambda 层也是一个好主意。
    【解决方案2】:

    我想我解决了这个问题,但它可能是精确的解决方案。 我添加了一些如下代码:

    diff = left_branch.output - right_branch.output
    setattr(diff, '_keras_history', getattr(right_branch.output, '_keras_history'))
    setattr(diff, '_keras_shape', getattr(right_branch.output, '_keras_shape'))
    setattr(diff, '_uses_learning_phase', getattr(right_branch.output, '_uses_learning_phase'))
    

    出现错误的原因是 diff tensor 没有名为 _keras_history 的 attr 等等。因此,有意将它们添加到 diff 张量可以防止上述错误。我检查了原始代码运行并可以学习。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-11-15
      • 1970-01-01
      • 2019-12-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-10-13
      • 1970-01-01
      相关资源
      最近更新 更多