2017-08-29 9 views
1

私はケラスで最初のアンサンブルモデルを作成しようとしています。私は私のデータセットに3つの入力値と1つの出力値を持っています。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)がエラーなしでコンパイルが、モデルをフィッティングしながら私は、同じ入力を2回model3.fit([X,X],y)を通過しなければなりません。これは不必要なステップだと思います。入力を2回繰り返すのではなく、アンサンブルモデルに共通の入力ノードが必要です。どうしたらいいですか?

答えて

3

ケラス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の)1回だけ呼び出されているので、model3の設定と同じ設定がモデル全体に​​適用されます。サブモデルを訓練するときに異なる設定をするためには、別々にフィット()する必要があります。 @Danielによるコメントを参照してください。

編集:コメントに基づいて更新ノート

+0

モデルのコンパイル(オプティマイザとロス)は、その特定のものに** fitを使用した場合にのみ考慮されます(テストされていません)モデル**。 'model3' **に** fitを使用している場合、' model3'のコンパイルだけが有効になります。 --- 'model1'と' model2'をコンパイルする必要はありません。( 'model1.fit'と' model2.fit'を使って)それらを別々に訓練する場合を除きます。重みと予測は 'compile'を必要としません。 –

2

etovの答えは素晴らしい選択肢です。

しかし、あなたはすでにMODEL1とMODEL2準備を持っており、あなたがそれらを変更したくない、あなたはこのような3番目のモデルを作成することができたとします

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

これは実際には良い選択です。実際には、入力レイヤーが埋め込みであることを除いて、2つの方法がほぼ同等であると私は考えています。その場合、共通の入力レイヤーを使用する場合とモデルごとに異なるレイヤーを使用する場合があります(どちらも有効です - 正しい選択はアプリケーションによって異なります) – etov

関連する問題