L1正则化和L2正则化

写在前面

最近在优化模型的时候,发现自己对一些常用优化策略的底层原理认识欠缺,于是开始研究一些底层的原理,以及补足自己的知识盲区,在看过大量博客后,将自己的理解记录下来,由输入到输出。 如有错误,欢迎批评指正。

文章目录

  • 写在前面
  • 一、什么是正则化?
  • 二、正则化的作用
  • 三、L1和L2正则化为什么可以防止过拟合?
  • 四、L1和L2正则化代码实现(Pytorch)
  • 写在后面

一、什么是正则化?

在深度学习模型中,模型的参数越多,对于样本的拟合程度越高,在下面三幅图中,可以看到一图表示欠拟合,二图拟合的刚刚好,三图对于样本的分类太过细致,产生过拟合,模型的的参数会很多,模型过拟合,则泛化能力变弱。
L1正则化和L2正则化_第1张图片
为了解决过拟合的问题,思路是减少模型的参数,也就是减小模型参数向量,这和数学中范数的思路一致。常用的范数有0范数,1范数,2范数。

0范数,向量中非零元素的个数。
1范数,为绝对值之和。
2范数,就是通常意义上的模。
0范数是一个np问题,很难求解,所以一般采用1范数和2范数。将1范数和2范数应用于模型的损失函数中,便是我们常说的L1正则化和L2正则化。

二、正则化的作用

上面分析了范数和正则化的关系,回到深度学习领域,正则化通常用于减轻模型的过拟合问题,通过将L1范数或者L2范数加入到损失函数中,在损失函数中增加一个惩罚项,从而限制模型参数的数量以及参数的大小。
L1正则化可以产生一个稀疏矩阵,从而用于特征选择
L2正则化可以缩小参数矩阵中的值,从而减轻模型过拟合的问题

三、L1和L2正则化为什么可以防止过拟合?

在这一部分,对正则化所起到的作用进行详细分析。
假设我们的损失函数为J0
损失函数带上L1正则化项,变为:

其中,a为正则化参数,我们的目标是得到损失函数的最小值,加上正则化项之后,相当于对模型参数增加了限制。
考虑只有两个模型参数的时候,画出原损失函数的等值线,已经L1正则化的等值线,如下图。彩色的是损失函数的等值线(二次多项式的等值线为椭圆),黑色的菱形是L1正则化的等值线。
L1正则化和L2正则化_第2张图片
由于L1正则化的限制,模型参数w的取值必须同时在L1正则化和原损失函数上,即两个等值线的交点。可以看到损失函数的等值线,一定会最先和L1正则化等值线的一个“角”相交,这便是最优解。
ps:为什么是最优解?因为如果损失函数的等值线继续变大的话,才会和L1正则化的等值线有其他交点,在此处,原损失函数的值最小,L1正则化的值在其等值线的任何点都不变。
在最优解处,其中的一个模型参数为0,这便是为什么L1正则化可以产生稀疏模型,对特征进行选择的原理。
同时,L1正则化等值线的大小可以通过a正则化参数控制,而且越大的a,可以使得损失函数在w=0时取得最小值。当a很大时,等值线图形越小,此时w很小,L1正则化也可以起到一定的减轻过拟合的作用。
当使用L2正则化项时,损失函数为:

对应的等值线如下图:
L1正则化和L2正则化_第3张图片
此时,损失函数的等值线和坐标系相交的概率大大降低,因此L2正则化不具有稀疏性。
当正则化系数越大时,上图中的周长越小,最终求得的模型参数也就越小,而越小的模型参数泛化能力越强。

四、L1和L2正则化代码实现(Pytorch)

L2正则化,在优化器中添加weight_decay参数,这个参数就是正则化项的系数,不添加则默认为0

# Model
        model = nn.DataParallel(model)
        # Criterion
        criterion = nn.CrossEntropyLoss()
        # Params
        params = model.parameters()
        # optimizer
        optimizer = optim.SGD(params, lr, weight_decay=weight_decay)

L1正则化,torch没有实现,无法在模型定义阶段添加,可以在模型训练的过程中添加:

regularity_coefficient = 0.01
#L1正则化模型参数的和
regularity = 0
params = model.parameters()
for param in params:
    regularity += torch.sum(torch.abs(param))
#优化器
optimizer = optim.SGD(params, lr)
#损失函数
criterion = nn.CrossEntropyLoss()
loss = criterion(logits, target) + regularity_coefficient * regularity
optimizer.zero_grad()
loss.backward()

写在后面

以上便是对与正则化的理解和介绍。这里只介绍了一些原理,对于其中蕴含的数学公式不多介绍。

你可能感兴趣的:(深度学习,深度学习)