无法加载和使用多个 keras 模型
Posted
技术标签:
【中文标题】无法加载和使用多个 keras 模型【英文标题】:Unable to load and use multiple keras models 【发布时间】:2018-05-03 19:05:38 【问题描述】:我正在尝试在同一进程中加载三个不同的模型。只有第一个按预期工作,其余的返回随机结果。 基本上顺序如下:
定义和编译第一个模型 之前加载经过训练的权重 重命名图层 第二个模型的相同过程 第三个模型的过程相同所以,类似:
model1 = Model(inputs=Input(shape=input_size_im) , outputs=layers_firstmodel)
model1.compile(optimizer='sgd', loss='mse')
model1.load_weights(weights_first, by_name=True)
# rename layers but didn't work
model2 = Model(inputs=Input(shape=input_size_im) , outputs=layers_secondmodel)
model2.compile(optimizer='sgd', loss='mse')
model2.load_weights(weights_second, by_name=True)
# rename layers but didn't work
model3 = Model(inputs=Input(shape=input_size_im) , outputs=layers_thirdmodel)
model3.compile(optimizer='sgd', loss='mse')
model3.load_weights(weights_third, by_name=True)
# rename layers but didn't work
for im in list_images:
results_firstmodel = model1.predict(im)
results_secondmodel = model2.predict(im)
results_thirdmodel = model2.predict(im)
我想对一堆图像进行一些推断。为此,想法在于循环图像并使用这三种算法进行推理,然后返回结果。
我尝试重命名所有图层以使它们独一无二,但没有成功。我还为每个网络创建了不同的图表,并使用不同的会话进行推理。这可行,但效率很低(此外,我每次都必须设置它们的权重,因为sess.run(tf.global_variables_initializer())
删除了它们)。每次创建会话时,tensorflow 都会打印“正在创建 tensorflow 设备 (/device:GPU:0)”。
我正在运行 Tensorflow 1.4.0-rc0、Keras 2.1.1 和 Ubuntu 16.04 内核 4.14。
【问题讨论】:
定义随机结果。他们仍然是概率吗?输出与仅加载一个模型而不是全部 3 个不同吗? 嗨 Vivek,是的,如果我只加载一个模型,则输出与加载多个模型时的输出不同(仍然是概率,但每次运行脚本时,除了加载的第一个模型之外,我得到的结果不同)。非常感谢您的回答 我遇到了这个问题,看起来 model.load_weights 命令覆盖了之前加载的权重,所以只有最后一个模型对我来说很好用。我通过单独运行多个 python 进程做了一个解决方法,但这对于较小的应用程序来说工作量太大。 【参考方案1】:这里的 OP 是正确的。当您尝试在同一个脚本中加载多个权重文件时,会出现严重错误。上面的答案并没有解决这个问题。如果您在同一脚本中为多个模型加载权重时实际询问权重,您会注意到权重与仅为一个模型单独加载权重时不同。这就是 OP 观察到的随机性的来源。
编辑:要解决此问题,您必须将 model.load_weight 命令封装在一个函数中,并且您遇到的随机性应该消失。问题是,当您在同一个脚本中使用多个 load_weight 命令时,会出现一些奇怪的问题,就像上面一样。如果您使用函数加载这些模型权重,则问题应该消失。
【讨论】:
【参考方案2】:来自 Keras docs 我们对load_weights
的用户有这样的解释:
从 HDF5 文件(由 save_weights 创建)加载模型的权重。默认情况下,架构预计不会改变。要将权重加载到不同的架构中(某些层共有),使用 by_name=True 仅加载那些具有相同名称的层。
因此,如果您的架构未更改,则应删除by_name=True
或将其改为False
(其默认值)。这可能会导致您面临的不一致,因为您的权重没有被加载可能是因为您的图层上有不同的名称。
另一个需要考虑的重要事项是您的 HDF5 文件的性质以及您创建它的方式。如果它确实只包含权重(正如文档指出的那样,使用 save_weights
创建),那么按照前面的解释进行操作应该没有问题。
现在,如果 HDF5 在同一个文件中包含权重和架构,那么您应该使用keras.models.load_model
来加载它(如果您喜欢here,请进一步阅读)。如果是这种情况,那么这也可以解释这些不一致之处。
作为附带建议,如果您想自动确定何时停止训练,我更喜欢使用 Callbacks 保存我的模型,例如 ModelCheckpoint
或 EarlyStopping
。这不仅在训练和保存模型时为您提供了更大的灵活性(因为您可以在最佳训练时期或在您需要时停止它们),而且还可以轻松加载这些模型,因为您可以简单地使用 load_model
方法来加载将架构和权重都设置为您想要的变量。
最后,here 是一篇有用的 SO 帖子,其中解释了保存(和加载)Keras 模型。
【讨论】:
非常感谢您的回答。只有当我在同一个脚本中加载多个模型时,我才在仅加载一个模型(无论是哪一个)时使用 load_weights 没有问题。实际上,我使用by_name=True
仅对某些层赋予权重。以上是关于无法加载和使用多个 keras 模型的主要内容,如果未能解决你的问题,请参考以下文章
无法使用 keras.models.load_model() 加载 TF 变压器模型
无法从 tensorflow/keras 中的加载模型中获取梯度