大纲:

  • L1和L2的区别以及范数相关知识
  • 对参数进行L1和L2正则化的作用与区别
  • pytorch实现L1与L2正则化
  • 对特征进行L2正则化的作用

L1和L2的区别以及范数

  使用机器学习方法解决实际问题时,我们通常要用L1或L2范数做正则化(regularization),从而限制权值大小,减少过拟合风险,故其又称为权重衰减。特别是在使用梯度下降来做目标函数优化时。

L1和L2的区别
在机器学习中,

  • L1范数(L2 normalization)是指向量中各个元素绝对值之和,通常表述为∥wi∥1\|\boldsymbol{w_i}\|_1∥wi​∥1​,线性回归中使用L1正则的模型也叫Lasso regularization
    比如 向量A=[1,-1,3], 那么A的L1范数为 |1|+|-1|+|3|.

  • L2范数指权值向量w中各个元素的平方和然后再求平方根(可以看到Ridge回归的L2正则化项有平方符号),通常表示为∥wi∥2\|\boldsymbol{w_i}\|_2∥wi​∥2​, 线性回归中使用L2正则的模型又叫岭回归(Ringe regularization)。

简单总结一下就是:

  • L1范数: 为x向量各个元素绝对值之和。
  • L2范数: 为x向量各个元素平方和的1/2次方,L2范数又称Euclidean范数或者Frobenius范数
  • Lp范数: 为x向量各个元素绝对值p次方和的1/p次方.

下图为p从无穷到0变化时,三维空间中到原点的距离(范数)为1的点构成的图形的变化情况。以常见的L-2范数(p=2)为例,此时的范数也即欧氏距离,空间中到原点的欧氏距离为1的点构成了一个球面

参数正则化作用

  • L1: 为模型加入先验, 简化模型, 使权值稀疏,由于权值的稀疏,从而过滤掉一些无用特征,防止过拟合
  • L2: 根据L2的特性,它会使得权值减小,即使平滑权值,一定程度上也能和L1一样起到简化模型,加速训练的作用,同时可防止模型过拟合

关于为什么L1会使得权重稀疏,而L2会使得权值平滑,可以参考知乎上一位答主的台大林轩田老师人工智能基石课笔记,从凸优化,梯度更新,概率分布三个角度诠释L1和L2正则化的原理和区别。我把笔记搬运到这:



pytorch实现L1与L2正则化

网上很多关于L2和L1正则化的对象都是针对参数的,或者说权重,即权重衰减,可以用pytorch很简单的实现L2惩罚:

class torch.optim.Adam(params, lr=0.001, betas=(0.9, 0.999), eps=1e-08, weight_decay=0, amsgrad=False)

如上,weight_decay参数即为L2惩罚项前的系数
举个栗子,对模型中的某些参数进行惩罚时

#定义一层感知机
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) # 对权重参数衰减,惩罚项前的系数为wd
optimizer_b = torch.optim.SGD(params=[net.bias], lr=lr)  # 不对偏差参数衰减

而对于L1正则化或者其他的就比较麻烦了,因为pytorch优化器只封装了L2惩罚功能,参考pytorch实现L2和L1正则化regularization的方法

class Regularization(torch.nn.Module):def __init__(self,model,weight_decay,p=2):''':param model 模型:param weight_decay:正则化参数:param p: 范数计算中的幂指数值,默认求2范数,当p=0为L2正则化,p=1为L1正则化'''super(Regularization, self).__init__()if weight_decay <= 0:print("param weight_decay can not <=0")exit(0)self.model=modelself.weight_decay=weight_decayself.p=pself.weight_list=self.get_weight(model)self.weight_info(self.weight_list)def to(self,device):'''指定运行模式:param device: cude or cpu:return:'''self.device=devicesuper().to(device)return selfdef forward(self, model):self.weight_list=self.get_weight(model)#获得最新的权重reg_loss = self.regularization_loss(self.weight_list, self.weight_decay, p=self.p)return reg_lossdef get_weight(self,model):'''获得模型的权重列表:param model::return:'''weight_list = []for name, param in model.named_parameters():if 'weight' in name:weight = (name, param)weight_list.append(weight)return weight_listdef regularization_loss(self,weight_list, weight_decay, p=2):'''计算张量范数:param weight_list::param p: 范数计算中的幂指数值,默认求2范数:param weight_decay::return:'''# weight_decay=Variable(torch.FloatTensor([weight_decay]).to(self.device),requires_grad=True)# reg_loss=Variable(torch.FloatTensor([0.]).to(self.device),requires_grad=True)# weight_decay=torch.FloatTensor([weight_decay]).to(self.device)# reg_loss=torch.FloatTensor([0.]).to(self.device)reg_loss=0for name, w in weight_list:l2_reg = torch.norm(w, p=p)reg_loss = reg_loss + l2_regreg_loss=weight_decay*reg_lossreturn reg_lossdef weight_info(self,weight_list):'''打印权重列表信息:param weight_list::return:'''print("---------------regularization weight---------------")for name ,w in weight_list:print(name)print("---------------------------------------------------")

