3.12 权重衰减

上一节中我们观察了过拟合现象,即模型的训练误差远小于它在测试集上的误差。虽然增大训练数据集可能会减轻过拟合,但是获取额外的训练数据往往代价高昂。本节介绍应对过拟合问题的常用方法:权重衰减(weight decay)。

3.12.1 方法

权重衰减等价于 L2L_2L2​ 范数正则化(regularization)。正则化通过为模型损失函数添加惩罚项使学出的模型参数值较小,是应对过拟合的常用手段。我们先描述L2L_2L2​范数正则化,再解释它为何又称权重衰减。

L2L_2L2​范数正则化在模型原损失函数基础上添加L2L_2L2​范数惩罚项,从而得到训练所需要最小化的函数。L2L_2L2​范数惩罚项指的是模型权重参数每个元素的平方和与一个正的常数的乘积。以3.1节(线性回归)中的线性回归损失函数

ℓ(w1,w2,b)=1n∑i=1n12(x1(i)w1+x2(i)w2+b−y(i))2\ell(w_1, w_2, b) = \frac{1}{n} \sum_{i=1}^n \frac{1}{2}\left(x_1^{(i)} w_1 + x_2^{(i)} w_2 + b - y^{(i)}\right)^2 ℓ(w1​,w2​,b)=n1​i=1∑n​21​(x1(i)​w1​+x2(i)​w2​+b−y(i))2

为例,其中w1,w2w_1, w_2w1​,w2​是权重参数,bbb是偏差参数,样本iii的输入为x1(i),x2(i)x_1^{(i)}, x_2^{(i)}x1(i)​,x2(i)​,标签为y(i)y^{(i)}y(i),样本数为nnn。将权重参数用向量w=[w1,w2]\boldsymbol{w} = [w_1, w_2]w=[w1​,w2​]表示,带有L2L_2L2​范数惩罚项的新损失函数为

ℓ(w1,w2,b)+λ2n∥w∥2,\ell(w_1, w_2, b) + \frac{\lambda}{2n} \|\boldsymbol{w}\|^2,ℓ(w1​,w2​,b)+2nλ​∥w∥2,

其中超参数λ>0\lambda > 0λ>0。当权重参数均为0时,惩罚项最小。当λ\lambdaλ较大时,惩罚项在损失函数中的比重较大,这通常会使学到的权重参数的元素较接近0。当λ\lambdaλ设为0时,惩罚项完全不起作用。上式中L2L_2L2​范数平方∥w∥2\|\boldsymbol{w}\|^2∥w∥2展开后得到w12+w22w_1^2 + w_2^2w12​+w22​。有了L2L_2L2​范数惩罚项后,在小批量随机梯度下降中,我们将线性回归一节中权重w1w_1w1​和w2w_2w2​的迭代方式更改为

w1←(1−ηλ∣B∣)w1−η∣B∣∑i∈Bx1(i)(x1(i)w1+x2(i)w2+b−y(i)),w2←(1−ηλ∣B∣)w2−η∣B∣∑i∈Bx2(i)(x1(i)w1+x2(i)w2+b−y(i)).\begin{aligned} w_1 &\leftarrow \left(1- \frac{\eta\lambda}{|\mathcal{B}|} \right)w_1 - \frac{\eta}{|\mathcal{B}|} \sum_{i \in \mathcal{B}}x_1^{(i)} \left(x_1^{(i)} w_1 + x_2^{(i)} w_2 + b - y^{(i)}\right),\\ w_2 &\leftarrow \left(1- \frac{\eta\lambda}{|\mathcal{B}|} \right)w_2 - \frac{\eta}{|\mathcal{B}|} \sum_{i \in \mathcal{B}}x_2^{(i)} \left(x_1^{(i)} w_1 + x_2^{(i)} w_2 + b - y^{(i)}\right). \end{aligned} w1​w2​​←(1−∣B∣ηλ​)w1​−∣B∣η​i∈B∑​x1(i)​(x1(i)​w1​+x2(i)​w2​+b−y(i)),←(1−∣B∣ηλ​)w2​−∣B∣η​i∈B∑​x2(i)​(x1(i)​w1​+x2(i)​w2​+b−y(i)).​

