L1主要是对BN层进行一些约束。L2主要是对参数W进行约束,偏执b相对W来说不影响模型,
自己代码出现过拟合,需要添加L2正则化来处理,记录在此。
知乎 https://zhuanlan.zhihu.com/p/388415560
假如损失函数是 C0 ,那么L2正则化就是:
然后反向传播求导就是这样
所以梯度下降以后权重更新的公式就是
就会发现实际上是进行普通的梯度下降之前先把原本的 w 乘一个 1−ηλ 系数。
pytorch添加正则化的方法有两种:
一是添加正则化项到损失函数中
代码如下
def l1_regularization(model, l1_alpha):
l1_loss = []
for module in model.modules():
if type(module) is nn.BatchNorm2d:
l1_loss.append(torch.abs(module.weight).sum())
return l1_alpha * sum(l1_loss)
def l2_regularization(model, l2_alpha):
l2_loss = []
for module in model.modules():
if type(module) is nn.Conv2d:
l2_loss.append((module.weight ** 2).sum() / 2.0)
return l2_alpha * sum(l2_loss)
第二种是在backward()
之后,添加正则化项到参数变量的梯度中,然后再进行step()
。
代码如下:
def l1_regularization(model, l1_alpha):
for module in model.modules():
if type(module) is nn.BatchNorm2d:
module.weight.grad.data.add_(l1_alpha * torch.sign(module.weight.data))
def l2_regularization(model, l2_alpha):
for module in model.modules():
if type(module) is nn.Conv2d:
module.weight.grad.data.add_(l2_alpha * module.weight.data)