Tensorflow 在模型定义中使用循环和Lambda层时,Keras load_模型错误
下面给出了一个最小的示例Tensorflow 在模型定义中使用循环和Lambda层时,Keras load_模型错误,tensorflow,keras,Tensorflow,Keras,下面给出了一个最小的示例 from keras.models import Model from keras.layers import Dense, Input, Lambda, Concatenate from keras.models import load_model from keras.optimizers import Adam def build_model_with_loop(): x = Input(shape=(22,), name='inputs')
from keras.models import Model
from keras.layers import Dense, Input, Lambda, Concatenate
from keras.models import load_model
from keras.optimizers import Adam
def build_model_with_loop():
x = Input(shape=(22,), name='inputs')
# 2 branches
xls = [[] for i in range(2)]
branch = [[0,10],[10,22]]
for _i, (b, e) in enumerate(branch):
xls[_i] = Lambda(lambda x: x[:, b:e])(x)
c = Concatenate()(xls)
y = Dense(1)(c)
model = Model(inputs=x, outputs=y)
model.compile(loss='mse', optimizer=Adam(1E-3))
return model
def build_model_without_loop():
x = Input(shape=(22,), name='inputs')
# 2 branches
xls = [[] for i in range(2)]
xls[0] = Lambda(lambda x: x[:, 0:10])(x)
xls[1] = Lambda(lambda x: x[:, 10:22])(x)
c = Concatenate()(xls)
y = Dense(1)(c)
model = Model(inputs=x, outputs=y)
model.compile(loss='mse', optimizer=Adam(1E-3))
return model
model = build_model_without_loop()
model.save('model_test.h5')
model = load_model('model_test.h5')
Traceback (most recent call last):
File "/home/junjiechen/.pyenv/versions/3.6.5/lib/python3.6/site-packages/tensorflow/python/framework/ops.py", line 1659, in _create_c_op
c_op = c_api.TF_FinishOperation(op_desc)
tensorflow.python.framework.errors_impl.InvalidArgumentError: Dimension 0 in both shapes must be equal, but are 24 and 22. Shapes are [24,1] and [22,1]. for 'Assign' (op: 'Assign') with input shapes: [24,1], [22,1].
ValueError: Dimension 0 in both shapes must be equal, but are 24 and 22. Shapes are [24,1] and [22,1]. for 'Assign' (op: 'Assign') with input shapes: [24,1], [22,1].
这个模型很简单。输入形状为[batch\u size,22]
,模型将首先将输入分成两个分支,分别为[batch\u size,10]
和[batch\u size,12]
。这里我们使用keras中的Lambda
层来进行分离。但是,如果我们在模型定义中使用for
循环,则加载\模型
无法正确加载保存的模型模型
。错误消息如下所示
from keras.models import Model
from keras.layers import Dense, Input, Lambda, Concatenate
from keras.models import load_model
from keras.optimizers import Adam
def build_model_with_loop():
x = Input(shape=(22,), name='inputs')
# 2 branches
xls = [[] for i in range(2)]
branch = [[0,10],[10,22]]
for _i, (b, e) in enumerate(branch):
xls[_i] = Lambda(lambda x: x[:, b:e])(x)
c = Concatenate()(xls)
y = Dense(1)(c)
model = Model(inputs=x, outputs=y)
model.compile(loss='mse', optimizer=Adam(1E-3))
return model
def build_model_without_loop():
x = Input(shape=(22,), name='inputs')
# 2 branches
xls = [[] for i in range(2)]
xls[0] = Lambda(lambda x: x[:, 0:10])(x)
xls[1] = Lambda(lambda x: x[:, 10:22])(x)
c = Concatenate()(xls)
y = Dense(1)(c)
model = Model(inputs=x, outputs=y)
model.compile(loss='mse', optimizer=Adam(1E-3))
return model
model = build_model_without_loop()
model.save('model_test.h5')
model = load_model('model_test.h5')
Traceback (most recent call last):
File "/home/junjiechen/.pyenv/versions/3.6.5/lib/python3.6/site-packages/tensorflow/python/framework/ops.py", line 1659, in _create_c_op
c_op = c_api.TF_FinishOperation(op_desc)
tensorflow.python.framework.errors_impl.InvalidArgumentError: Dimension 0 in both shapes must be equal, but are 24 and 22. Shapes are [24,1] and [22,1]. for 'Assign' (op: 'Assign') with input shapes: [24,1], [22,1].
ValueError: Dimension 0 in both shapes must be equal, but are 24 and 22. Shapes are [24,1] and [22,1]. for 'Assign' (op: 'Assign') with input shapes: [24,1], [22,1].
然而,如果我们使用构建模型而不使用循环
,那么一切都会顺利进行。如何解决此问题并在模型定义中正确使用循环
事实上,问题也可能来自
Lambda
层。如果两个分支具有相同的维度[batch\u size,11]
,则不会发生错误。解决方案是在Lambda
层中使用参数选项,以便正确传递相应的参数。事实上,上面显示的问题是由于python的lambda
函数造成的
def build_model_with_loop():
x = Input(shape=(22,), name='inputs')
# 2 branches
xls = [[] for i in range(2)]
branch = [[0,10],[10,22]]
def get_branch(x, beg, end):
return x[:, beg:end]
for i, (b, e) in enumerate(branch):
xls[i] = Lambda(get_branch, arguments={'beg':b, 'end':e})(x)
c = Concatenate()(xls)
y = Dense(1)(c)
model = Model(inputs=x, outputs=y)
model.compile(loss='mse', optimizer=Adam(1E-3))
return model
在这里,我们定义get_分支
函数包装器,并通过Lambda
层中的arguments
选项传递beg
和end