2017-03-07 35 views
2

我有3個keras模型的列表,每個模型的輸出形狀爲(None, 2)。我也有一個通用的keras基礎模型來產生他們的輸入。我的目標是組合4個模型,但僅從列表中的每個模型中獲取第一個輸出(因此最終輸出應該具有形狀(None, 3)。我嘗試使用Lambda圖層從第一個輸出提取第一個輸出時出現問題。每個模型添加Lambda層後無法合併keras模型

如果我省略了LAMBDA步驟,只需如下結合的機型,它創建了一個模型,給出了正確的輸出與形狀(None, 6)

>>> sequentials = [Sequential([base_model, m]) for m in models] 
>>> output = merge([s.output for s in sequentials], mode='concat') 
>>> combined = Model(input=base_model.layers[0].input, output=output) 
>>> combined.predict(X) 
array([[ 8.52127552e-01, 1.47872433e-01, 1.89960217e-13, 
      1.00000000e+00, 7.56258190e-01, 2.43741751e-01]], dtype=float32) 

當我第一次使用lambda出現的問題層提取每個模型的第一個值:

>>> print([m.output_shape for m in models]) 
[(None, 2), (None, 2), (None, 2)] 
>>> for m in models: 
     m.add(Lambda(lambda x: x[0], output_shape=(1,))) 
>>> print([m.output_shape for m in models]) 
[(None, 1), (None, 1), (None, 1)] 
>>> sequentials = [Sequential([base_model, m]) for m in models] 
>>> print([s.output_shape for s in sequentials]) 
[(None, 1), (None, 1), (None, 1)] 
>>> output = merge([s.output for s in sequentials], 
        output_shape=(len(sequentials),), mode='concat') 
>>> combined = Model(base_model.layers[0].input, output=output) 
>>> print(combined.output_shape) 
(None, 3) 
>>> combined.predict(X) 
--------------------------------------------------------------------------- 
ValueError        Traceback (most recent call last) 
<ipython-input-3-4f4ed3bd605d> in <module>() 
----> 1 ann.combined.predict(X) 

./.virtualenvs/py3/lib/python3.4/site-packages/keras/engine/training.py in predict(self, x, batch_size, verbose) 
    1217   f = self.predict_function 
    1218   return self._predict_loop(f, ins, 
-> 1219         batch_size=batch_size, verbose=verbose) 
    1220 
    1221  def train_on_batch(self, x, y, 

./.virtualenvs/py3/lib/python3.4/site-packages/keras/engine/training.py in _predict_loop(self, f, ins, batch_size, verbose) 
    904 
    905    for i, batch_out in enumerate(batch_outs): 
--> 906     outs[i][batch_start:batch_end] = batch_out 
    907    if verbose == 1: 
    908     progbar.update(batch_end) 

ValueError: could not broadcast input array from shape (6) into shape (1) 

什麼是正確的方式來合併這些模型,而只是從每一個單一的輸出值?

注意,我可以成功地使用lambda函數,如果我申請它合併型號如下:

>>> sequentials = [Sequential([base_model, m]) for m in models] 
>>> output = merge([s.output for s in sequentials], mode='concat') 
>>> filtered = Lambda(lambda x: x[:,::2], lambda s: (s[-1]/2,))(output) 
>>> combined = Model(input=base_model.layers[0].input, output=filtered) 
>>> combined.predict(X) 
array([[ 1.89960217e-13, 7.56258249e-01, 8.52127552e-01]], type=float32) 

但我想知道如何在合併之前應用它

+0

你是否在某一點編譯模型?不知道它是否會改變任何東西,但它只是一個想法 –

+0

不,這些模型都是從文件中加載的(它們在保存之前進行了編譯和訓練)。 – bogatron

+0

嘗試'm.add(Lambda(lambda x:x [:,0],output_shape =(1,)))' –

回答

3

這個問題在Lambda切片中有點不一致。儘管輸出的shape沒有考慮到batch尺寸 - 人們應該記住提供給Lambda圖層的tensor也具有此額外尺寸。這就是爲什麼以下行導致的錯誤:

m.add(Lambda(lambda x: x[0], output_shape=(1,))) 

這應改爲:

m.add(Lambda(lambda x: x[:,:1], output_shape=(1,))) 

當心切片的方式如下:

m.add(Lambda(lambda x: x[:,0], output_shape=(1,)))

,因爲它改變維度爲tensor