权重衰减——L2正则化

《动手学深度学习pytorch》部分学习笔记,仅用作自己复习。

权重衰减

过拟合现象,即模型的训练误差小于它在测试集上的误差。虽然增⼤训练数据集可能会减轻过拟合,但是获取额外的训练数据往往代价高昂。应对过拟合问题的常用⽅法:权重衰减(weight decay)。

方法

权重衰减等价于L2 范数正则化(regularization)。正则化通过为模型损失函数添加惩罚项使学出的模型参数值较⼩,是应对过拟合的常⽤手段。

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

带有L2 范数惩罚项的新损失函数为

⾼维线性回归实验

下面,我们以高维线性回归为例来引⼊一个过拟合问题,并使用权重衰减来应对过拟合。设数据样本特征的维度为 p。对于训练数据集和测试数据集中特征为x 的任一样本,我们使用如下的线性函数来生成该样本的标签:

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

%matplotlib inline
import torch
import torch.nn as nn
import numpy as np
import sys
sys.path.append("..")
import d2lzh_pytorch as d2l
n_train, n_test, num_inputs = 20, 100, 200
true_w, true_b = torch.ones(num_inputs, 1) * 0.01, 0.05
features = 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:]

从零开始实现

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

初始化模型参数

# 定义随机初始化模型参数的函数。
def init_params():
    # 为每个参数都附上梯度。
    w = torch.randn((num_inputs, 1), requires_grad=True)
    b = torch.zeros(1, requires_grad=True)
    return [w, b]

定义L2  范数惩罚项

# 只惩罚模型的权重参数。
def l2_penalty(w):
    return (w**2).sum() / 2

定义训练和测试

# 定义如何在训练数据集和测试数据集上分别训练和测试模型。
# 与前面几节中不同的是,这里在计算最终的损失函数时添加了L2 范数惩罚项。
batch_size, num_epochs, lr = 1, 100, 0.003
net, loss = d2l.linreg, d2l.squared_loss
dataset = 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())

观察过拟合

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

输出:L2 norm of w: 15.114808082580566

使⽤权重衰减

fit_and_plot(lambd=3) 

输出:L2 norm of w: 0.035220853984355927 

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

简洁实现

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())

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

小结

  • 正则化通过为模型损失函数添加惩罚项使学出的模型参数值较小,是应对过拟合的常用手段。
  • 权重衰减等价于L2 范数正则化,通常会使学到的权重参数的元素较接近0。
  • 权重衰减可以通过优化器中的 weight_decay 超参数来指定。
  • 可以定义多个优化器实例对不同的模型参数使用不同的迭代⽅法。
