【问题标题】:Weights transfer from one model to another model with different layer architecture权重从一个模型转移到另一个具有不同层架构的模型
【发布时间】:2018-03-19 20:58:11
【问题描述】:

我有一个三层的 CNN 网络,在拟合模型后,权重保存在磁盘上。我第二次加载权重,但这次模型增加了一层。所以现在是4层网络。是否可以使用不同的架构传输模型权重?如果是,那怎么办?我正在使用 keras 进行开发。

对我来说,它显示错误:“您正在尝试将包含 3 层的权重文件加载到具有 4 层的模型中”。

提前致谢!

【问题讨论】:

    标签: keras conv-neural-network


    【解决方案1】:

    我还没有尝试过,但是应该可以使用 layer.get_weights() 和 layer.set_weights(weights) 方法。

    weights = old_model_layer.get_weights()
    new_model_layer.set_weights(weights)
    

    请参阅https://keras.io/layers/about-keras-layers/ 了解更多信息。

    【讨论】:

    • 我们当然可以做到。我已经在层级进行了重量转移。我试图在没有架构差异的情况下进行模型重量转移。我想现在没有办法使用模型权重来扩展架构。我们必须使用层权重进行扩展。
    • 如何创建另一个基于旧模型的模型实例?例如 new_model = Model( inputs=[old_model.input], outputs=[new_model(old_model.output)] )
    • 我尝试了同样的事情。我使用旧模型的权重和偏差创建了一个新模型,但发现每一层的不同权重输出形状不能合并一个新模型。例如,如果我们有 3 层的旧网络和 4 层的新网络,那么第 4 层将使用默认权重进行初始化,这将不兼容,因为输入将与第 4 层不同。在顺序模型中,输入形状只给出一次。让网络自行管理。
    • 或者用函数式API:x = old_model.output x = Dense(1024, activation='relu')(x) # Additional layer model = Model(inputs=old_model.input, outputs=x)然后你可以把它保存为一个新的模型扩展模型,可以单独使用。
    • 来自 keras 文档:model.load_weights(filepath, by_name=False) 从 HDF5 文件(由 save_weights 创建)加载模型的权重。默认情况下,架构预计不会改变。要将权重加载到不同的架构中(某些层共有),请使用 by_name=True 仅加载具有相同名称的层。
    【解决方案2】:

    我回答有点晚了,但希望这会对某人有所帮助。

    我就是这样做的:

    1. 使用列表存储所有层:

      model_layers = []
      model_layers.append(keras.layers.Conv2D(...))
      ...
      model_layers.append(keras.layers.Dense(units=num_classes))
      model_layers.append(keras.layers.Softmax())
      
    2. 定义源模型,并从列表中添加层。从保存的文件中加载权重:

      model = keras.Sequential()
      for layer in model_layers:
          model.add(layer)
      model.compile(...)
      model.load_weights(filename)
      
    3. 将原始列表复制到新的临时列表。清除原始列表,并向其中添加目标网络所需的新层实例:

      temp_layers = model_layers.copy()
      model_layers.clear()
      model_layers.append(keras.layers.Conv2D(...))
      ...
      model_layers.append(keras.layers.Dense(units=num_classes))
      model_layers.append(keras.layers.Softmax())
      
    4. 假设源网络中的所有层构成目标网络的初始部分,将所有层引用从临时列表复制到model_layers。如果需要,排除分类层。如果您知道它们的索引,您还可以恢复单个图层:

      for i in range(len(temp_layers) - 2):
          model_layers[i] = temp_layers[i]
      
    5. 按照第 2 步创建新模型:

      new_model = keras.Sequential()
      for layer in model_layers:
          new_model.add(layer)
      
    6. 添加任何可能需要的附加层(以及分类层,如果需要):

      new_model.add(...)
      new_model.add(keras.layers.Dense(units=num_classes))
      new_model.add(keras.layers.Softmax())
      new_model.compile(...)
      

    我意识到这不是一个普遍的答案。我已经提到了我在成功实施中使用的确切步骤。

    随意尝试不同的变体。

    【讨论】:

      猜你喜欢
      • 2021-08-13
      • 2018-07-10
      • 1970-01-01
      • 2012-12-13
      • 2016-12-28
      • 2016-11-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多