模型的输出张量必须是Keras张量

时间:2017-04-26 12:12:43

标签: python keras deep-learning

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

  

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)

2 个答案:

答案 0 :(得分:3)

最好通过一个图层来完成所有操作,不要减去那样的输出(我不会因为文档的预期不同而冒隐藏的错误):

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(或再次编译以进行培训),从而在完整模型中训练正确的部分。

答案 1 :(得分:0)

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

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张量可以防止上述错误。我检查了原始代码,并且可以学习。