2017-04-26 66 views
0

我试图从两个模型输出之间的差异中学习模型。所以我做了如下的代码。但它发生的错误如下:模型的输出张量必须是凯拉斯张量

TypeError:模型的输出张量必须是Keras张量。发现:Tensor(“sub:0”,shape =(?, 10),dtype = float32)

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

Thx提前。

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

这是更好地保持由层完成所有的操作,不减去这样的输出(我不会冒险做的事情隐藏的错误不同于文档所期待的):

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

+0

谢谢!,它的工作原理。我很感激,这将有所帮助。 – semenbari

+1

:) - 此外,对于这个答案不是必需的,但是不像我那样使用'Activation',理解'Lambda'层也是一个好主意。 –

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张量不具有ATTR命名_keras_history等原因。因此,故意添加差异张量可以防止出现上述错误。我检查了原始代码,并且可以学习。