使用 Keras 加载之前保存的重新训练的 VGG16 模型时出现 ValueError

2024-03-18

我在 Keras 中使用 VGG16 架构,我通过以下方式对其进行了重新训练以满足我的需求:

vgg16_model = keras.applications.vgg16.VGG16()
model = Sequential()
for layer in vgg16_model.layers:
    model.add(layer)


model.layers.pop()
for layer in model.layers:
    layer.trainable = False

model.add(Dense(3, activation='softmax'))

model.compile(Adam(lr=.0001), loss='categorical_crossentropy', metrics=['accuracy'])

接下来,我训练模型,然后按照 keras 文档中建议的方式保存整个模型:

from keras.models import load_model

model.save('my_model_vgg16.h5')  # creates a HDF5 file

加载模型时,如下所示:

model = load_model('my_model_vgg16.h5')

在 Jupyter Notebook 中使用经过训练的模型非常有魅力。但是,当我在重新启动内核后尝试加载保存的模型时,出现以下错误:

ValueError: Dimension 0 in both shapes must be equal, but are 4096 and 1000 for 'Assign_30' (op: 'Assign') with input shapes: [4096,3], [1000,3].

我无法弄清楚为什么会发生此错误,因为在保存和加载期间我既没有更改模型/图层的输入也没有更改输出大小。

出于测试目的,我尝试使用一个更简单的顺序模型,该模型是我在同一管道中从头开始构建的(即相同的保存和加载过程),这不会给我带来错误。因此,我想知道在使用预训练模型(保存和加载它)时是否缺少一些东西。

作为参考,整个控制台错误日志如下所示:

---------------------------------------------------------------------------
InvalidArgumentError                      Traceback (most recent call last)
~\Anaconda2\envs\tensorflow-gpu\lib\site-packages\tensorflow\python\framework\common_shapes.py in _call_cpp_shape_fn_impl(op, input_tensors_needed, input_tensors_as_shapes_needed, require_shape_fn)
    685           graph_def_version, node_def_str, input_shapes, input_tensors,
--> 686           input_tensors_as_shapes, status)
    687   except errors.InvalidArgumentError as err:

~\Anaconda2\envs\tensorflow-gpu\lib\site-packages\tensorflow\python\framework\errors_impl.py in __exit__(self, type_arg, value_arg, traceback_arg)
    472             compat.as_text(c_api.TF_Message(self.status.status)),
--> 473             c_api.TF_GetCode(self.status.status))
    474     # Delete the underlying status object from memory otherwise it stays alive

InvalidArgumentError: Dimension 0 in both shapes must be equal, but are 4096 and 1000 for 'Assign_30' (op: 'Assign') with input shapes: [4096,3], [1000,3].

During handling of the above exception, another exception occurred:

ValueError                                Traceback (most recent call last)
<ipython-input-5-a2d2e98db4b6> in <module>()
      1 from keras.models import load_model
----> 2 loaded_model = load_model('my_model_vgg16.h5')
      3 print("Loaded Model from disk")
      4 
      5 #compile and evaluate loaded model

~\Anaconda2\envs\tensorflow-gpu\lib\site-packages\keras\models.py in load_model(filepath, custom_objects, compile)
    244 
    245         # set weights
--> 246         topology.load_weights_from_hdf5_group(f['model_weights'], model.layers)
    247 
    248         # Early return if compilation is not required.

~\Anaconda2\envs\tensorflow-gpu\lib\site-packages\keras\engine\topology.py in load_weights_from_hdf5_group(f, layers)
   3164                              ' elements.')
   3165         weight_value_tuples += zip(symbolic_weights, weight_values)
-> 3166     K.batch_set_value(weight_value_tuples)
   3167 
   3168 

~\Anaconda2\envs\tensorflow-gpu\lib\site-packages\keras\backend\tensorflow_backend.py in batch_set_value(tuples)
   2363                 assign_placeholder = tf.placeholder(tf_dtype,
   2364                                                     shape=value.shape)
