Keras - 正则化和自定义损失

3
我构建了一个自定义 Keras 模型,其中包含各种层。由于我想要向这些层添加 L2 正则化,因此我将 keras.regularizers.l2 的一个实例作为这些层的 kernel_regularizer 参数的值进行了传递(例如,请参见keras.layers.Conv2D类的构造函数)。现在,如果我使用 Keras 实现的二元交叉熵损失函数(keras.losses.BinaryCrossentropy)训练此模型,那么当计算损失时将考虑到我指定的 L2 正则化。
然而,在我的情况下,我有一个自定义损失函数,除了y_truey_pred之外还需要几个其他参数,这意味着我无法将此函数作为model.compile(...)loss参数的值进行传递(事实上,我甚至不调用model.compile(...))。因此,我还必须编写自定义训练循环。换句话说,我不是简单地运行model.fit(...),而是:
  1. 通过调用model(x)进行前向传播
  2. 计算损失
  3. 使用tf.GradientTape计算相对于模型权重(即model.trainable_variables)的损失梯度
  4. 应用梯度
  5. 重复
我的问题是:正则化在哪个阶段被考虑?
  • 在前向传播期间?
  • 在计算/应用梯度期间?
请注意,我的自定义损失函数不考虑正则化,因此,如果它没有在我上述提到的任何一个阶段中被考虑,则实际上我正在训练一个没有正则化的模型(即使我在网络中的每个层中都提供了kernel_regularizer参数的值)。在那种情况下,我是否需要手动计算正则化项并将其添加到损失中?

2
我投票关闭此问题,因为它不属于[help]中定义的编程范畴,而是涉及ML理论和方法。 - desertnaut
请查看 machine-learning 标签信息 中的注意事项(也适用于深度学习问题)。 - desertnaut
1个回答

2

正则化损失是在模型前向传递时计算的,其梯度在反向传递时应用。我认为你的训练步骤没有应用任何权重正则化,因此你的模型没有被正则化。一种检查方法是实际查看已经训练好的模型的权重 - 如果它们是稀疏的,则意味着你以某种方式对权重进行了正则化。L1正则化实际上会将一些权重推向0。L2正则化也会做类似的事情,但通常会导致权重不那么稀疏。

这篇文章概述了在Keras中从头编写训练循环的过程,并介绍了模型正则化的部分。作者在训练步骤中添加了来自正则化层的损失,具体命令如下:

loss += sum(model.losses)

我认为这可能是你需要的内容。如果你还不确定,我建议在训练循环中使用上述行进行模型训练,并使用另一个没有该行的模型。检查已训练模型的权重将使您对权重正则化是否按预期工作有所了解。


所以基本上在Keras的fit(...)方法的实现中,必须有一行类似的代码,对吧? - Francesco Cariaggi
是的。请查看这行代码:https://github.com/tensorflow/tensorflow/blob/b36436b087bd8e8701ef51718179037cccdfc26e/tensorflow/python/keras/engine/training.py#L749。该代码明确指出 regularization_losses = self.losses。我上面发布的解决方案有效吗? - Tom C

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