<think>嗯,用户问的是“解耦权重衰减正则化”,我需要先理解这个概念。首先,权重衰减(Weight Decay)是机器学习中常用的正则化方法,用来防止过拟合。通常,权重衰减通过在损失函数中添加一个L2正则项,比如λ||w||&sup2;,其中λ是正则化系数,w是模型参数。这样在优化过程中,参数会被限制,避免变得过大。 不过,用户提到的是“解耦权重衰减正则化”(Decoupled Weight Decay Regularization),这应该是指将权重衰减与优化器的更新步骤分开处理。传统上,比如在使用SGD优化器时,权重衰减是直接加到梯度上的,也就是参数更新时减去学习率乘以梯度加上λ乘以参数。但可能存在问题,尤其是在使用自适应优化器(如Adam)时,因为Adam本身有自适应学习率,可能权重衰减的耦合导致效果不佳。 解耦的核心思想是将权重衰减参数更新的步骤分开。比如,在Adam优化器中,通常权重衰减是与梯度计算合并的,而解耦的方法则是在参数更新时独立地应用权重衰减。这样可以更精确地控制正则化的效果,避免自适应学习率对权重衰减的影响。这样做的优势可能包括更稳定的训练过程更好的模型性能。 另外,我记得有一篇论文可能提到过,比如《Decoupled Weight Decay Regularization》,作者指出在Adam等自适应优化器中解耦权重衰减可以提升效果。需要确认这个方法的实现细节,比如在更新参数时,先计算梯度更新,再单独应用权重衰减项,而不是将两者混合在一起。 可能还需要比较传统方法解耦方法的具体公式。传统SGD中,权重衰减是直接叠加在梯度上,而解耦方法则是分开处理,比如参数更新公式变为w = w - lr * (grad + λ * w),而解耦后可能是先计算梯度更新w = w - lr * grad,然后再应用w = w * (1 - lr * λ)。不过这里可能需要更准确的数学表达式。 此外,解耦权重衰减可能对学习率衰减系数的调整更鲁棒,因为两者是独立调整的,而不是像传统方法那样耦合在一起。这对于超参数的选择可能有帮助,尤其是在使用较大的学习率或衰减系数时,避免不稳定的情况。 总结来说,解耦权重衰减正则化就是将权重衰减从优化器的梯度更新步骤中分离出来,独立应用,以提高正则化的效果训练的稳定性,特别是在使用自适应优化器时效果更明显。需要确保在回答中准确描述其原理、优势,以及可能的实际应用场景。</think>解耦权重衰减正则化(Decoupled Weight Decay Regularization)是机器学习中一种改进权重衰减(Weight Decay)实现方式的技术,其核心思想是将**权重衰减**与**优化器的梯度更新步骤**解耦,以解决传统方法在自适应优化器(如Adam)中的局限性。 --- ### **1. 权重衰减的基本原理** 权重衰减是一种经典的**正则化技术**,通过在损失函数中添加L2正则项(即参数平方项)防止过拟合: $$ L_{\text{total}} = L_{\text{data}} + \frac{\lambda}{2} \|w\|^2 $$ 其中,$\lambda$是正则化系数,$w$是模型参数。在优化过程中,参数更新时会额外减去$\lambda w$,从而限制参数值的大小。 --- ### **2. 传统权重衰减的问题** 在**非自适应优化器**(如SGD)中,权重衰减直接作用于参数更新: $$ w_{t+1} = w_t - \eta (\nabla L + \lambda w_t) $$ ($\eta$为学习率,$\nabla L$为梯度) 但在**自适应优化器**(如Adam、RMSProp)中,权重衰减的实现通常与梯度计算耦合。例如,Adam的更新公式中,权重衰减项会被自适应学习率缩放,导致**正则化效果不稳定**,甚至可能破坏自适应学习率的优势。 --- ### **3. 解耦权重衰减的改进** 解耦权重衰减的核心是**将正则化与梯度更新分离**: 1. **先计算梯度更新**:仅基于损失函数的梯度调整参数。 2. **独立应用权重衰减**:在参数更新后,单独施加衰减项。 以Adam为例,解耦后的更新公式为: $$ w_{t+1} = w_t - \eta \cdot \text{AdamStep}(\nabla L) - \eta \lambda w_t $$ (`AdamStep`表示自适应学习率计算,权重衰减项$\eta \lambda w_t$独立于梯度) --- ### **4. 优势** - **更稳定的正则化**:权重衰减系数$\lambda$不受自适应学习率影响。 - **超参数调节更鲁棒**:学习率($\eta$)衰减系数($\lambda$)解耦,便于独立调整。 - **兼容性**:适用于Adam、RMSProp等优化器,提升其正则化效果。 --- ### **5. 实际应用** - **深度学习框架支持**:PyTorch的`AdamW`(Adam with decoupled weight decay)TensorFlow的`AdamW`均实现了此方法。 - **实验效果**:在图像分类(如ResNet)、自然语言处理(如Transformer)等任务中,解耦权重衰减常能取得更好的泛化性能。 --- ### **总结** 解耦权重衰减正则化通过分离梯度更新与权重衰减步骤,解决了传统方法在自适应优化器中的缺陷,是提升模型泛化能力的有效技术。其核心在于“独立控制学习率衰减强度”,使训练过程更稳定、超参数调节更直观。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Clark-dj

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值