class Regularization的使用


# 检查GPU是否可用
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")print("-----device:{}".format(device))
print("-----Pytorch version:{}".format(torch.__version__))weight_decay=100.0 # 正则化参数model = my_net().to(device)
# 初始化正则化
if weight_decay>0:reg_loss=Regularization(model, weight_decay, p=2).to(device)
else:print("no regularization")criterion= nn.CrossEntropyLoss().to(device) # CrossEntropyLoss=softmax+cross entropy
optimizer = optim.Adam(model.parameters(),lr=learning_rate)#不需要指定参数weight_decay# train
batch_train_data=...
batch_train_label=...out = model(batch_train_data)# loss and regularization
loss = criterion(input=out, target=batch_train_label)
if weight_decay > 0:loss = loss + reg_loss(model)
total_loss = loss.item()# backprop
optimizer.zero_grad()#清除当前所有的累积梯度
total_loss.backward()
optimizer.step()

特征正则化作用

上面介绍了对于权重进行正则化的作用以及具体实现,其实在很多模型中,也会对特征采用L2归一化,有的时候在训练模型时,经过几个batch后,loss会变成nan,此时,如果你在特征后面加上L2归一化,可能可以很好的解决这个问题,而且有时会影响训练的效果,深有体会。
L2正则的原理比较简单,如下公式:
y=xi∑i=0Dxi2\boldsymbol{y} = \frac{\boldsymbol{x_i}}{\sum_{i=0}^D\boldsymbol{{x_i}}^2 }y=∑i=0D​xi​2xi​​
其中D为向量的长度,经过l2正则后xi\boldsymbol{x_i}xi​向量的元素平方和等于1

python实现

def l2norm(X, dim=-1, eps=1e-12):"""L2-normalize columns of X"""norm = torch.pow(X, 2).sum(dim=dim, keepdim=True).sqrt() + epsX = torch.div(X, norm)return X

在SSD目标检测的conv4_3层便使用了L2Norm

对特征进行L2正则的具体作用如下:

  • 防止梯度消失或者梯度爆炸
  • 统一量纲,加快模型收敛

参考:

机器学习中L1和L2的直观理解
几种范数的介绍

