2017-08-29 137 views
1

我想在keras中創建我的第一個合奏模型。我的數據集中有3個輸入值和一個輸出值。如何合併具有相同輸入的keras連續模型?

from keras.optimizers import SGD,Adam 
from keras.layers import Dense,Merge 
from keras.models import Sequential 

model1 = Sequential() 
model1.add(Dense(3, input_dim=3, activation='relu')) 
model1.add(Dense(2, activation='relu')) 
model1.add(Dense(2, activation='tanh')) 
model1.compile(loss='mse', optimizer='Adam', metrics=['accuracy']) 

model2 = Sequential() 
model2.add(Dense(3, input_dim=3, activation='linear')) 
model2.add(Dense(4, activation='tanh')) 
model2.add(Dense(3, activation='tanh')) 
model2.compile(loss='mse', optimizer='SGD', metrics=['accuracy']) 

model3 = Sequential() 
model3.add(Merge([model1, model2], mode = 'concat')) 
model3.add(Dense(1, activation='sigmoid')) 
model3.compile(loss='binary_crossentropy', optimizer='Adam', metrics=['accuracy']) 

model3.input_shape 

該整體模型(model3)編譯沒有任何錯誤,但同時擬合模型我必須通過相同的輸入兩次model3.fit([X,X],y)。我認爲這是一個不必要的步驟,而不是兩次傳入輸入,我想爲我的集合模型提供一個通用輸入節點。我該怎麼做?

回答

3

Keras functional API似乎更適合您的用例,因爲它允許在計算圖中具有更大的靈活性。例如:

from keras.layers import concatenate 
from keras.models import Model 
from keras.layers import Input, Merge 
from keras.layers.core import Dense 
from keras.layers.merge import concatenate 

# a single input layer 
inputs = Input(shape=(3,)) 

# model 1 
x1 = Dense(3, activation='relu')(inputs) 
x1 = Dense(2, activation='relu')(x1) 
x1 = Dense(2, activation='tanh')(x1) 

# model 2 
x2 = Dense(3, activation='linear')(inputs) 
x2 = Dense(4, activation='tanh')(x2) 
x2 = Dense(3, activation='tanh')(x2) 

# merging models 
x3 = concatenate([x1, x2]) 

# output layer 
predictions = Dense(1, activation='sigmoid')(x3) 

# generate a model from the layers above 
model = Model(inputs=inputs, outputs=predictions) 
model.compile(optimizer='adam', 
       loss='binary_crossentropy', 
       metrics=['accuracy']) 

# Always a good idea to verify it looks as you expect it to 
# model.summary() 

data = [[1,2,3], [1,1,3], [7,8,9], [5,8,10]] 
labels = [0,0,1,1] 

# The resulting model can be fit with a single input: 
model.fit(data, labels, epochs=50) 

注:

  • 可能存在Keras版本之間的API(前和後第2版)
  • 上面的例子指定了不同的優化和損失函數中的輕微差異每個模型。但是,由於fit()僅被調用一次(在model3上),相同的設置(即model3的設置)將應用於整個模型。爲了在訓練子模型時有不同的設置,他們必須分別適合() - 請參閱@Daniel的評論。

編輯:基於註釋更新筆記

+0

彙編(優化和損失)的模型中,當您使用**'fit'針對特定只考慮模型**。如果在'model3' **中使用**'fit',則只有'model3'的編譯生效。 ---除非你要單獨訓練(使用'model1.fit'和'model2.fit'),否則根本不需要編譯'model1'和'model2'。權重和預測不需要「編譯」。 –

2

etov的回答是一個很好的選擇。

但是,假設你已經有了MODEL1和MODEL2準備好,你不想改變他們,你可以創建第三種模式是這樣的:

singleInput = Input((3,)) 
out1 = model1(singleInput) 
out2 = model2(singleInput) 

out3 = Concatenate()([out1,out2]) 
out3 = Dense(1, activation='sigmoid')(out3) 

model3 = Model(singleInput,out3) 

如果你已經擁有了所有的模型準備和唐「不想改變他們,你可以有這樣的事情(未測試):

singleInput = Input((3,)) 
output = model3([singleInput,singleInput]) 
singleModel = Model(singleInput,output) 
+0

這確實是一個很好的選擇,實際上我認爲兩種方式幾乎是等價的,除了輸入層是一個嵌入。在這種情況下,使用通用輸入層而不是每個模型使用不同的輸入層會產生變化(兩者都是有效的 - 正確的選擇取決於應用程序) – etov