初始化神经网络权重的方法总结 神经网络如果权重全部初始化为0会存在什么问题
ztj100 2024-12-18 18:19 33 浏览 0 评论
在本文中,评估了权值初始化的许多方法和当前的最佳实践
零初始化
将权值初始化为零是不行的。那我为什么在这里提到它呢?要理解权值初始化的需要,我们需要理解为什么将权值初始化为零是无效的。
让我们考虑一个类似于上面所示的简单网络。每个输入只是一个标量X?,X?X?。和每个神经元的权重是W?和W?。每次权重更新如下:
Out? = X?W? + X?W? + X?W?
Out? = X?W? + X?W? + X?*W?
正如你所看到的现在,如果权重矩阵W = [W?W?]被初始化为零,然后out1和out2都完全一样。
即使我们对两者都添加一个非零的随机偏差项,权值也会更新为非零,但它们仍将保持相同,因此隐藏单元的两个神经元都在计算相同的东西。换句话说,它们是对称的。
这是非常不可取的,因为这是浪费计算。这就是零初始化无法工作的原因。
随机初始化
现在我们知道权重必须是不同的,下一个想法是随机初始化这些权重。随机初始化比零初始化好得多,但是这些随机数可以是任意数吗?
假设你使用的是s型非线性。sigmoid函数如下所示。
我们可以看到,对于大到6的值,sigmoid的值几乎是1,对于小到-6的值,sigmoid的值为0。这意味着如果我们的权值矩阵被初始化为过大或过小的值,所有有用的信息都会在sigmoid函数中丢失。
如果我们使用ReLu非线性,这就不那么重要了,但是在将权重初始化为大值或小值时还有其他问题。有更好的方法来初始化权重。
Xavier初始化
Xavier初始化是由Xavier Glorot和Yoshua Bengio在2010年提出的。本文的主要目标是初始化权重,使激活的平均值为零,标准偏差为1。考虑如下所示计算的函数。
Z = WX + b
这里W是权值矩阵,X是来自前一层的输入,b是偏差。Z是一个层计算的输出,也称为激活。我们希望Z的均值是0,标准差是1。(从技术上讲,Z是ReLu等非线性激活后的结果)
为什么均值为0,标准差为1这么重要?
考虑一个有100层的深度神经网络。在每一步,权重矩阵乘以来自前一层的激活。如果每一层的激活大于1,当它们被重复乘以100次时,它们就会不断变大,爆炸到无穷大。类似地,如果激活值小于1,它们将消失为零。这叫做渐变爆炸和渐变消失问题。 我们可以从下图中看到这一点。甚至比1稍大一点的值也会爆炸成非常大的数字,而比1稍小一点的值也会消失为零。
为了避免梯度和激活的爆炸和消失,我们希望激活的平均值为0,标准偏差为1。我们可以通过仔细选择权重来实现这一点。
在本文发布期间,权值的最佳实践是从均匀分布[-1,1]中随机选取,然后除以输入维数的平方根。事实证明,这不是一个好主意,梯度消失了,如果可能的话,训练也非常缓慢。
这个问题通过Xavier的初始化得到了解决,Xavier的初始化建议我们从一个均匀分布中随机初始化权重,如下图所示。
Xavier 初始化的 Uniform分布
现在,Xavier的初始化是通过从标准正态分布中选择权重来完成的,每个元素都要除以输入维度大小的平方根。在PyTorch中,代码如下所示。
torch.randn(n_inp, n_out)*math.sqrt(1/n_inp)
Xavier的初始化工作相当好,对于对称非线性,如sigmoid和Tanh。然而,对于目前最常用的非线性函数ReLu,它的工作效果并不理想。
Kaiming 初始化
2015年,何凯明等人撰写了一篇名为《Deep into Rectifiers: Surpassing Human-Level Performance on ImageNet Classification》的论文,在论文中,他们介绍了现在广为人知的Kaiming 初始化。
但是为什么我们需要Kaiming 初始话呢?关于ReLu非线性的Xavier Init有什么问题?
从上图中可以看出,ReLu对所有X<0给出了0,对所有X>给出了Y=X。ReLu并没有很好地定义0,但大多数程序都将其赋值为接近于0的近似,比如machine epsilon。
左:均值0,标准差1的正态分布。右:通过ReLu后的正态分布。
在上面我们可以看到2个散点图,左边是ReLu之前的数据,右边是ReLu之后的数据。从图像中可以清楚地看到,在ReLu之后,方差几乎是一半,平均值略高。这改变了激活,方差减少了一半,所以我们需要将方差加倍才能得到Xavier Init的原始效果。因此,我们将权重乘以一个额外的值√2。所以在PyTorch中,Kaiming 初始化如下所示。
torch.randn(n_inp, n_out)*math.sqrt(2/n_inp)
如果你仍然对上面的公式不太理解,那么记住:
方差=标准差的平方
方差翻倍所以需要乘以√2
Fixup初始化
Fixup是Zhang等人在2019年提出的初始化。根据他们的观察,Kaiming 的初始化和其他标准的初始化不能很好地用于有残差分支的网络(又叫残差网络)。他们发现,标准初始化的残差网络只有在BatchNorm下才能正常工作。
让我们看看为什么Kaiming Init不能在残差网络上更好的工作。考虑如下图所示的跳过连接。X2 = f(X1) X3 = f(X2) + X1。我们知道Kaiming init选择的权重使得每一层后的激活有0均值和1方差。我们知道X1的方差是1 X2的方差是1。但是Kaiming init不考虑跳过连接。因此,根据总方差定律,X3的方差翻倍。由残差分支添加的额外方差在Kaiming Init中没有考虑在内。因此残差网络不能很好地与标准初始化一起工作,除非它们有BatchNorm。没有BatchNorm,输出方差会随深度呈指数爆炸式增长。
Var[X???] ≈ 2Var[X? ]
残差网络中的跳过连接
该论文的作者提出了一个重要的观察结果,即SGD更新每个残差分支的权重会在高度相关的方向上更新网络输出。 这意味着,如果所有残差分支权重都由X更新,则网络输出也将在相同的权重更新方向上按比例地更改为X。
作者将所需的网络输出变化定义为Θ(η)。 如我们所知,平均每个残差分支对输出更新的贡献均等。如果我们称残差分支的数量为L,则每个残差分支平均应将输出改变Θ(η/ L),以实现总变化。 输出上的Θ(η)。
接下来,作者展示如何初始化m层的残差分支,以便SGD更新将输出更改Θ(η/ L)。 作者表明,可以通过以下方式重新调整这些权重层的标准初始化:
权重比例因子
作者还讨论了偏差和乘数的效用。 他们发现在每次卷积,添加一个初始值为0的偏置层,线性层和逐元素激活导致训练显着改善之前。 他们还发现,在每个残差分支上添加一个乘法标度有助于通过标准化来模仿网络的权重范数动态。
所以所有的而解决方案汇总如下
LSUV初始化
Mishkin等人在2016年的一篇论文《All you need is a good Init》中介绍了LSUV。LSUV Init是一种数据驱动的方法,它具有最小的计算量和非常低的计算开销。初始化是一个2部分的过程,首先初始化标准正交矩阵的权值(与高斯噪声相反,它只是近似正交)。下一部分是迭代一个小批处理并缩放权重,以便激活的方差为1。作者断言,在大范围内,小批量大小对方差的影响可以忽略不计。
在论文中,作者列出了以下初始化步骤。
1. 使用单位方差将权重初始化为高斯噪声。
1. 使用SVD或QR将它们分解为正交坐标。
1. 使用第一个微型批处理在网络中进行迭代,并在每次迭代比例时权重以使输出方差接近1。重复直到输出方差为1或发生最大迭代。
论文中,作者提出比例因子为√Var(BL),其中BL —它的输出Blob
作者还提出了最大迭代次数的值,以防止无限循环。但是,在他们的实验中,他们发现在1–5次迭代中实现了单位方差。
可以将LSUV Init看作是正交初始化和BatchNorm的组合,它仅在第一个迷你批处理中执行。 作者在实验中表明,与完整的BatchNorm相比,该方法在计算上非常高效。
转移学习
转移学习是一种在我们的新模型中使用已经训练有素的模型进行权重的方法,该模型已经针对相似的任务进行了训练。 这些权重已经学习了很多有用的信息,我们可以针对我们的特定目标进行微调! 我们有一个了不起的模型,没有初始化的麻烦。
每次使用来自另一个模型的预训练权重都是最好的方法。唯一需要我们自己初始化权值的情况是,我们在一个从未有人训练过的网络上工作。在大多数实际情况下,情况并非如此,所以一般情况下,我们使用一个与训练的模型作为我们训练的开始是一个很好的习惯。
作者 Akash Shastri
deephub翻译组
相关推荐
- SpringBoot整合SpringSecurity+JWT
-
作者|Sans_https://juejin.im/post/5da82f066fb9a04e2a73daec一.说明SpringSecurity是一个用于Java企业级应用程序的安全框架,主要包含...
- 「计算机毕设」一个精美的JAVA博客系统源码分享
-
前言大家好,我是程序员it分享师,今天给大家带来一个精美的博客系统源码!可以自己买一个便宜的云服务器,当自己的博客网站,记录一下自己学习的心得。开发技术博客系统源码基于SpringBoot,shiro...
- springboot教务管理系统+微信小程序云开发附带源码
-
今天给大家分享的程序是基于springboot的管理,前端是小程序,系统非常的nice,不管是学习还是毕设都非常的靠谱。本系统主要分为pc端后台管理和微信小程序端,pc端有三个角色:管理员、学生、教师...
- SpringBoot+LayUI后台管理系统开发脚手架
-
源码获取方式:关注,转发之后私信回复【源码】即可免费获取到!项目简介本项目本着避免重复造轮子的原则,建立一套快速开发JavaWEB项目(springboot-mini),能满足大部分后台管理系统基础开...
- Spring Boot的Security安全控制——认识SpringSecurity!
-
SpringBoot的Security安全控制在Web项目开发中,安全控制是非常重要的,不同的人配置不同的权限,这样的系统才安全。最常见的权限框架有Shiro和SpringSecurity。Shi...
- 前同事2024年接私活已入百万,都是用这几个开源的SpringBoot项目
-
前言不得不佩服SpringBoot的生态如此强大,今天给大家推荐几款优秀的后台管理系统,小伙伴们再也不用从头到尾撸一个项目了。SmartAdmin...
- 值得学习的15 个优秀开源的 Spring Boot 学习项目
-
SpringBoot算是目前Java领域最火的技术栈了,除了书呢?当然就是开源项目了,今天整理15个开源领域非常不错的SpringBoot项目供大家学习,参考。高富帅的路上只能帮你到这里了,...
- 开发企业官网就用这个基于SpringBoot的CMS系统,真香
-
前言推荐这个项目是因为使用手册部署手册非常...
- 2021年超详细的java学习路线总结—纯干货分享
-
本文整理了java开发的学习路线和相关的学习资源,非常适合零基础入门java的同学,希望大家在学习的时候,能够节省时间。纯干货,良心推荐!第一阶段:Java基础...
- jeecg-boot学习总结及使用心得(jeecgboot简单吗)
-
jeecg-boot学习总结及使用心得1.jeecg-boot是一个真正前后端分离的模版项目,便于二次开发,使用的都是较流行的新技术,后端技术主要有spring-boot2.x、shiro、Myb...
- 后勤集团原料管理系统springboot+Layui+MybatisPlus+Shiro源代码
-
本项目为前几天收费帮学妹做的一个项目,JavaEEJSP项目,在工作环境中基本使用不到,但是很多学校把这个当作编程入门的项目来做,故分享出本项目供初学者参考。一、项目描述后勤集团原料管理系统spr...
- 白卷开源SpringBoot+Vue的前后端分离入门项目
-
简介白卷是一个简单的前后端分离项目,主要采用Vue.js+SpringBoot技术栈开发。除了用作入门练习,作者还希望该项目可以作为一些常见Web项目的脚手架,帮助大家简化搭建网站的流程。...
- Spring Security 自动踢掉前一个登录用户,一个配置搞定
-
登录成功后,自动踢掉前一个登录用户,松哥第一次见到这个功能,就是在扣扣里边见到的,当时觉得挺好玩的。自己做开发后,也遇到过一模一样的需求,正好最近的SpringSecurity系列正在连载,就结...
- 收藏起来!这款开源在线考试系统,我爱了
-
大家好,我是为广大程序员兄弟操碎了心的小编,每天推荐一个小工具/源码,装满你的收藏夹,每天分享一个小技巧,让你轻松节省开发效率,实现不加班不熬夜不掉头发,是我的目标!今天小编推荐一款基于Spr...
- Shiro框架:认证和授权原理(shiro权限认证流程)
-
优质文章,及时送达前言Shiro作为解决权限问题的常用框架,常用于解决认证、授权、加密、会话管理等场景。本文将对Shiro的认证和授权原理进行介绍:Shiro可以做什么?、Shiro是由什么组成的?举...
你 发表评论:
欢迎- 一周热门
- 最近发表
-
- SpringBoot整合SpringSecurity+JWT
- 「计算机毕设」一个精美的JAVA博客系统源码分享
- springboot教务管理系统+微信小程序云开发附带源码
- SpringBoot+LayUI后台管理系统开发脚手架
- Spring Boot的Security安全控制——认识SpringSecurity!
- 前同事2024年接私活已入百万,都是用这几个开源的SpringBoot项目
- 值得学习的15 个优秀开源的 Spring Boot 学习项目
- 开发企业官网就用这个基于SpringBoot的CMS系统,真香
- 2021年超详细的java学习路线总结—纯干货分享
- jeecg-boot学习总结及使用心得(jeecgboot简单吗)
- 标签列表
-
- idea eval reset (50)
- vue dispatch (70)
- update canceled (42)
- order by asc (53)
- spring gateway (67)
- 简单代码编程 贪吃蛇 (40)
- transforms.resize (33)
- redisson trylock (35)
- 卸载node (35)
- np.reshape (33)
- torch.arange (34)
- npm 源 (35)
- vue3 deep (35)
- win10 ssh (35)
- vue foreach (34)
- idea设置编码为utf8 (35)
- vue 数组添加元素 (34)
- std find (34)
- tablefield注解用途 (35)
- python str转json (34)
- java websocket客户端 (34)
- tensor.view (34)
- java jackson (34)
- vmware17pro最新密钥 (34)
- mysql单表最大数据量 (35)