2017-04-26 36 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等原因。因此,故意添加差異張量可以防止出現上述錯誤。我檢查了原始代碼,並且可以學習。