我有一个Keras模型,我想在其中添加一个常数到预测中。经过一番谷歌搜索后,我得到了以下代码,该代码完全符合我的要求:
import numpy as np
from keras.layers import Input, Add
from keras.backend import variable
from keras.models import Model, load_model
inputs = Input(shape=(1,))
add_in = Input(tensor=variable([[5]]), name='add')
output = Add()([inputs, add_in])
model = Model([inputs, add_in], output)
model.compile(loss='mse', optimizer='adam')
X = np.array([1,2,3,4,5,6,7,8,9,10])
model.predict(X)
但是,如果我保存并加载此模型,Keras似乎会失去对常数的跟踪:
p = 'k_model.hdf5'
model.save(p)
del model
model2 = load_model(p)
model2.predict(X)
哪个返回:
检查模型时出错:您正在使用的Numpy数组列表 传递给您的模型不是模型期望的大小。预期 查看2个数组,但得到以下1个数组的列表:
在保存/加载Keras模型时如何包含常量?
答案 0 :(得分:1)
由于如前所述,它始终是常量,因此没有必要为其定义单独的Input层;特别考虑到它不是模型的输入。我建议您改用Lambda
层:
import numpy as np
from keras.layers import Input, Lambda
from keras.models import Model, load_model
def add_five(a):
return a + 5
inputs = Input(shape=(1,))
output = Lambda(add_five)(inputs)
model = Model(inputs, output)
model.compile(loss='mse', optimizer='adam')
X = np.array([1,2,3,4,5,6,7,8,9,10])
model.predict(X)
输出:
array([[ 6.],
[ 7.],
[ 8.],
[ 9.],
[10.],
[11.],
[12.],
[13.],
[14.],
[15.]], dtype=float32)
由于add_five
函数已存储在模型文件中,因此保存并重新加载模型不会有问题。
更新:您可以将其扩展到每个输入样本包含多个元素的情况。例如,如果输入形状为(2,)
,并且您想将5添加到每个样本的第一个元素,将10添加到第二个元素,则可以轻松地修改add_five
函数并重新定义它,如下所示:
def add_constants(a):
return a + [5, 10]
# ... the same as above (just change the function name and input shape)
X = np.array([1,2,3,4,5,6,7,8,9,10]).reshape(5, 2)
model.predict(X)
输出:
# X
array([[ 1, 2],
[ 3, 4],
[ 5, 6],
[ 7, 8],
[ 9, 10]])
# predictions
array([[ 6., 12.],
[ 8., 14.],
[10., 16.],
[12., 18.],
[14., 20.]], dtype=float32)