添加 Lambda 层后无法合并 keras 模型
Unable to merge keras models after adding Lambda layer
我有一个包含 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)
但我想知道如何在合并之前应用它。
问题出在 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
.
的维数
我有一个包含 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)
但我想知道如何在合并之前应用它。
问题出在 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
.