-> 2365                 assign_op = x.assign(assign_placeholder)
   2366                 x._assign_placeholder = assign_placeholder
   2367                 x._assign_op = assign_op

~\Anaconda2\envs\tensorflow-gpu\lib\site-packages\tensorflow\python\ops\variables.py in assign(self, value, use_locking)
    571       the assignment has completed.
    572     """
--> 573     return state_ops.assign(self._variable, value, use_locking=use_locking)
    574 
    575   def assign_add(self, delta, use_locking=False):

~\Anaconda2\envs\tensorflow-gpu\lib\site-packages\tensorflow\python\ops\state_ops.py in assign(ref, value, validate_shape, use_locking, name)
    274     return gen_state_ops.assign(
    275         ref, value, use_locking=use_locking, name=name,
--> 276         validate_shape=validate_shape)
    277   return ref.assign(value)

~\Anaconda2\envs\tensorflow-gpu\lib\site-packages\tensorflow\python\ops\gen_state_ops.py in assign(ref, value, validate_shape, use_locking, name)
     54     _, _, _op = _op_def_lib._apply_op_helper(
     55         "Assign", ref=ref, value=value, validate_shape=validate_shape,
---> 56         use_locking=use_locking, name=name)
     57     _result = _op.outputs[:]
     58     _inputs_flat = _op.inputs

~\Anaconda2\envs\tensorflow-gpu\lib\site-packages\tensorflow\python\framework\op_def_library.py in _apply_op_helper(self, op_type_name, name, **keywords)
    785         op = g.create_op(op_type_name, inputs, output_types, name=scope,
    786                          input_types=input_types, attrs=attr_protos,
--> 787                          op_def=op_def)
    788       return output_structure, op_def.is_stateful, op
    789 

~\Anaconda2\envs\tensorflow-gpu\lib\site-packages\tensorflow\python\framework\ops.py in create_op(self, op_type, inputs, dtypes, input_types, name, attrs, op_def, compute_shapes, compute_device)
   2956         op_def=op_def)
   2957     if compute_shapes:
-> 2958       set_shapes_for_outputs(ret)
   2959     self._add_op(ret)
   2960     self._record_op_seen_by_control_dependencies(ret)

~\Anaconda2\envs\tensorflow-gpu\lib\site-packages\tensorflow\python\framework\ops.py in set_shapes_for_outputs(op)
   2207       shape_func = _call_cpp_shape_fn_and_require_op
   2208 
-> 2209   shapes = shape_func(op)
   2210   if shapes is None:
   2211     raise RuntimeError(

~\Anaconda2\envs\tensorflow-gpu\lib\site-packages\tensorflow\python\framework\ops.py in call_with_requiring(op)
   2157 
   2158   def call_with_requiring(op):
-> 2159     return call_cpp_shape_fn(op, require_shape_fn=True)
   2160 
   2161   _call_cpp_shape_fn_and_require_op = call_with_requiring

~\Anaconda2\envs\tensorflow-gpu\lib\site-packages\tensorflow\python\framework\common_shapes.py in call_cpp_shape_fn(op, require_shape_fn)
    625     res = _call_cpp_shape_fn_impl(op, input_tensors_needed,
    626                                   input_tensors_as_shapes_needed,
--> 627                                   require_shape_fn)
    628     if not isinstance(res, dict):
    629       # Handles the case where _call_cpp_shape_fn_impl calls unknown_shape(op).

~\Anaconda2\envs\tensorflow-gpu\lib\site-packages\tensorflow\python\framework\common_shapes.py in _call_cpp_shape_fn_impl(op, input_tensors_needed, input_tensors_as_shapes_needed, require_shape_fn)
    689       missing_shape_fn = True
    690     else:
--> 691       raise ValueError(err.message)
    692 
    693   if missing_shape_fn:

ValueError: Dimension 0 in both shapes must be equal, but are 4096 and 1000 for 'Assign_30' (op: 'Assign') with input shapes: [4096,3], [1000,3].

问题出在线路上model.layers.pop()。当您直接从列表中弹出图层时model.layers,该模型的拓扑没有相应更新。因此,如果模型定义错误,以下所有操作都将是错误的。

具体来说,当您添加一个图层时model.add(layer), 列表model.outputs被更新为该层的输出张量。您可以在源代码中找到以下几行Sequential.add():

        output_tensor = layer(self.outputs[0])
        # ... skipping irrelevant lines
        self.outputs = [output_tensor]

你打电话时model.layers.pop(), 然而,model.outputs没有相应更新。结果,下一个添加的层将使用错误的输入张量进行调用(因为self.outputs[0]仍然是移除层的输出张量)。

这可以通过以下几行来证明:

model = Sequential()
for layer in vgg16_model.layers:
    model.add(layer)

model.layers.pop()
model.add(Dense(3, activation='softmax'))

print(model.layers[-1].input)
# => Tensor("predictions_1/Softmax:0", shape=(?, 1000), dtype=float32)
# the new layer is called on a wrong input tensor

print(model.layers[-1].kernel)
# => <tf.Variable 'dense_1/kernel:0' shape=(1000, 3) dtype=float32_ref>
# the kernel shape is also wrong

不正确的内核形状是您看到有关形状不兼容的错误的原因[4096,3] versus [1000,3].

要解决这个问题,只需不要将最后一层添加到Sequential model.

model = Sequential()
for layer in vgg16_model.layers[:-1]:
    model.add(layer)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 Keras 加载之前保存的重新训练的 VGG16 模型时出现 ValueError 的相关文章

随机推荐

  • Python Flask WTForm SelectField 在验证时具有枚举值“不是有效选择”

    我的 Python Flask 应用程序使用带有内置 python 枚举支持的 WTForms 我正在尝试提交一个表单 POST 其中 SelectField 由枚举的所有值填充 当我点击 提交 时 我收到错误 不是有效的选择 这看起来很奇
  • android.support.design.widget.TextInputLayout 无法实例化

    我想整合android support design widget TextInputLayout在我的安卓应用程序中 我已经复制了jar文件android support design jar从 sdk 到我的应用程序 lib 文件夹 我
  • 将 UserControl 绑定到其自己的 dependencyProperty 不起作用

    我遇到一个问题 当父级将该对象设置为数据绑定时 我无法创建使用自定义对象的属性的用户控件 尝试解释一下我在这里的意思是代码 自定义对象 public class MyObj public string Text get set public
  • 向 Django 管理添加自定义字段

    我已经用各个领域定义了我的模型 其中一些是自定义字段 我使用应用程序的 fields py 文件来验证信用卡数据 来源是here https github com bryanchow django creditcard fields cla
  • Unicorn 与 Ruby 2.4.1 导致奇怪的崩溃

    我正在从 Ruby 2 3 1 升级到 Ruby 2 4 1 这样做后 Unicorn 似乎与新版本不兼容 我收到以下错误 我正在使用 Unicorn 5 1 0 并尝试了 Unicorn 5 3 1 无济于事 我需要使用不同的库而不是 X
  • 树形视图验证

    树视图有叶节点复选框 我需要验证树视图 如果至少检查了一个节点 并且用户可以选择的节点数量不超过特定 例如 3 个节点 注意 Treeview是asp net树视图 不是ajax树视图 好吧 既然你没有提到你想要什么类型的验证 我将同时进行
  • Google 驱动器 - WSL2 中的虚拟驱动器安装

    有谁知道我是否可以在win10系统中的wsl2中安装Google驱动器 虚拟驱动器 谢谢 sudo mount t drvfs G mnt g 第一次这样做时 运行sudo mkdir mnt g first
  • 等待 QueueUserWorkItem 完成

    如果我将作业添加到线程池中QueueUserWorkItem 在所有工作完成之前 如何阻止我的计划继续进行 我知道我可以添加一些逻辑来阻止应用程序运行 直到所有作业完成 但我想知道是否有类似的东西Thread Join 或者是否有任何方法可
  • .NET Core 中的程序集绑定重定向

    如何在 NET Core 中进行程序集绑定重定向 我发现这个问题被问了几次 但没有提供解决方案 情况微不足道 我有一个引用版本 10 中的程序集 A 的包 我想使用版本 12 中的程序集 A 在标准 NET 中 它可以完美地与此配合使用
  • 在运行时隐藏水晶报表中的列?

    如何在运行时隐藏水晶报表中的列 感谢您的任何建议 选项 1 使用条件抑制逻辑隐藏 显示冗余字段 使用参数字段来驱动所需字段的抑制公式 如果您想消除字段之间的空格 则需要将字段堆叠在一起并适当地抑制它们 在您的示例中 第 2 列将包含 fie
  • 通过 CSS 根据高度设置元素宽度

    我有一组元素 要求它们的最小宽度等于它们的高度 但高度没有明确设置 目前我可以通过设置 css 来实现这一点min width通过 jQuery 属性 document ready function myClass each functio
  • Asp.net 图像大小调整质量

    我有这段代码 用于调整和保存用户发布的文件的大小 问题是 当我调整到 480px 宽度时 图像质量会下降很多 而且大小 以 kb 为单位 仍然很大 例如 当我使用 Paint 之类的软件 手动 将同一图像的大小调整为 480px 时 质量仍
  • 如何在全日历中将事件的背景颜色更改为不同的颜色?

    我正在使用最新版本fullcalendar 我查看了文档如何更改背景颜色事件 但我不知道如何处理不同的事件 我需要带有红色 蓝色 绿色事件的代码示例 如下图所示 我在文档网站上看到了这段代码 但我无法应用两种颜色 calendar full
  • 在 check_box_tag 的 onclick 函数中传递 Rails 变量

    我正在使用 Rails 3 0 在我看来 我试图拥有一个每行都有一个复选框的表 以及一个带有特定参数 rails 变量 的 onclick 事件函数 table tr td gt td tr table 我尝试了很多方法 但没有成功 我知道
  • 使用 slick 3.0.0 流结果和 Postgresql 的正确方法是什么?

    我正在尝试弄清楚如何使用流畅的流媒体 我使用 slick 3 0 0 和 postgres 驱动程序 情况如下 服务器必须向客户端提供按大小 以字节为单位 限制的数据块分割的数据序列 因此 我编写了以下巧妙的查询 val sequences
  • 获取 Jenkins Pipeline 插件中工作区目录的绝对路径

    我目前正在对 Jenkins Pipeline 插件 以前称为 Workflow 插件 进行一些评估 阅读文档我发现我目前无法使用以下命令检索工作区路径env WORKSPACE 目前 以下变量在工作流程脚本中不可用 节点标签 工作空间 S
  • 使用 .NET RegEx 检索第二个“-”之后的字符串部分

    这是我的第一条堆栈消息 希望你能帮忙 我有几个字符串需要分解以供以后使用 这里有几个例子来说明我的意思 fred 064528 NEEDED frederic 84728957 NEEDED sam 028 NEEDED 正如您在上面看到的
  • 有没有办法跨模块使用局部变量?

    我有一个带有模块和用户窗体的 VBA 项目 我想在我的用户表单中使用模块中的一些变量 我是否有必要在全局声明这些变量 我不喜欢全局变量 因为它们在代码执行后保留在内存中 并且我必须在宏开始时一一重置这些变量 我无法使用关键字 End 从内存
  • 电子邮件中的 Message-ID 有什么用?

    据我所知 每个消息 ID 都必须是唯一的 但是如果我们强制标头具有固定值 则可能会创建重复的消息 ID 所以我不明白他们说 Message ID 应该是唯一的有什么意义 但他们很容易创建重复项 如果任何有一点阅读和基本编程知识的人都可以轻松
  • 使用 Keras 加载之前保存的重新训练的 VGG16 模型时出现 ValueError

    我在 Keras 中使用 VGG16 架构 我通过以下方式对其进行了重新训练以满足我的需求 vgg16 model keras applications vgg16 VGG16 model Sequential for layer in v