是否应该在使用 model.load_weights() 之前运行 model.compile(),如果模型只是稍微改变了说 dropout?

Posted

技术标签:

【中文标题】是否应该在使用 model.load_weights() 之前运行 model.compile(),如果模型只是稍微改变了说 dropout?【英文标题】:should model.compile() be run prior to using model.load_weights(), if model has been only slightly changed say dropout? 【发布时间】:2018-10-26 07:27:42 【问题描述】:

通过数据集进行近 24 个 epoch 的训练和验证,间歇性地一次 8 个 epoch,并在每个间隔后累积保存权重。

我观察到前 16 个时期的训练和测试损失不断下降,之后训练损失继续下降而测试损失上升,所以我认为这是过度拟合的情况。

为此,我尝试使用在 16 个 epoch 后保存的权重恢复训练,超参数的变化说 增加 dropout_rate 一点。 因此,我使用新的 dropout 重新运行密集和转换块,以获得具有相同序列和可学习参数计数的相同架构。

现在,当我使用 model.load_weights()此后编译 为我的新模型(带有新的 dropout)分配以前的权重时。 我看到训练损失甚至更高,最初应该是(明显地随着训练期间随机节点不活动的增加),但后来它的表现也很不令人满意, 所以我怀疑在加载预训练权重后进行编译可能会破坏性能?

model.load_weights() & model.compile() 的推理和推荐顺序是什么?我真的很感激对上述案例的任何见解。

【问题讨论】:

你试过先编译再加载权重吗?从理论上讲,这无关紧要,很可能您增加的辍学率会降低性能。从头开始训练以确认这一点可能会更稳定。 不,在重新定义层之后,我首先加载权重然后编译它,以确定它从之前的训练中获得的准确性。否则对于 model.evaluate() 它会抛出一个错误,模型需要在评估之前进行编译。我怀疑需要提高 dropout,因为大约权重数为 127k,出于同样的原因,我正在间歇性地训练、保存和加载权重,因为每次从头开始训练多个 epoch 都需要很长时间。 【参考方案1】:

model.compile() 方法不会以任何方式触及权重。

其目的是创建一个符号函数,将损失和优化器添加到模型的现有函数中。

您可以根据需要随时编译模型多次,并且您的权重将保持不变。

编译的可能后果

如果您有一个模型,在某些时期训练有素,那么它的优化器(取决于您为它选择的类型和参数)也将针对特定时期进行训练。

编译会使您失去经过训练的优化器,并且由于学习率不适合模型的当前状态,您的第一批训练可能会遇到一些不好的结果。

除此之外,编译不会造成任何伤害。

【讨论】:

是的,我怀疑看到验证的突然下降以及第一个时期的训练准确性。这很有见地。谢谢丹尼尔。

以上是关于是否应该在使用 model.load_weights() 之前运行 model.compile(),如果模型只是稍微改变了说 dropout?的主要内容,如果未能解决你的问题,请参考以下文章

是否应该使用 Git 来存储持续集成构建?

是否应该使用 Linq? [关闭]

是否应该在模型和数据库中都设置唯一约束?

[使用Automapper时,我是否也应该展平/映射视图模型的内部objetc?

是否应该在 SQLite 中使用 GROUP BY 在 UNION 上进行 INNER JOIN 花费数小时?

是否应该为所有请求使用单个 Mongoose 连接?或者每个请求都有不同的连接?