Keras(tensorflow后端)中的model.compile()是否会初始化所有权重和偏差?

109
当我开始训练一个模型时,没有之前保存的模型。我可以安全地使用model.compile()。现在我已将模型保存在一个h5文件中,以便使用checkpoint进行进一步训练。
假设我想进一步训练该模型。此时我感到困惑:我是否可以在这里使用model.compile()?它应该放在model = load_model()语句的前面还是后面?如果model.compile()重新初始化所有权重和偏差,则应该将其放在model = load_model()语句之前。
在查阅了一些讨论后,我发现model.compile()只需要在我没有之前保存的模型时才需要使用。一旦我保存了模型,就不需要使用model.compile()。这是真的还是假的?当我想使用经过训练的模型进行预测时,我应该在预测之前使用model.compile()吗?
2个回答

223

何时使用?

如果您正在使用 compile,那么肯定是在load_model()之后进行。毕竟,您需要一个模型来编译。(PS:load_model会自动使用与保存的模型一起的优化器来编译模型)

compile是用来做什么的?

compile 定义了损失函数优化器指标。就这些。

它与权重没有任何关系,您可以编译模型多次而不会对预训练权重造成任何影响。

您需要已编译的模型来进行训练(因为训练使用损失函数和优化器)。但是对于预测,不必编译模型。

您需要多次使用 compile 吗?

只有在以下情况下:

  • 您想更改以下其中一项:
    • 损失函数
    • 优化器/学习率
    • 指标
    • 某些层的 trainable 属性
  • 您加载(或创建)的模型尚未编译。或者您的加载/保存方法没有考虑到之前的编译。

再次编译的后果:

如果您再次编译模型,您将丢失 优化器状态

这意味着您的训练会在开始时受到一些影响,直到它调整学习率、动量等。但是权重不会受到任何损坏(除非您的初始学习率太大,以至于第一次训练步骤会大幅改变微调的权重)。


1
即使您最初使用include_optimizer=True保存了模型,重新编译后是否会丢失所有优化器状态? - kawingkelvin
1
@DanielMöller:它是否影响model.outputs,即在编译之前和之后的区别是什么?另外,如果您能解释一下load_model(model, compile=False/True)参数中compile=False的用法将会很棒。 - aspiring1
2
没有什么变化。编译是为了为“训练”设置“优化器”和“损失”函数,仅此而已。如果您想加载一个模型而不进行训练,则无需对其进行编译。1- compile=True:模型将以相同的设置加载和编译。2- compile=False,您只会加载没有优化器的模型。 - Daniel Möller
@DanielMöller 在更改层的“trainable”属性后使用model.compile的常见建议怎么样?这是否包含在你列出的何时使用model compile的要点中?那么,当使用“set_weights()”更改层的权重时呢? - hirschme
1
谢谢你提醒我“可训练”。但是设置权重没有任何问题。 - Daniel Möller
显示剩余4条评论

35

不要忘记,在更改层的trainable标志后,您还需要编译模型,例如当您想像这样微调模型时:

  1. 加载没有顶部分类器的VGG模型

  2. 冻结所有层(即trainable = False

  3. 在顶部添加一些层

  4. 对一些数据进行编译和训练

  5. 通过设置trainable = True解冻一些VGG层

  6. 再次编译模型(不要忘记这一步!)

  7. 对一些数据进行训练


2
改变层的可训练标志后不编译模型会导致什么结果? - Kake_Fisk
3
更改不会生效,即层的可训练状态将保持与上一次“compile”方法调用之前相同。 - today

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接