tensorflow - Keras - 正则化和自定义损失
问题描述
我已经构建了一个自定义的 Keras 模型,它由各个层组成。由于我想将 L2 正则化添加到此类层,因此我已将 的实例keras.regularizers.l2
作为kernel_regularizer
这些层的参数的参数传递(例如,请参见 的构造函数keras.layers.Conv2D
)。keras.losses.BinaryCrossEntropy
现在,如果我使用 Keras 实现的二元交叉熵损失(
然而,就我而言,我有一个自定义损失函数,它需要除y_true
and之外的其他几个参数y_pred
,这意味着我无法将此函数作为参数的loss
参数传递model.compile(...)
(事实上,我什至不调用model.compile(...)
)。结果,我还不得不编写一个自定义训练循环。换句话说,不是简单地运行model.fit(...)
,我必须:
- 通过调用执行前向传播
model(x)
- 计算损失
- 计算关于模型权重(即
model.trainable_variables
)的损失梯度tf.GradientTape
- 应用渐变
- 重复
我的问题是:正则化在哪个阶段进行?
- 在前向传播期间?
- 在梯度的计算/应用期间?
请记住,我的自定义损失函数不考虑正则化,所以如果在我上面提到的两个阶段中的任何一个阶段都没有考虑到,那么我实际上是在训练一个没有任何正则化的模型(即使我已经为kernel_regularizer
构成我的网络的每一层中的参数提供了一个值)。在那种情况下,我是否会被迫手动计算正则化项并将其添加到损失中?
解决方案
正则化损失在模型的前向传播中计算,它们的梯度被应用在后向传播中。我认为你的训练步骤没有应用任何权重正则化,因此你的模型没有被正则化。检查这一点的一种方法是实际查看训练模型的权重 - 如果它们很稀疏,则意味着您已经以某种方式对权重进行了正则化。L1 正则化实际上会将一些权重推为 0。L2 正则化做类似的事情,但通常会导致权重更稀疏。
这篇文章概述了在 Keras 中从头开始编写一个训练循环,并有一节介绍了模型正则化。作者使用以下命令在他的训练步骤中添加了正则化层的损失:
loss += sum(model.losses)
我想这可能是你需要的。如果您仍然不确定,我会在训练循环中用上面的线训练一个模型,而另一个模型没有该线。检查训练模型的权重将为您提供一些关于权重正则化是否按预期工作的输入。
推荐阅读
- supercollider - Supercollider:对一个组应用 FX 似乎会影响其他组
- html - 通过单击隐藏和显示移动内容并在桌面上显示 3 列
- ios - 在表格视图单元格中时,如何根据其内容快速设置 CollectionView 高度?
- javascript - React Native 状态不更新
- bash - 在 bash 中将兆比特转换为千比特
- google-chrome - 单击页面中的任意位置时,Chrome 将我送回 Elements 选项卡
- tensorflow - 如何使用使用自定义操作的模型从源代码构建张量流,这些操作是现有操作的重命名版本?
- r - 基于 R 中的列值(或日期)的滚动回归
- javascript - 是否有允许在后台窗口中使用 RequestAnimationFrame 的浏览器(用于测试目的,macOS)
- oracle - 将记录类型作为参数传递有什么问题