正则化方法(权重衰退和Dropout)

正则化方法和以前学过的正则表达式没有任何关系!
花书 p141 说到:

能显式地减少测试误差(可能会以增大训练误差为代价)的方法都被称为正则化。

0. 环境介绍

环境使用 Kaggle 里免费建立的 Notebook

教程使用李沐老师的 动手学深度学习 网站和 视频讲解

小技巧:当遇到函数看不懂的时候可以按 Shift+Tab 查看函数详解。

1. 权重衰减

权重衰减是正则化方法之一,权重衰减通过 L2 正则项使得模型参数不会过大,减少噪声的影响,从而控制模型复杂度。

我学这个权重衰减一开始就是学得迷迷糊糊的。
大家可以看一下这个视频看看能不能理解:王木头学科学。
李老师Q&A:
为什么控制模型参数值变小就可以减少模型复杂度?

如果不限制 w 的取值,有大有小就会导致得到的结果类似于上图中的蓝线(比较复杂的曲线)。如果控制 w 的取值得到类似于上图绿线的结果(比较平滑的曲线)。

1.1 使用均方范数作为硬性限制

通过限制参数值的选择范围来控制模型容量:
min⁡ℓ(w,b)subject to ∥w∥2≤θ\min \ell(\mathbf{w}, b) \quad \text {subject to }\|\mathbf{w}\|_{2} \leq \theta minℓ(w,b)subject to ∥w∥2​≤θ
通常不限制偏移 b (限不限制都差不多),b 不会改变函数的形状,只会改变模型的平移情况。
小的 θ\thetaθ 意味着更强的正则项。

1.2 使用均方范数作为柔性限制

对于每个 θ\thetaθ,都可以找到 λ\lambdaλ 使得之前的目标函数等价于:
min⁡ℓ(w,b)+λ2∥w∥2\min\quad \ell(\mathbf{w}, b)+\frac{\lambda}{2}\|\mathbf{w}\|_{2} minℓ(w,b)+2λ​∥w∥2​
超参数 λ\lambdaλ 控制了正则项的重要程度

  • λ=0\lambda=0λ=0:无作用
  • λ→∞,w∗→0\lambda \rightarrow \infty, \mathbf{w}^{*} \rightarrow 0λ→∞,w∗→0

1.3 演示对最优解的影响


λ2∥w∥2\frac{\lambda}{2}\|w\|^22λ​∥w∥2 也被称为惩罚项,较小的 λ\lambdaλ 值对应较少 www 约束的, 而较大的 λ\lambdaλ 值对 www 的约束更大。

过拟合:

加入正则化得到的结果:

图来自:王木头学科学。

1.4 参数更新法则

计算梯度:
∂∂w(ℓ(w,b)+λ2∥w∥2)=∂ℓ(w,b)∂w+λw\frac{\partial}{\partial \mathbf{w}}\left(\ell(\mathbf{w}, b)+\frac{\lambda}{2}\|\mathbf{w}\|_{2}\right)=\frac{\partial \ell(\mathbf{w}, b)}{\partial \mathbf{w}}+\lambda \mathbf{w} ∂w∂​(ℓ(w,b)+2λ​∥w∥2​)=∂w∂ℓ(w,b)​+λw
时间 t 更新参数:
wt+1=(1−ηλ)wt−η∂ℓ(wt,bt)∂wt\mathbf{w}_{t+1}=(1-\eta \lambda) \mathbf{w}_{t}-\eta \frac{\partial \ell\left(\mathbf{w}_{t}, b_{t}\right)}{\partial \mathbf{w}_{t}} wt+1​=(1−ηλ)wt​−η∂wt​∂ℓ(wt​,bt​)​
通常 ηλ<1\eta \lambda<1ηλ<1,在深度学习中通常叫做权重衰退。

2. 权重衰减代码

2.0 导入模块

#!pip install -U d2l
%matplotlib inline
import torch
from torch import nn
from d2l import torch as d2l

2.1 生成数据

按照公式生成数据:
y=0.05+∑i=1d0.01xi+ϵwhere ϵ∼N(0,0.012).y = 0.05 + \sum_{i = 1}^d 0.01 x_i + \epsilon \text{ where } \epsilon \sim \mathcal{N}(0, 0.01^2). y=0.05+i=1∑d​0.01xi​+ϵ where ϵ∼N(0,0.012).