详解L1和L2正则化相关推荐

  1. L1、L2正则化详解

    正则化是一种回归的形式,它将系数估计(coefficient estimate)朝零的方向进行约束.调整或缩小.也就是说,正则化可以在学习过程中降低模型复杂度和不稳定程度,从而避免过拟合的危险. 一. ...

  2. 梯度下降、牛顿法凸优化、L1、L2正则化、softmax、Batchnorm、droupout、Targeted Dropout详解

    一.梯度下降 问题提出:虽然给定一个假设函数,我们能够根据cost function知道这个假设函数拟合的好不好,但是毕竟函数有这么多,总不可能一个一个试吧?因此我们引出了梯度下降:能够找出cost ...

  3. 【L1正则化与L2正则化详解及为什么L1和L2正则化可防止过拟合】

    一.为什么L1和L2正则化可防止过拟合? 线性模型常用来处理回归和分类任务,为了防止模型处于过拟合状态,需要用L1正则化和L2正则化降低模型的复杂度,很多线性回归模型正则化的文章会提到L1是通过稀疏参 ...

  4. 机器学习中的L1与L2正则化图解!

    今日锦囊 特征锦囊:今天一起搞懂机器学习里的L1与L2正则化 今天我们来讲讲一个理论知识,也是老生常谈的内容,在模型开发相关岗位中出场率较高的,那就是L1与L2正则化了,这个看似简单却十分重要的概念, ...

  5. 【机器学习基础】一文搞懂机器学习里的L1与L2正则化

    文章来源于SAMshare,作者flora 特征锦囊:今天一起搞懂机器学习里的L1与L2正则化 今天我们来讲讲一个理论知识,也是老生常谈的内容,在模型开发相关岗位中出场率较高的,那就是L1与L2正则化 ...

  6. 深入理解L1、L2正则化

    过节福利,我们来深入理解下L1与L2正则化. 1 正则化的概念 正则化(Regularization) 是机器学习中对原始损失函数引入额外信息,以便防止过拟合和提高模型泛化性能的一类方法的统称.也就是 ...

  7. 机器学习中的L1和L2正则化项

    关注微信公众号[Microstrong],我写过四年Android代码,了解前端.熟悉后台,现在研究方向是机器学习.深度学习!一起来学习,一起来进步,一起来交流吧! 本文同步更新在我的微信公众号里,地 ...

  8. L1、L2正则化以及smooth L1 loss

       一.L1.L2正则化 当样本特征很多,而样本数相对较少时,学习过程很容易陷入过拟合.为了缓解过拟合问题,可以对损失函数加入正则化项.正则化项中的Lp范数有很多,常见的有L1范数和L2范数. 给定 ...

  9. L1、L2正则化的原理及适用场景

    1. L1正则化,也称Lasso回归 1.1 含义 权值向量  中各元素的绝对值之和,一般记作   . 1.2  公式表示 添加了L1正则化的损失函数一般可表示为: 1.3 作用 L1正则常被用来解决 ...

最新文章

  1. Ubuntu 12.04 64bit上安装Apache Traffic Server 4.1.2
  2. 想挖矿?不如先学习一下以太坊
  3. 004_strace工具
  4. WEB--一个不错的想法
  5. 九年双11云化架构演进和升级,打造更加完美的双11
  6. 超级计算机预测2月有雪寒潮,神预测!中国超级计算提前半个月预测了美国的寒潮...
  7. 【B站视频笔记】linux 进程间通信(ipc)信号(软中断信号)signal库函数、可靠信号和不可靠信号、信号集sigprocmask(信号掩码、信号递达Delivery、信号未决Pending)
  8. 史上最完整的文件和目录操作类
  9. XCTF-Reverse:insanity
  10. 【视频】网易杭州研究院副院长汪源2016QCon大会专访
  11. java队列实现限流,java中应对高并发的两种策略
  12. spring 集成 spring cloud config 的相关知识
  13. ASP.NET MVC 利用Razor引擎生成静态页
  14. 使用spring+quartz配置多个定时任务
  15. English trip V2-B 5 Apartment Living 公寓生活 Teacher:Tom
  16. 一文搞懂常见概率分布的直觉与联系
  17. NEC学习 ---- 布局 -两列, 右侧定宽,左侧自适应
  18. 关于目标文件系统,文件过大的解决方法
  19. 外链式样式表_WEB前端 CSS样式表
  20. 机器学习算法——支持向量机SVM4(SMO算法及KTT条件)

热门文章

  1. Class not found: “com.parkManagement.dao.DaoTest 测试找不到测试类
  2. input框输入中文内容,另一个input框中时时显示转换后的拼音首字母缩写
  3. Linux驱动入门学习(三):I2C架构全面理解
  4. 蒙特卡罗方法在金融领域中的应用:从风险管理到投资组合优化
  5. flask+链家+福州房产信息网
  6. python 培训 太原
  7. io.protostuff.ProtostuffIOUtil序列化
  8. C#人脸识别入门篇-STEP BY STEP人脸识别--入门篇
  9. 为什么你逃不脱打工被老板压榨的命运?
  10. 【考研】数据结构考点——希尔排序