【问题标题】:Unable to merge keras models after adding Lambda layer添加 Lambda 层后无法合并 keras 模型
【发布时间】:2017-07-27 21:20:29
【问题描述】:

我有 3 个 keras 模型的列表,每个模型的输出形状为 (None, 2)。我也有一个通用的 keras 基础模型来产生他们的输入。我的目标是组合这 4 个模型,但只从列表中的每个模型中获取第一个输出(因此最终输出的形状应该是 (None, 3)。当我尝试使用 Lambda 层提取第一个时出现问题每个模型的输出。

如果我省略 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)

但我想知道如何在合并之前应用它。

【问题讨论】:

  • 你会在某个时候编译模型吗?不确定它是否会改变任何东西,但这只是一个想法
  • 不,模型都是从文件中加载的(它们是在保存之前编译和训练的)。
  • 试试m.add(Lambda(lambda x: x[:,0], output_shape=(1,)))
  • @MarcinMożejko 你很亲密。这会将错误更改为ValueError: could not broadcast input array from shape (3) into shape (1)。如果我使用lambda x: x[:,:1],它会成功运行。既然你让我朝着正确的方向前进,请随时发布作为答案(最好有解释),我会接受。谢谢!
  • 对了。我认为m.add(Lambda(lambda x: x[:,[0]], output_shape=(1,))) 也应该可以正常工作。

标签: python machine-learning neural-network keras keras-layer


【解决方案1】:

问题在于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 的维度。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-27
    • 2019-03-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多