n_train, n_test, num_inputs, batch_size = 20, 100, 200, 5
true_w, true_b = torch.ones((num_inputs, 1)) * 0.01, 0.05
train_data = d2l.synthetic_data(true_w, true_b, n_train)
train_iter = d2l.load_array(train_data, batch_size)
test_data = d2l.synthetic_data(true_w, true_b, n_test)
test_iter = d2l.load_array(test_data, batch_size, is_train=False)

我们选择标签是关于输入的线性函数。 标签同时被均值为 000,标准差为 0.010.010.01 高斯噪声破坏。 为了使过拟合的效果更加明显,我们可以将问题的维数增加到 d=200d=200d=200, 并使用一个只包含 202020 个样本的小训练集,以及 100100100 个样本的测试集。

2.2 初始化参数模型

def init_params():w = torch.normal(0, 1, size=(num_inputs, 1), requires_grad=True)b = torch.zeros(1, requires_grad=True)return [w, b]

2.3 定义 L2 范数惩罚

def l2_penalty(w):return torch.sum(w.pow(2)) / 2

如果想变成 L1 范数惩罚只需要将 torch.sum(w.pow(2)) / 2 变成 torch.sum(torch.abs(w))

2.4 定义训练代码实现

def train(lambd):w, b = init_params()net, loss = lambda X: d2l.linreg(X, w, b), d2l.squared_lossnum_epochs, lr = 100, 0.003animator = d2l.Animator(xlabel='epochs', ylabel='loss', yscale='log',xlim=[5, num_epochs], legend=['train', 'test'])for epoch in range(num_epochs):for X, y in train_iter:# 增加了L2范数惩罚项,# 广播机制使l2_penalty(w)成为一个长度为batch_size的向量l = loss(net(X), y) + lambd * l2_penalty(w)l.sum().backward()d2l.sgd([w, b], lr, batch_size)if (epoch + 1) % 5 == 0:animator.add(epoch + 1, (d2l.evaluate_loss(net, train_iter, loss),d2l.evaluate_loss(net, test_iter, loss)))print('w的L2范数是:', torch.norm(w).item())

2.5 忽略正则化直接训练

train(lambd=0)


这里训练误差有了减少,但测试误差没有减少, 这意味着出现了严重的过拟合。

2.6 使用权重衰减

train(lambd=3)


可以看到训练误差相对于无正则化的结果更大,但是测试集的误差更小。

2.7 简洁实现

我们在实例化优化器时直接通过 weight_decay 指定 weight decay 超参数。 默认情况下,PyTorch 同时衰减权重和偏移。 这里我们只为权重设置了 weight_decay,所以偏置参数 bbb 不会衰减。

def train_concise(wd):net = nn.Sequential(nn.Linear(num_inputs, 1))for param in net.parameters():param.data.normal_()loss = nn.MSELoss(reduction='none')num_epochs, lr = 100, 0.003# 偏置参数没有衰减trainer = torch.optim.SGD([{"params":net[0].weight,'weight_decay': wd},{"params":net[0].bias}], lr=lr)animator = d2l.Animator(xlabel='epochs', ylabel='loss', yscale='log',xlim=[5, num_epochs], legend=['train', 'test'])for epoch in range(num_epochs):for X, y in train_iter:trainer.zero_grad()l = loss(net(X), y)l.mean().backward()trainer.step()if (epoch + 1) % 5 == 0:animator.add(epoch + 1,(d2l.evaluate_loss(net, train_iter, loss),d2l.evaluate_loss(net, test_iter, loss)))print('w的L2范数:', net[0].weight.norm().item())

3. Dropout

3.1 动机

一个好的模型需要对输入数据的扰动鲁棒

  • 使用有噪音的数据等价于 Tikhonov 正则
  • Dropout:在层之间加入噪音。

来自 B 站弹幕:意思就是输入数据加入随机扰动可以防止过拟合,泛化性更好,(数据自带的噪声可能出现偏好,加入随机噪声后,能把这种偏好抵消一点)等价于一种正则方式,现在对扰动的添加方式从输入位置放到了层间位置。

3.2 实践中的 Dropout

删除了 h2h_2h2​ 和 h5h_5h5​, 因此输出的计算不再依赖于 h2h_2h2​ 或 h5h_5h5​,并且它们各自的梯度在执行反向传播时也会消失。 这样,输出层的计算不能过度依赖于 h1,…,h5h_1, \ldots, h_5h1​,…,h5​ 的任何一个元素。

4. Dropout 代码