可见,L2L_2L2​范数正则化令权重w1w_1w1​和w2w_2w2​先自乘小于1的数,再减去不含惩罚项的梯度。因此,L2L_2L2​范数正则化又叫权重衰减。权重衰减通过惩罚绝对值较大的模型参数为需要学习的模型增加了限制,这可能对过拟合有效。实际场景中,我们有时也在惩罚项中添加偏差元素的平方和。

3.12.2 高维线性回归实验

下面,我们以高维线性回归为例来引入一个过拟合问题,并使用权重衰减来应对过拟合。设数据样本特征的维度为ppp。对于训练数据集和测试数据集中特征为x1,x2,…,xpx_1, x_2, \ldots, x_px1​,x2​,…,xp​的任一样本,我们使用如下的线性函数来生成该样本的标签:

y=0.05+∑i=1p0.01xi+ϵy = 0.05 + \sum_{i = 1}^p 0.01x_i + \epsilon y=0.05+i=1∑p​0.01xi​+ϵ

其中噪声项ϵ\epsilonϵ服从均值为0、标准差为0.01的正态分布。为了较容易地观察过拟合,我们考虑高维线性回归问题,如设维度p=200p=200p=200;同时,我们特意把训练数据集的样本数设低,如20。

%matplotlib inline
import torch
import torch.nn as nn
import numpy as np
import sys
sys.path.append("..")
import d2lzh_pytorch as d2ln_train, n_test, num_inputs = 20, 100, 200
true_w, true_b = torch.ones(num_inputs, 1) * 0.01, 0.05features = torch.randn((n_train + n_test, num_inputs))
labels = torch.matmul(features, true_w) + true_b
labels += torch.tensor(np.random.normal(0, 0.01, size=labels.size()), dtype=torch.float)
train_features, test_features = features[:n_train, :], features[n_train:, :]
train_labels, test_labels = labels[:n_train], labels[n_train:]

3.12.3 从零开始实现

下面先介绍从零开始实现权重衰减的方法。我们通过在目标函数后添加L2L_2L2​范数惩罚项来实现权重衰减。

3.12.3.1 初始化模型参数

首先,定义随机初始化模型参数的函数。该函数为每个参数都附上梯度。

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

3.12.3.2 定义L2L_2L2​范数惩罚项

下面定义L2L_2L2​范数惩罚项。这里只惩罚模型的权重参数。

def l2_penalty(w):return (w**2).sum() / 2

3.12.3.3 定义训练和测试

下面定义如何在训练数据集和测试数据集上分别训练和测试模型。与前面几节中不同的是,这里在计算最终的损失函数时添加了L2L_2L2​范数惩罚项。

batch_size, num_epochs, lr = 1, 100, 0.003
net, loss = d2l.linreg, d2l.squared_lossdataset = torch.utils.data.TensorDataset(train_features, train_labels)
train_iter = torch.utils.data.DataLoader(dataset, batch_size, shuffle=True)def fit_and_plot(lambd):w, b = init_params()train_ls, test_ls = [], []for _ in range(num_epochs):for X, y in train_iter:# 添加了L2范数惩罚项l = loss(net(X, w, b), y) + lambd * l2_penalty(w)l = l.sum()if w.grad is not None:w.grad.data.zero_()b.grad.data.zero_()l.backward()d2l.sgd([w, b], lr, batch_size)train_ls.append(loss(net(train_features, w, b), train_labels).mean().item())test_ls.append(loss(net(test_features, w, b), test_labels).mean().item())d2l.semilogy(range(1, num_epochs + 1), train_ls, 'epochs', 'loss',range(1, num_epochs + 1), test_ls, ['train', 'test'])print('L2 norm of w:', w.norm().item())

