首页 > 解决方案 > Keras - 正则化和自定义损失

问题描述

我已经构建了一个自定义的 Keras 模型,它由各个层组成。由于我想将 L2 正则化添加到此类层,因此我已将 的实例keras.regularizers.l2作为kernel_regularizer这些层的参数的参数传递(例如,请参见 的构造函数keras.layers.Conv2D)。keras.losses.BinaryCrossEntropy现在,如果我使用 Keras 实现的二元交叉熵损失(

然而,就我而言,我有一个自定义损失函数,它需要除y_trueand之外的其他几个参数y_pred,这意味着我无法将此函数作为参数的loss参数传递model.compile(...)(事实上,我什至不调用model.compile(...))。结果,我还不得不编写一个自定义训练循环。换句话说,不是简单地运行model.fit(...),我必须:

  1. 通过调用执行前向传播model(x)
  2. 计算损失
  3. 计算关于模型权重(即model.trainable_variables)的损失梯度tf.GradientTape
  4. 应用渐变
  5. 重复

我的问题是:正则化在哪个阶段进行?

请记住,我的自定义损失函数不考虑正则化,所以如果在我上面提到的两个阶段中的任何一个阶段都没有考虑到,那么我实际上是在训练一个没有任何正则化的模型(即使我已经为kernel_regularizer构成我的网络的每一层中的参数提供了一个值)。在那种情况下,我是否会被迫手动计算正则化项并将其添加到损失中?

标签: tensorflowkerasdeep-learning

解决方案


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

这篇文章概述了在 Keras 中从头开始编写一个训练循环,并有一节介绍了模型正则化。作者使用以下命令在他的训练步骤中添加了正则化层的损失:

loss += sum(model.losses)

我想这可能是你需要的。如果您仍然不确定,我会在训练循环中用上面的线训练一个模型,而另一个模型没有该线。检查训练模型的权重将为您提供一些关于权重正则化是否按预期工作的输入。


推荐阅读