4.0 导入模块

#!pip install -U d2l
import torch
from torch import nn
from d2l import torch as d2l

4.1 定义 Dropout

def dropout_layer(X, dropout):assert 0 <= dropout <= 1# 在本情况中,所有元素都被丢弃if dropout == 1:return torch.zeros_like(X)# 在本情况中,所有元素都被保留if dropout == 0:return X# torch.rand(X.shape) 会产生 X.shape 形状的(0,1)的均匀分布的随机数,补充:randn 是生成标准正态分布的随机数mask = (torch.rand(X.shape) > dropout).float()return mask * X / (1.0 - dropout)

测试 dropout 分别为 000,0.50.50.5,111:

X= torch.arange(16, dtype = torch.float32).reshape((2, 8))
print(X)
print(dropout_layer(X, 0.))
print(dropout_layer(X, 0.5))
print(dropout_layer(X, 1.))

4.2 定义模型参数

num_inputs, num_outputs, num_hiddens1, num_hiddens2 = 784, 10, 256, 256

输入为 784=(28×28)784=(28×28)784=(28×28),输出为 101010 个类别。222 个全连接隐藏层,每个隐藏层有 256256256 个单元。

4.3 定义模型

# 两个隐藏层的丢弃率
dropout1, dropout2 = 0.2, 0.5class Net(nn.Module):def __init__(self, num_inputs, num_outputs, num_hiddens1, num_hiddens2,is_training = True):super(Net, self).__init__()self.num_inputs = num_inputsself.training = is_trainingself.lin1 = nn.Linear(num_inputs, num_hiddens1)self.lin2 = nn.Linear(num_hiddens1, num_hiddens2)self.lin3 = nn.Linear(num_hiddens2, num_outputs)self.relu = nn.ReLU()def forward(self, X):H1 = self.relu(self.lin1(X.reshape((-1, self.num_inputs))))# 只有在训练模型时才使用dropoutif self.training == True:# 在第一个全连接层之后添加一个dropout层H1 = dropout_layer(H1, dropout1)H2 = self.relu(self.lin2(H1))if self.training == True:# 在第二个全连接层之后添加一个dropout层H2 = dropout_layer(H2, dropout2)out = self.lin3(H2)return outnet = Net(num_inputs, num_outputs, num_hiddens1, num_hiddens2)

4.4 训练和测试

num_epochs, lr, batch_size = 10, 0.5, 256
loss = nn.CrossEntropyLoss(reduction='none')
train_iter, test_iter = d2l.load_data_fashion_mnist(batch_size)
trainer = torch.optim.SGD(net.parameters(), lr=lr)
d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs, trainer)

4.5 Dropout 简洁实现

