权重衰退 + 丢弃法
权重衰退(Weight Decay)
回忆:如何控制一个模型的容量(方法1:把模型变得比较小;方法2:使得模型参数的选择范围比较小)
是一种正则化模型的技术;
使用均方范数作为硬性限制
- 通过限制参数值的选择范围来控制模型的容量
(最小化损失的时候,限制权重向量 w 的范数平方不能超过 θ)- 通常不限制偏移b(限不限制都差不多)
- 小的 θ 意味着更强的正则项
-
直观解释理解: θ 确实是把w限制在一个范围里面,但实际上使用以下的柔性限制。
使用均方范数作为柔性限制
- 对每个 θ ,都可以找到 λ 使得之前的目标函数等价于下面:
- 可以通过拉格朗日乘子来证明
- 超参数λ控制了正则项的重要程度
- λ = 0:无作用
- λ → ∞,w* → 0
对最优解的影响:
理解:橙色是惩罚项:lamda/2*||w||平方的图像,绿色是原来损失函数的图像;曲线代表损失函数,有几个圈就是对不同的w来说,一个圈对应一个参数,最中间的点是参数的最优解。
大概应该就是:新的损失函数由两项组成,此时求导后,梯度有两项了,一项将w向绿线中心拉,一项将w向原点拉进,最后将在w*点达到一个平衡
-
参数更新法则
-
计算梯度
-
时间 t 更新参数
- 通常 nλ<1,在深度学习中通常叫做权重衰退
- 主要变化:先把当前的值 缩小再 沿着负梯度方向学习
总结
- 权重衰退通过L2 正则项使得模型参数不会过大,从而控制模型复杂度
- 正则项权重是控制模型复杂度的超参数。
代码实现- 从零实现
# 权重衰退
# 像之前一样 导入相关包
import torch
from torch import nn
from d2l import torch as d2l
# 像以前一样生成一些数据:
# 
# 将训练数据设置的很小(当训练数据比较少的时候容易 过拟合)
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)
# 从零开始实现
#下面我们将从头开始实现权重衰减,只需将 𝐿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]
# 定义L2范数惩罚
# 实现这一惩罚最方便的方法是对所有项求平方后并将它们求和
def l2_penalty(w):
return torch.sum(w.pow(2)) / 2
# 定义训练代码实现:
def train(lambd):
w,b = init_params()
# 定义了一个线性回归模型,
net, loss = lambda X: d2l.linreg(X, w, b<