2017-01-12 78 views
2

在keras中,我想訓練共享某些圖層的模型集合。它們是以下形式的:共享圖層模型集合

X ---> F(X)---> G_1(F(X))

X ---> F(X)---> G_2( F(X))

...

X ---> F(X)---> G_N(F(X))

這裏F(X)是一些非平凡的共享層。 g_1到g_n具有它們的特定參數。

在每個訓練階段,數據x被饋送到n個網絡之一,比如第i個網絡。然後通過基於梯度的優化器使g_i(f(x))上的損失最小化/減小。我怎樣才能定義和訓練這樣一個模型?

在此先感謝!

回答

7

您可以輕鬆地使用功能模型來做到這一點。

一個小例子..你可以建立在它:

import numpy as np 
from keras.models import Model 
from keras.layers import Dense, Input 

X = np.empty(shape=(1000,100)) 
Y1 = np.empty(shape=(1000)) 
Y2 = np.empty(shape=(1000,2)) 
Y3 = np.empty(shape=(1000,3)) 

inp = Input(shape=(100,)) 
dense_f1 = Dense(50) 
dense_f2 = Dense(20) 

f = dense_f2(dense_f1(inp)) 

dense_g1 = Dense(1) 
g1 = dense_g1(f) 

dense_g2 = Dense(2) 
g2 = dense_g2(f) 

dense_g3 = Dense(3) 
g3 = dense_g3(f) 


model = Model([inp], [g1, g2, g3]) 
model.compile(loss=['mse', 'binary_crossentropy', 'categorical_crossentropy'], optimizer='rmsprop') 

model.summary() 

model.fit([X], [Y1, Y2, Y3], nb_epoch=10) 

編輯:

根據您的意見,你自己根據你怎麼總是可以使不同的車型,寫訓練循環你需要你的訓練。您可以在model.summary()中看到所有模型都共享最初的圖層。這裏是示例的擴展

model1 = Model(inp, g1) 
model1.compile(loss=['mse'], optimizer='rmsprop') 
model2 = Model(inp, g2) 
model2.compile(loss=['binary_crossentropy'], optimizer='rmsprop') 
model3 = Model(inp, g3) 
model3.compile(loss=['categorical_crossentropy'], optimizer='rmsprop') 
model1.summary() 
model2.summary() 
model3.summary() 

batch_size = 10 
nb_epoch=10 
n_batches = X.shape[0]/batch_size 


for iepoch in range(nb_epoch): 
    for ibatch in range(n_batches): 
     x_batch = X[ibatch*batch_size:(ibatch+1)*batch_size] 
     if ibatch%3==0: 
      y_batch = Y1[ibatch*batch_size:(ibatch+1)*batch_size] 
      model1.train_on_batch(x_batch, y_batch)  
     elif ibatch%3==1: 
      y_batch = Y2[ibatch*batch_size:(ibatch+1)*batch_size] 
      model2.train_on_batch(x_batch, y_batch)  
     else: 
      y_batch = Y3[ibatch*batch_size:(ibatch+1)*batch_size] 
      model3.train_on_batch(x_batch, y_batch)  
+0

感謝您的回覆!這是有益的,但仍不能完全解決問題。 在你的例子中,我希望X的每個minibatch只能通過三條管道中的一條被推送。換句話說,有一個指標變量可以選擇三種損失之一。 – wolfustc

+1

根據評論更新。 – indraforyou

+0

這真是太棒了!非常感謝!另一個擔憂:我認爲train_on_batch()只需要一個SGD步驟,而不需要使用更好的優化技術,例如動量SGD。是否有可能改爲調用model_i.fit(x_batch_i,y_batch_i,optimizer ='fancier optimizer'),其中i = 1,2,3。在這種情況下我擔心的是:這三個獨立的調用是否共享相同的內部優化器狀態(例如動量速度SGD)在我看來,分享這些狀態是應該如何進行優化。 – wolfustc