深度学习@IT·互联网

深度学习第八篇---正则化

2023-12-24  本文已影响0人  LooperJing

什么叫过拟合和欠拟合?

我们在模型训练的时候,通过把数据划分成训练集和测试集,然后选择Loss函数来评估训练效果怎么样,其loss函数在训练集上的值叫训练误差,在测试集上叫泛化误差,当训练误差比较大的时候,可能说明模型参数量比较小,难以拟合所有数据特征,称为欠拟合。反之当训练误差比较小,但是泛化误差比较大的时候,说明模型虽然在训练集上有不错的表现,但是在未见过的测试集上表现较差的这种现象称过拟合。

那什么是正则化呢,花书上说“凡是能够减少泛化误差的方法”都叫正则化。因此正则化是防止过拟合和提高模型泛化性能的一类方法的统称。
本文记录一下,经典的正则化方法有以下几种:
● Dropout - 在全连接层中随机丢弃部分神经元节点,产生一个简化了的网络结构
● L1/L2正则化 - 在原始的损失函数中增加L1/L2的惩罚项,从而限制产生较大的权重w
● Batch normalization - 控制隐层的输出在一个稳定的范围内
● 数据增强 - 通过增加数据集多样性的方式避免过拟合
● Early stopping - 在达到模型过拟合的阶段前停止训练模型

1 Dropout (随机失效)

Dropout通过随机地将一些神经元的输出置零,迫使模型不依赖于特定的神经元,从而增强了模型的泛化能力。这样,每个神经元都将学习到与其他神经元合作的特征,而不是过度依赖于某些特定的神经元。
在PyTorch中,可以通过在网络层中添加torch.nn.Dropout层来实现Dropout。例如:

import torch
import torch.nn as nn

if __name__ == '__main__':
   # 创建一个4行5列的矩阵
   matrix = torch.randn(4, 5)

   # 定义Dropout层,设置p参数为0.2,表示将20%的元素设置为0
   dropout = nn.Dropout(p=0.2)

   # 应用Dropout层
   matrix_dropout = dropout(matrix)

   print("原始矩阵:")
   print(matrix)
   print()
   print("应用Dropout后的矩阵:")
   print(matrix_dropout)

输出:

原始矩阵:
tensor([[ 0.1143, -1.0621,  0.7031, -0.7662, -1.1596],
       [-0.8340, -0.8210, -0.8747,  1.3130, -2.2559],
       [-0.6311,  0.4332,  2.6923,  0.0424,  1.1330],
       [ 1.7028,  0.3254,  0.1760,  1.9037, -0.2492]])

应用Dropout后的矩阵:
tensor([[ 0.1429, -1.3276,  0.8788, -0.9577, -1.4495],
       [-1.0425, -1.0262, -1.0934,  1.6413, -2.8199],
       [-0.0000,  0.5415,  3.3653,  0.0000,  0.0000],
       [ 0.0000,  0.4068,  0.2201,  0.0000, -0.3115]])

数一数刚刚好4个0。在举一个例子,在实际网络中应用也比较简单。

import torch
import torch.nn as nn

# 定义一个简单的神经网络
class Net(nn.Module):
   def __init__(self):
       super(Net, self).__init__()
       self.fc1 = nn.Linear(100, 64)
       self.dropout = nn.Dropout(0.5)
       self.fc2 = nn.Linear(64, 10)

   def forward(self, x):
       x = self.fc1(x)
       x = self.dropout(x)
       x = torch.relu(x)
       x = self.fc2(x)
       return x

# 创建网络实例
net = Net()

# 在训练过程中使用dropout
net.train()

# 在测试过程中禁用dropout
net.eval()

在训练过程中,通过调用net.train()启用Dropout层,而在测试过程中,通过调用net.eval()禁用Dropout层。这是因为在训练过程中,Dropout层会随机丢弃神经元的输出,而在测试过程中,我们希望保留所有神经元的输出来获得更准确的预测结果。

