2017-03-07 108 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