【问题标题】:How to set parameters in keras to be non-trainable?如何将keras中的参数设置为不可训练?
【发布时间】:2019-04-29 09:54:52
【问题描述】:

我是 Keras 的新手,我正在构建一个模型。我想在训练前几层时冻结模型最后几层的权重。我试图将横向模型的可训练属性设置为 False,但它似乎不起作用。这是代码和模型摘要:

opt = optimizers.Adam(1e-3)
domain_layers = self._build_domain_regressor()
domain_layers.trainble = False
feature_extrator = self._build_common()
img_inputs = Input(shape=(160, 160, 3))
conv_out = feature_extrator(img_inputs)
domain_label = domain_layers(conv_out)
self.domain_regressor = Model(img_inputs, domain_label)
self.domain_regressor.compile(optimizer = opt, loss='binary_crossentropy', metrics=['accuracy'])
self.domain_regressor.summary()

型号汇总:model summary

如您所见,model_1 是可训练的。但是根据代码,它被设置为不可训练的。

【问题讨论】:

  • 你确定这不仅仅是一个错字吗?它应该是trainable 而不是trainble(即ab 之前丢失)。
  • 我发现我错过了将单词“trainable”拼写为“trainble”,可悲的是 keras 并没有警告我该模型没有属性“trainble”。这个问题可以结束了。
  • 还是要感谢其他人。
  • 好吧,看看错字,反正只是为了以后的读者。
  • 如果您愿意,可以回答您自己的问题并将其标记为已回答:)

标签: python keras deep-learning


【解决方案1】:

尽管原始问题的解决方案是一个错字修复,让我添加一些有关 keras 可训练对象的信息。

现代 Keras 包含以下工具来查看和操作可训练状态:

  • tf.keras.Layer._get_trainable_state() 函数 - 打印字典,其中键是模型组件,值是布尔值。请注意,tf.keras.Model 也是 tf.Keras.Layer
  • tf.keras.Layer.trainable 属性 - 操作各个层的可训练状态。

所以典型的动作如下所示:

# Print current trainable map:
print(model._get_trainable_state())

# Set every layer to be non-trainable:
for k,v in model._get_trainable_state().items():
    k.trainable = False

# Don't forget to re-compile the model
model.compile(...)

【讨论】:

    【解决方案2】:

    单词“trainble”中有错字(缺少“a”)。可悲的是,keras 没有警告我该模型不具有“可训练”属性。这个问题可以结束了。

    【讨论】:

      【解决方案3】:

      更改代码中的最后 3 行:

      last_few_layers = 20 #number of the last few layers to freeze
      self.domain_regressor = Model(img_inputs, domain_label)
      for layer in model.layers[:-last_few_layers]:
          layer.trainable = False
      self.domain_regressor.compile(optimizer = opt, loss='binary_crossentropy', metrics=['accuracy'])
      

      【讨论】:

        【解决方案4】:

        您可以简单地为层属性trainable 分配一个布尔值。

        model.layers[n].trainable = False
        

        您可以可视化哪个层是可训练的:

        for l in model.layers:
            print(l.name, l.trainable)
        

        你也可以通过模型定义来传递它:

        frozen_layer = Dense(32, trainable=False)
        

        来自 Keras documentation:

        “冻结”一个层意味着从训练中排除它,即它的 权重永远不会更新。这在以下情况下很有用 微调模型,或对文本输入使用固定嵌入。
        您可以将可训练的参数(布尔值)传递给层构造函数以 将图层设置为不可训练。 此外,您可以将图层的可训练属性设置为 True 或 实例化后为假。要使其生效,您需要 修改可训练属性后在模型上调用 compile()。

        【讨论】:

        • 请注意,您不能简单地在“层”上创建trainable=False,您必须从“模型实例”中获取层,然后编译:self.domain_regressor。您可能需要递归层查找,因为模型中有模型。
        • @DanielMöller 你可以。 trainable 是基本 Layer() 类的属性。
        • 不会生效。
        • 它不会被真正冻结,至少在我的经验中(也许新版本的工作方式不同)。如果你没有从你正在编译的“精确模型”中获得层,那么 trainable 属性将不会真正起作用。
        • 当我试图从作为网络一部分的功能模型中解冻层时,我被困在了这个问题上。感谢@DanielMöller 的评论,我意识到我应该让整个功能层可训练,冻结它的所有层,然后使用一个函数我可以解冻我想要的层。
        猜你喜欢
        • 2019-02-01
        • 2020-08-26
        • 2023-03-13
        • 1970-01-01
        • 1970-01-01
        • 2019-02-24
        • 1970-01-01
        • 1970-01-01
        • 2019-02-15
        相关资源
        最近更新 更多