2 L1/L2正则化

Loss函数:


2.1 为什么L1,L2正则可以解决过拟合问题?

答:模型的复杂度和参数的数量和参数的范围决定,拟合过程中通常都倾向于让权值尽可能小,最后构造一个所有参数都比较小的模型。因为一般认为参数值小的模型比较简单,能适应不同的数据集,也在一定程度上避免了过拟合现象。可以设想一下对于一个线性回归方程,若参数很大,那么只要数据偏移一点点,就会对结果造成很大的影响;但如果参数足够小,数据偏移得多一点也不会对结果造成什么影响,专业一点的说法是抗扰动能力强。

L1正则:



其中,λ是正则化系数,控制正则化的强度;||w||₁表示参数向量w的L1范数。

L2正则:


其中,λ是正则化系数,控制正则化的强度;||w||₂表示参数向量w的L2范数。

给定特征X,训练模型得到的能满足测试集和验证集w值,可能有多个(求导的解不止一组),有的w值比较大,有的w值比较小,为了降低模型的复杂度,我们需要限制一下w的值,即想求解到比较小的w值,因此我们在损失函数后面直接加上了λ(w),由于梯度下降,为了使得总体L值小,那么后面的w也要比较小,从而得到使得模型的复杂度降低,从而解决过拟合问题。

2.2 为啥对参数w进行限制,不对参数B进行限制呢

因为B只能是曲线上下移动,不能降低复杂度

2.3 训练时如何确定λ值

考虑二维的情况,即只有两个权值和 ,此时对于梯度下降法,求解函数的过程可以画出等值线,同时L1正则化的函数也可以在二维平面上画出来。如下图:

图中彩色圆圈线是Loss中前半部分待优化项的等高线,就是说在同一条线上其取值相同,且越靠近中心其值越小。
黑色菱形区域是L1正则项限制。带有正则化的loss函数的最优解要在黑色菱形区域和彩色圆圈线之间折中,也就是说最优解出现在图中优化项等高线与正则化区域相交处。从图中可以看出,当待优化项的等高线逐渐向正则项限制区域扩散时,L1正则化的交点大多在坐标轴上,则很多特征维度上其参数w为0,因此会产生稀疏解;而正则化前面的系数,可以控制图形的大小。越小,约束项的图形越大(上图中的黑色方框);越大,约束项的图形就越小,可以小到黑色方框只超出原点范围一点点,这是最优点的值中的可以取到很小的值。

同时L2正则化的函数也可以在二维平面上画出来。如下图:

图中彩色一圈一圈的线是Loss中前半部分待优化项的等高线,就是说在同一条线上其取值相同,且越靠近中心其值越小。图中黑色圆形区域是L2正则项限制。带有正则化的loss函数的最优解要在loss函数和正则项之间折中,也就是说最优解出现在图中优化项等高线与正则化区域相交处。从图中可以看出,当待优化项的等高线逐渐向正则项限制区域扩散时L2正则化的交点大多在非坐标轴上,二维平面下L2正则化的函数图形是个圆,与方形相比,被磨去了棱角。因此与相交时使得或等于零的机率小了许多,这就是为什么L2正则化不具有稀疏性的原因。

一般来说,λ的确定,从0开始,逐渐增大λ。在训练集上学习到参数,然后在测试集上验证误差。反复进行这个过程,直到测试集上的误差最小。一般的说,随着λ从0开始增大,测试集的误分类率应该是先减小后增大,交叉验证的目的,就是为了找到误分类率最小的那个位置。建议一开始将正则项系数λ设置为0,先确定一个比较好的learning rate。然后固定该learning rate,给λ一个值(比如1.0),然后根据validation accuracy,将λ增大或者减小10倍,增减10倍是粗调节,当你确定了λ的合适的数量级后,比如λ= 0.01,再进一步地细调节,比如调节为0.02,0.03,0.009之类。

上一篇 下一篇

猜你喜欢

热点阅读