net = nn.Sequential(nn.Flatten(),nn.Linear(784, 256),nn.ReLU(),# 在第一个全连接层之后添加一个dropout层nn.Dropout(dropout1),nn.Linear(256, 256),nn.ReLU(),# 在第二个全连接层之后添加一个dropout层nn.Dropout(dropout2),nn.Linear(256, 10))def init_weights(m):if type(m) == nn.Linear:nn.init.normal_(m.weight, std=0.01)net.apply(init_weights);trainer = torch.optim.SGD(net.parameters(), lr=lr)
d2l.train_ch3(net, train_iter, test_iter, loss, num_epochs, trainer)


将第一层和第二层隐藏层丢失率设置为 000 情况下的结果:

训练集精度比测试集精度稍微大一点。

4.6 李沐老师的 Q&A 补充

Dropout 操作是每一个 batch 就丢一次。
丢弃率一般设置 0.10.10.1,0.50.50.5,0.90.90.9。别问为什么这么设置,问就是经验。

Dropout 在训练时和在测试时的区别:

  • 训练时:Dropout 随机丢弃比率 ppp 神经元,使其失效,即输出为 000。
  • 测试时:全部神经元都发挥作用,但是他们的输出乘上了系数 (1−p)(1-p)(1−p)。

Pytorch 正则化方法(权重衰减和Dropout)相关推荐

  1. 深度学习的权重衰减是什么_【深度学习理论】一文搞透Dropout、L1L2正则化/权重衰减...

    前言 本文主要内容--一文搞透深度学习中的正则化概念,常用正则化方法介绍,重点介绍Dropout的概念和代码实现.L1-norm/L2-norm的概念.L1/L2正则化的概念和代码实现- 要是文章看完 ...

  2. pytorch学习笔记(十二):权重衰减

    文章目录 1. 方法 2. 高维线性回归实验 3. 从零开始实现 3.1 初始化模型参数 3.2 定义L2L_2L2​范数惩罚项 3.3 定义训练和测试 3.4 观察过拟合 3.5 使用权重衰减 4. ...

  3. 深度学习的权重衰减是什么_权重衰减和L2正则化是一个意思吗?它们只是在某些条件下等价...

    权重衰减== L2正则化? 神经网络是很好的函数逼近器和特征提取器,但有时它们的权值过于专门化而导致过度拟合.这就是正则化概念出现的地方,我们将讨论这一概念,以及被错误地认为相同的两种主要权重正则化技 ...

  4. 神经翻译笔记4扩展b. RNN的正则化方法

    文章目录 神经翻译笔记4扩展b. RNN的正则化方法 层归一化 对dropout的扩展 集大成的方法:AWD-LSTM 正则化方法 不同形式的dropout 变长的反向传播 嵌入共享 嵌入维度与隐藏层 ...

  5. ECCV2020 | SOD100K:超低参数量的高效显著性目标检测算法,广义OctConv和动态权重衰减...

    点击上方"AI算法修炼营",选择"星标"公众号 精选作品,第一时间送达 这篇文章收录于ECCV2020,是一篇超高效的显著性目标检测的算法,仅有100K的参数量 ...

  6. 谷歌大脑提出DropBlock卷积正则化方法,显著改进CNN精度

    点击我爱计算机视觉标星,更快获取CVML新技术 昨天arXiv新上一篇被NIPS2018会议接收的论文<DropBlock: A regularization method for convol ...

  7. 正则化方法:L1和L2 regularization、数据集扩增、dropout

    https://www.toutiao.com/a6704868049352131080/ 为什么要使用正则化 我们先回顾一下房价预测的例子.以下是使用多项式回归来拟合房价预测的数据: 正则化方法:防 ...

  8. 正则化方法/防止过拟合提高泛化能力的方法:L1和L2 regularization、数据集扩增、dropout

    转载自:http://blog.csdn.net/u012162613/article/details/44261657 本文是<Neural networks and deep learnin ...

  9. 正则化方法:数据增强、regularization、dropout

    文章目录 过拟合 overfitting 数据增强 正则化项 范数 norm L1 正则 Lasso regularizer L2 正则 Ridge Regularizer / Weight Deca ...

最新文章

  1. Android 笔记:BroadcastReceiver
  2. 77.Linux系统日志,screen工具介绍
  3. 健身品牌Shape获得数千万元Pre-A轮融资,清流资本领投
  4. C 图像处理 颜色相关宏定义
  5. css实现web前端最美的loading加载动画!
  6. wbepack中output.filename和output.chunkFilename
  7. Mysql添加字段.md
  8. Yii 2 美化 url
  9. oracle函数trunc的使用
  10. 三大抽样分布、正态总体下的抽样分布
  11. 1.2 架构结构和视图
  12. 陆维家具设计拆单软件
  13. 《特征工程入门与实践》读书笔记一
  14. 请教FlashCs3导入图片时出现无法导入问题。
  15. oracle 12c新特性 FETCH FIRST、WITH TIES 关键字详解
  16. python 还原九宫格图片_python生成九宫格图片
  17. bailian.openjudge 1190:生日蛋糕
  18. mysql设备未就绪_SQL Server 返回了错误 21(设备未就绪。) 解决方法
  19. STC用PCA测量脉宽_示波器在进行频率测量时如何减少误差
  20. 燕东微在科创板上市:市值263亿元,北京电控、亦庄国投等为股东

热门文章

  1. JCE cannot authenticate the provider BC问题解决
  2. activiti-explorer stencilset.json 国际化文件
  3. DeepMind爆发史:决定AI高峰的“游戏玩家”|深度学习崛起十年
  4. 数据的核密度估计及其可视化:Python实现
  5. Opencv值core组件(二):感兴趣区域选取与计算数组加权和
  6. HPRD数据库HPRD_Release9_062910表中最后一列RefSeq字段的含义
  7. 2022安全员-B证考试题及在线模拟考试
  8. hdu-2852 KiKi's K-Number---二分+树状数组
  9. kvm 模块加载时报错:insmod: error inserting 'kvm.ko': -1 Unknown symbol in module
  10. 旺旺机器人的快捷短语_机器人配置和我的快捷短语