3.12.3.4 观察过拟合

接下来,让我们训练并测试高维线性回归模型。当lambd设为0时,我们没有使用权重衰减。结果训练误差远小于测试集上的误差。这是典型的过拟合现象。

fit_and_plot(lambd=0)

输出:

L2 norm of w: 15.114808082580566

3.12.3.5 使用权重衰减

下面我们使用权重衰减。可以看出,训练误差虽然有所提高,但测试集上的误差有所下降。过拟合现象得到一定程度的缓解。另外,权重参数的L2L_2L2​范数比不使用权重衰减时的更小,此时的权重参数更接近0。

fit_and_plot(lambd=3)

输出:

L2 norm of w: 0.035220853984355927

3.12.4 简洁实现

这里我们直接在构造优化器实例时通过weight_decay参数来指定权重衰减超参数。默认下,PyTorch会对权重和偏差同时衰减。我们可以分别对权重和偏差构造优化器实例,从而只对权重衰减。

def fit_and_plot_pytorch(wd):# 对权重参数衰减。权重名称一般是以weight结尾net = nn.Linear(num_inputs, 1)nn.init.normal_(net.weight, mean=0, std=1)nn.init.normal_(net.bias, mean=0, std=1)optimizer_w = torch.optim.SGD(params=[net.weight], lr=lr, weight_decay=wd) # 对权重参数衰减optimizer_b = torch.optim.SGD(params=[net.bias], lr=lr)  # 不对偏差参数衰减train_ls, test_ls = [], []for _ in range(num_epochs):for X, y in train_iter:l = loss(net(X), y).mean()optimizer_w.zero_grad()optimizer_b.zero_grad()l.backward()# 对两个optimizer实例分别调用step函数,从而分别更新权重和偏差optimizer_w.step()optimizer_b.step()train_ls.append(loss(net(train_features), train_labels).mean().item())test_ls.append(loss(net(test_features), test_labels).mean().item())d2l.semilogy(range(1, num_epochs + 1), train_ls, 'epochs', 'loss',range(1, num_epochs + 1), test_ls, ['train', 'test'])print('L2 norm of w:', net.weight.data.norm().item())

与从零开始实现权重衰减的实验现象类似,使用权重衰减可以在一定程度上缓解过拟合问题。

fit_and_plot_pytorch(0)

输出:

L2 norm of w: 12.86785888671875

fit_and_plot_pytorch(3)

输出:

L2 norm of w: 0.09631537646055222

小结

  • 正则化通过为模型损失函数添加惩罚项使学出的模型参数值较小,是应对过拟合的常用手段。
  • 权重衰减等价于L2L_2L2​范数正则化,通常会使学到的权重参数的元素较接近0。
  • 权重衰减可以通过优化器中的weight_decay超参数来指定。
  • 可以定义多个优化器实例对不同的模型参数使用不同的迭代方法。

注:本节除了代码之外与原书基本相同,原书传送门

