Keras/Tensorflow中的L1正则化是否真正是L1正则化?

14
我正在使用Keras中的keras.regularizers.l1(0.01)在神经网络参数上应用L1正则化,以获得稀疏模型。我发现,虽然我的许多系数非常接近于零,但实际上只有很少的系数为零。
查看正则化的源代码后,它表明Keras简单地将参数的L1范数添加到损失函数中。
这是不正确的,因为参数几乎肯定永远不会达到零(在浮点误差内),这是使用L1正则化时预期的。当参数为零时,L1范数不可微分,因此需要使用子梯度方法,在优化过程中如果参数足够接近零,则将其设置为零。请参见软阈值操作符max(0, ..)此处
Tensorflow/Keras是否这样做,或者使用随机梯度下降来实现这一点是否不切实际?
编辑:此外,这里有一篇非常出色的博客文章,解释了L1正则化的软阈值操作符。

L1 正则化很好。L1 比 L2 更鼓励稀疏性,但并不保证它。Theano 和 TensorFlow 都经过了充分的测试,并且当然可以在不可微分点周围很好地处理梯度。 - yhenon
{btsdaf} - Aaron
{btsdaf} - Daniel Möller
通过将绝对权重值之和的比例项添加到损失函数中,可以实现@DanielMöller所述的功能。 - Aaron
4个回答

5

尽管有@Joshua的答案,还有三个值得提及的事情:

  1. There is no problem connected with a gradient in 0. keras is automatically setting it to 1 similarly to relu case.
  2. Remember that values lesser than 1e-6 are actually equal to 0 as this is float32 precision.
  3. The problem of not having most of the values set to 0 might arise due to computational reasons due to the nature of a gradient-descent based algorithm (and setting a high l1 value) because of oscillations which might occur due to gradient discontinuity. To understand imagine that for a given weight w = 0.005 your learning rate is equal to 0.01 and a gradient of the main loss is equal to 0 w.r.t. to w. So your weight would be updated in the following manner:

    w = 0.005 - 1 * 0.01 = -0.05 (because gradient is equal to 1 as w > 0),
    

    and after the second update:

    w = -0.005 + 1 * 0.01 = 0.05 (because gradient is equal to -1 as w < 0).
    

    As you may see the absolute value of w hasn't decreased even though you applied l1 regularization and this happened due to the nature of the gradient-based algorithm. Of course, this is simplified situation but you could experience such oscillating behavior really often when using l1 norm regularizer.


第一个更新中的方程应该是 w = 0.005 - 1 * 0.01 = -0.005。第二个更新中的方程也是如此。这只是一个小错误,谢谢你的答复。那对我很有帮助! - Max Wong
我们可以在dropout中使用L1正则化吗? - MUK

2
TL;DR: 深度学习框架中的公式是正确的,但目前我们没有一个强大的求解器/优化器来使用 SGD 或其变种 精确地解决它。但如果您使用近端优化器,您可以获得稀疏解。
您的观察是正确的。
几乎所有深度学习框架(包括TF)通过将参数的绝对值添加到损失函数中来实现L1正则化。这是L1正则化的Lagrangian形式,是正确的。
然而,求解器/优化器应该受到责备。即使对于经过充分研究的LASSO问题,其中解决方案应该是稀疏的,软阈值运算符确实给出了稀疏解,次梯度下降求解器也不能得到精确的稀疏解。Quora上的这个答案提供了一些关于次梯度下降收敛性质的见解,它说:
“由于它完全忽略了问题结构(它没有区分最小二乘拟合和正则化项),只看整个目标的子梯度,因此次梯度下降对于非平滑函数(例如Lasso目标)具有非常差的收敛性质。直观地说,在(次)梯度方向上采取小步骤通常不会导致坐标完全等于零。”
如果您使用近端算子,可以获得稀疏解。例如,您可以查看论文 "Data-driven sparse structure selection for deep neural networks"(该论文带有 MXNET 代码,易于复现!)或 "Stochastic Proximal Gradient Descent with Acceleration Techniques"(该论文提供了更多的理论洞见)。我不确定 TF 中内置的近端优化器(例如:tf.train.ProximalAdagradOptimizer)是否可以导致稀疏解,但您可以试试。另一个简单的解决方法是在训练后或每个梯度下降步骤后将小权重(即绝对值<1e-4)归零以强制稀疏性。这只是一种方便的启发式方法,不具备理论上的严谨性。

2
Keras正确地实现了L1正则化。在神经网络的背景下,L1正则化简单地将参数的L1范数加到损失函数中(见CS231)。
虽然L1正则化鼓励稀疏性,但并不能保证输出一定是稀疏的。随机梯度下降的参数更新本质上是有噪声的。因此,任何给定参数恰好为0的概率是微不足道的。
然而,L1正则化网络的许多参数通常接近于0。一个简单的方法是将小值阈值化为0。已经有研究探索了更高级的方法来生成稀疏的神经网络。在this paper中,作者同时修剪和训练神经网络,在许多知名的网络架构上达到90-95%的稀疏度。

0
Keras 正确地实现了 L1 正则化,但这不是 LASSO。对于 LASSO,需要一个软阈值函数,正如原帖中正确指出的那样。类似于 keras.layers.ThresholdedReLU(theta=1.0) 的函数将非常有用,但 f(x) = x 对于 x > theta 或 f(x) = x 对于 x < -theta,f(x) = 0 其他情况。对于 LASSO,theta 将等于学习率乘以 L1 函数的正则化因子。

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