如何解决Keras-正则化和自定义丢失
我建立了一个自定义的Keras模型,该模型包含各个层。由于我想向此类层添加L2正则化,因此我传递了keras.regularizers.l2
的实例作为这些层的kernel_regularizer
参数的参数(例如,请参见{{3}的构造函数})。现在,如果我使用Keras的二进制交叉熵损失(keras.layers.Conv2D
)的实现来训练该模型,则可以确定在计算时将考虑我指定的L2正则化损失。
但是,对于我来说,我有一个自定义损失函数,除了y_true
和y_pred
之外还需要其他几个参数,这意味着我无法将此函数作为{ loss
的{1}}参数(实际上,我什至没有调用model.compile(...)
)。结果,我还必须编写一个自定义训练循环。换句话说,我不仅要运行model.compile(...)
,还必须:
- 通过调用
model.fit(...)
进行前向传播
- 计算损失
- 使用
model(x)
计算相对于模型权重(即model.trainable_variables
)的损耗梯度 - 应用渐变
- 重复
我的问题是:在哪个阶段进行正则化?
- 正向传播期间?
- 在计算/应用梯度期间?
请记住,我的自定义损失函数不考虑正则化,因此,如果我在上面提到的两个阶段中的任何一个阶段都没有考虑到它,那么我实际上是在训练一个没有正则化的模型(即使我已经在构成网络的每一层中为tf.GradientTape
参数提供了一个值)。在那种情况下,我会被迫手工计算正则项并将其添加到损失中吗?
解决方法
正则化损失是在模型的前向通过时计算的,其梯度将在后向通过时应用。我认为您的训练步骤未应用任何权重正则化,因此您的模型也未正则化。检查此问题的一种方法是实际查看经过训练的模型的权重-如果它们稀疏,则意味着您已经以某种方式调整了权重。 L1正则化实际上会将一些权重推到0。L2正则化做类似的事情,但通常会导致权重稀疏。
This帖子概述了在Keras中从头开始编写训练循环,并提供了有关模型正则化的部分。作者使用以下命令在训练步骤中添加了正则化层的损失:
loss += sum(model.losses)
我认为这可能是您所需要的。如果您仍然不确定,我将在训练循环中使用上面的线训练一个模型,而在那条线的情况下训练另一个模型。检查训练后的模型的权重将为您提供一些有关权重正则化是否按预期工作的信息。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。