3.12_weight-decay相关推荐

  1. 2018/8/27 A Modified PSO Algorithm with Exponential Decay Weight

    信息: 2017年                            会议 题目: A Modified PSO Algorithm with Exponential Decay Weight 总 ...

  2. Power Law and Exponential Decay of Inter Contac...

    2019独角兽企业重金招聘Python工程师标准>>> MobiCom'07, September 9–14, 2007: the observed dichotomy: Power ...

  3. tf.nn.l2_loss() 与 权重衰减(weight decay)

    权重衰减(weight decay)   L2正则化的目的就是为了让权重衰减到更小的值,在一定程度上减少模型过拟合的问题,所以权重衰减也叫L2正则化.   L2正则化就是在代价函数后面再加上一个正则化 ...

  4. boost::hana::detail::decay用法的测试程序

    boost::hana::detail::decay用法的测试程序 实现功能 C++实现代码 实现功能 boost::hana::detail::decay用法的测试程序 C++实现代码 #inclu ...

  5. 梯度下降法快速教程 | 第三章:学习率衰减因子(decay)的原理与Python实现

    北京 | 深度学习与人工智能 12月23-24日 再设经典课程 重温深度学习阅读全文> 正文共3017个字.11张图.预计阅读时间:8分钟 前言 梯度下降法(Gradient Descent)是 ...

  6. 神经网络调参-warmup and decay

    欢迎大家访问个人博客:https://jmxgodlz.xyz 前言 本文将介绍神经网络调参技巧:warmup,decay.反向传播主要完成参数更新:θt=θt−1−α∗gt\theta_t=\the ...

  7. 深度学习:权重衰减(weight decay)与学习率衰减(learning rate decay)

    正则化方法:防止过拟合,提高泛化能力 避免过拟合的方法有很多:early stopping.数据集扩增(Data augmentation).正则化(Regularization)包括L1.L2(L2 ...

  8. 权值衰减weight decay的理解

    1. 介绍 权值衰减weight decay即L2正则化,目的是通过在Loss函数后加一个正则化项,通过使权重减小的方式,一定减少模型过拟合的问题. L1正则化:即对权重矩阵的每个元素绝对值求和, λ ...

  9. Adam和学习率衰减(learning rate decay)

    1.梯度下降法更新参数 梯度下降法参数更新公式: 其中,η 是学习率,θt是第 t 轮的参数,J(θt) 是损失函数,∇J(θt) 是梯度. 在最简单的梯度下降法中,学习率 ηη 是常数,是一个需要实 ...

  10. C++的std::is_same与std::decay

    一.背景 有一个模板函数,函数在处理int型和double型时需要进行特殊的处理,那么怎么在编译期知道传入的参数的数据类型是int型还是double型呢? #include <iostream& ...

最新文章

  1. CCF系列之画图(201409-2)
  2. 怎么能把看不清的照片给看清_哪些人会得?应该怎么治?关于白内障的“经典十问”...
  3. Linux下的shell脚本实战之用户创建
  4. 07/11/20 资料整理
  5. nyoj 710 外星人的供给站
  6. python字典的建立和输出_字典的创建和使用
  7. 深入理解计算机系统——bomblab
  8. PHP5.4 + IIS + Win2008 R2 配置
  9. 高斯积分(概率积分)以及它与伽马函数之间的关系
  10. [window] win7系统下电脑声音正常,右下角的小喇叭图标不见了
  11. 简单并不粗暴:自学产品的8个方法
  12. 土库曼人纳德沙为什么选择波斯一方与奥斯曼人作战?
  13. 有搜python题目的软件吗_Python开发及应用-中国大学mooc-试题题目及答案
  14. anaconda安装后打不开,卡在loading application
  15. 数据库原理与技术 作业及答案 复习用
  16. 电影《乌云背后的幸福线》观后感
  17. 判断单链表是否存在环,判断两个链表是否相交问题详解(转)
  18. 格力蒸发式冷风扇开机鸣响故障的修复
  19. Qt QImage 加载 BMP 图像的一个BUG
  20. 硬件描述语言与c语言函数,计算机硬件描述语言(VHDL)与编程语言(C语言)的区别及关系,...

热门文章

  1. MapReduce强化实验
  2. 【技术博客】当蒸馏遇上GAN
  3. 感知机不能表示“异或”
  4. 服务器日志显示意外关闭,服务器多次异常关闭,错误日志:计算机已经从检测错误后重新启动。。检测错误: - Microsoft Community...
  5. 布同:3D网游开发整体流程简述
  6. 拟立法禁止采购有漏洞软件,“引爆”网络安全行业
  7. 网站安全性之js注入
  8. android 仿美团日历,仿小米日历 纵享丝滑切换的周月效果
  9. 51ditu maps API 使用——显示所有信息——点击链接显示对应标记浮窗[修]
  10. python中类似对象吗_关于性能:什么是Python中最快的(访问)类似结构的对象?