深度学习方法(二十一):常用权重初始化方法Xavier,He initialization的推导-程序员宅基地

技术标签: 深度学习 Deep Learning  深度学习  神经网络  机器学习与深度学习笔记  

交叉熵目标函数更陡峭

在论文[1]中给了一个图示,一定程度上说明了为什么Cross Entropy用的很多,效果很好。图中上面的曲面表示的是交叉熵代价函数,下面的曲面表示的是二次代价函数,W1和W2分别表示层与层之间的连接权值。

在这里插入图片描述)

在1986年 Rumelhart 已经发现:logistic function 或者叫 conditional log-likelihood function: -log P(y|x) 的效果比 quadratic cost function(平方代价函数)的效果好很多的,原因在于 quadratic cost function(平方代价函数)在训练过程中会出现更多的 plateaus(平坦区域)。文章给出了一个两个参数下的图,图中采用的是具有单隐层的神经网络,激活函数使用的是 tanh 函数,对于输入信号进行随机初始化,可以看到二次代价函数具有更多的 plateaus (平坦区域)。

Xavier initialization [1][4]

早期的参数初始化方法普遍是将数据和参数初始化为标准高斯分布(均值0方差1),但随着神经网络深度的增加,这方法并不能解决梯度消失问题。

在这里插入图片描述
那么我们应该怎么通过初始化来缓解这个问题呢?
论文中首先给出了一个启发式的方法,想法是初始化值和神经元的输入个数有关:

We initialized the biases to be 0 and the weights Wij at each layer with the following commonly used heuristic, where U[−a, a] is the uniform distribution in the interval (−a, a) and n is the size of the previous layer (the number of columns of W)

W ∼ U [ − 1 n , 1 n ] V a r ( W ) = 1 3 n W \sim U[-\frac{1}{\sqrt n},\frac{1}{\sqrt n}]\\ Var(W) = \frac{1}{3n} WU[n 1,n 1]Var(W)=3n1

上面式子中, W ∼ W \sim W表示其中的每一个元素 W i j W_{ij} Wij都是符合一个均匀分布的。其中n表示本层的输入size,也就是上一层的输出size。我们知道随机变量在[a,b] 间的均匀分布的方差为
V a r = ( b − a ) 2 12 Var= \frac{(b-a)^2}{12} Var=12(ba)2
所以得到权重参数的方差是1/3n。先记一下,后面分析会讲到。

为了便于研究,作者假设使用线性激活函数 f ( x ) f(x) f(x),且在零点导数 f ′ ( 0 ) = 1 f'(0)=1 f(0)=1。实际上,作者研究的是参数的线性区域,可以认为是对任务的一个简化。

对于一层网络:
f ( x ) = ∑ i n w i x i + b f(\textbf x) = \sum_i^n w_ix_i + b f(x)=inwixi+b
输出的方差:
V a r ( f ( x ) ) = ∑ i n V a r ( w i x i ) Var(f(\textbf x)) = \sum_i^n Var(w_i x_i) Var(f(x))=inVar(wixi)
其中每一项:
V a r ( w i x i ) = E [ w i ] 2 V a r ( x i ) + E [ x i ] 2 V a r ( w i ) + V a r ( w i ) V a r ( x i ) Var(w_i x_i) = E[w_i]^2Var(x_i) + E[x_i]^2Var(w_i)+Var(w_i)Var(x_i) Var(wixi)=E[wi]2Var(xi)+E[xi]2Var(wi)+Var(wi)Var(xi)

当我们假设输入和权重都是0均值时(目前有了BN之后,每一层的输入也较容易满足),即 E [ x i ] = E [ w i ] = 0 E[x_i] = E[w_i] = 0 E[xi]=E[wi]=0,上式可以简化为:

V a r ( w i x i ) = V a r ( w i ) V a r ( x i ) Var(w_i x_i) =Var(w_i)Var(x_i) Var(wixi)=Var(wi)Var(xi)

由于w和x独立同分布,那么输出的方差就是

V a r ( f ( x ) ) = n V a r ( w i ) V a r ( x i ) Var(f(\textbf x)) = n Var(w_i) Var(x_i) Var(f(x))=nVar(wi)Var(xi)

我们发现,输出的方差是和输入的方差是一个线性倍数关系。假设 z i z^i zi是第 i i i层的输入向量, s i s^i si是第 i i i层激活函数的输入, f f f表示激活函数

s i = z i W i + b i z i + 1 = f ( s i ) s i + 1 = z i + 1 W i + 1 + b i + 1 \textbf s^i = \textbf z^i W^i + \textbf b^i \\ \textbf z^{i+1} = f(\textbf s^i)\\ \textbf s^{i+1} = \textbf z^{i+1} W^{i+1} + \textbf b^{i+1} si=ziWi+bizi+1=f(si)si+1=zi+1Wi+1+bi+1

可以得到:
对于一个多层的网络,某一层的方差可以用累积的形式表达:
V a r [ z i ] = V a r [ x ] ∏ i ′ = 0 i − 1 n i ′ V a r [ W i ′ ] Var[z^i] = Var[x] \prod_{i'=0}^{i-1}n_{i'} Var[W^{i'}] Var[zi]=Var[x]i=0i1niVar[Wi]

求反向我们可以得到(假设 f ′ ( s k i ) ≈ 1 f'(s_k^i) \approx 1 f(ski)1,其中Cost表示Loss):
∂ C o s t ∂ s k i = f ′ ( s k i ) W k , ⋅ i + 1 ∂ C o s t ∂ s i + 1 ∂ C o s t ∂ w l , k i = z l i ∂ C o s t ∂ s k i \frac{\partial Cost}{\partial s_k^i} = f'(s_k^i) W_{k,\cdot}^{i+1} \frac{\partial Cost}{\partial s^{i+1}} \\ \frac{\partial Cost}{\partial w_{l,k}^i} = z_l^i \frac{\partial Cost}{\partial s_k^i} skiCost=f(ski)Wk,i+1si+1Costwl,kiCost=zliskiCost

其中 V a r [ W i ′ ] Var[W^{i'}] Var[Wi]表示第 i ′ i' i层的共享权重的方差,对于 d d d层的网络(大饼博士注:下面第一个式子的变量的layer号,符号上和上面求 ∂ C o s t ∂ s k i \frac{\partial Cost}{\partial s_k^i} skiCost的式子,有一点歧义难看懂。主要上面是正向去写,在同一个层里面 S i S^i Si W i + 1 W^{i+1} Wi+1是一对。而下面第一个式子,理解成同一个层里面输入以及参数都是对应的 i ′ i' i,通过堆叠 d d d层,得到最初的输入 s i s^i si的梯度的方差)
V a r [ ∂ C o s t ∂ s i ] = V a r [ ∂ C o s t ∂ s d ] ∏ i ′ = i d n i ′ + 1 V a r [ W i ′ ] V a r [ ∂ C o s t ∂ w i ] = ∏ i ′ = 0 i − 1 n i ′ V a r [ W i ′ ] ∏ i ′ = i d − 1 n i ′ + 1 V a r [ W i ′ ] × V a r [ x ] V a r [ ∂ C o s t ∂ s d ] Var[\frac{\partial Cost}{\partial s^i}]=Var[\frac{\partial Cost}{\partial s^d}] \prod_{i'=i}^{d}n_{i'+1} Var[W^{i'}] \\ Var[\frac{\partial Cost}{\partial w^i}]= \prod_{i'=0}^{i-1}n_{i'} Var[W^{i'}] \prod_{i'=i}^{d-1}n_{i'+1} Var[W^{i'}] \times Var[x] Var[\frac{\partial Cost}{\partial s^d}] Var[siCost]=Var[sdCost]i=idni+1Var[Wi]Var[wiCost]=i=0i1niVar[Wi]i=id1ni+1Var[Wi]×Var[x]Var[sdCost]

如果我们希望,神经网络在前向计算的时候,输入输出的方差都是一致的,即 ∀ ( i , i ′ ) , V a r [ z i ] = V a r [ z i ′ ] \forall (i,i'), Var[z^i] = Var[z^{i'}] (i,i),Var[zi]=Var[zi],我们需要满足:

∀ i , n i V a r [ W i ] = 1 \forall i, \quad n_i Var[W^i] = 1 i,niVar[Wi]=1

类似的,如果我们希望反向计算的输入输出方差也是一致的, ∀ ( i , i ′ ) , V a r [ ∂ C o s t ∂ s i ] = V a r [ ∂ C o s t ∂ s i ′ ] \forall (i,i'), Var[\frac{\partial Cost}{\partial s^i}] = Var[\frac{\partial Cost}{\partial s^{i'}}] (i,i),Var[siCost]=Var[siCost],需要满足:

∀ i , n i + 1 V a r [ W i ] = 1 \forall i, \quad n_{i+1} Var[W^i] = 1 i,ni+1Var[Wi]=1

一个层的输入输出一般不相同,作为折中

∀ i , V a r [ W i ] = 2 n i + n i + 1 \forall i, \quad Var[W^i] = \frac{2}{n_i + n_{i+1}} i,Var[Wi]=ni+ni+12

这个就是Xavier初始化算法,认为神经网络每一层的参数的方差需要满足的方差(均值=0)。(注:这里并没有假设是符合什么分布的,只是要求方差是这样,所以理论上我们可以采用任意分布,只要方差等于上面的公式即可)。

常见的,我们可以用高斯分布,或者均匀分布来生成随机参数(对于Xavier初始化方式,例如pytorch提供了uniform和normal两种:)。

  • 如果是采用均匀分布,根据前面讲过的,随机变量在[a,b] 间的均匀分布的方差为 V a r = ( b − a ) 2 / 12 Var= {(b-a)^2}/{12} Var=(ba)2/12,那么我们只要用下面分布来采样,就可以得到上面的方差。这个公式也是Xavier论文[1]中给出的建议。

W ∼ U [ − 6 n j + n j + 1 , 6 n j + n j + 1 ] W \sim U[-\frac{\sqrt 6}{\sqrt {n_j + n_{j+1}}},\frac{\sqrt 6}{\sqrt {n_j + n_{j+1}}}] WU[nj+nj+1 6 ,nj+nj+1 6 ]

  • 如果是采用高斯分布,那么直接就:[6]

W ∼ N ( 0 , 2 n i + n i + 1 ) W \sim N(0, { \frac{2}{n_i + n_{i+1}}}) WN(0,ni+ni+12)

补充一句,caffe的Xavier实现有三种选择[7]:
在这里插入图片描述

He initialization [2][3]

前面Xavier方法只考虑了线性激活函数,而现在的神经网络(特别是CNN网络)采用的主要是ReLU和Leaky ReLU函数,He初始化方法就是来分析采用ReLU和Leaky ReLU激活函数下,如果我们希望每一层的输入输出方差不变,我们应该如何初始化权重参数,方法上和前一节基本一致。

对于一个卷积层或者全连接层,其表达式为

y l = W l x l + b l . y_l = W_l x_l + b_l. yl=Wlxl+bl.

W l W_l Wl b l b_l bl采样自0均值高斯分布,用 n l n_l nl表示第 l l l x l x_l xl的维数,在卷积层,有 n l = k 2 c n_l=k^2c nl=k2c k k k为卷积核的边长, c c c为channel数,注意到 y l y_l yl W l W_l Wl中元素与 x l x_l xl中对应元素的乘积的和,则上式各变量的方差关系可以表示为:

V a r [ y l ] = n l V a r [ W l x l ] = n l V a r [ W l ] E [ x l 2 ] . Var[y_l] = n_l Var[W_l x_l]=n_l Var[W_l]E[x_l^2]. Var[yl]=nlVar[Wlxl]=nlVar[Wl]E[xl2].

这里的 x l x_l xl项前并不是其方差,而是 E [ x l 2 ] E[x^2_l] E[xl2],因为 x l x_l xl通常并不具备0均值,例如ReLU激活函数得到的结果, x l x_l xl均为正值。注意到由于 W l W_l Wl是0均值的,所以无论 x l x_l xl均值为多少,均有

E [ y l ] = E [ W l x l ] = 0. E[y_l]=E[W_l x_l]=0. E[yl]=E[Wlxl]=0.

He init 考虑ReLU函数

通过ReLU激活函数: x l = m a x ( 0 , y l − 1 ) x_l=max(0,y_{l−1}) xl=max(0,yl1),仅正半轴有值,我们假设激活之前的值正负各一半,总体是对称的,可以得到:
E [ x l 2 ] = 1 2 V a r [ y l − 1 ] . E[x_l^2] = \frac{1}{2} Var[y_{l-1}]. E[xl2]=21Var[yl1].

因此(如果本文从上面看下来的话,看到这个公式就很熟悉了):
V a r [ y l ] = 1 2 n l V a r [ W l ] V a r [ y l − 1 ] . Var[y_l] = \frac{1}{2} n_l Var[W_l]Var[y_{l-1}]. Var[yl]=21nlVar[Wl]Var[yl1].

我们希望每一层的激活前值(卷积的结果,没有过激活函数)的方差一致, V a r [ y l ] = V a r [ y l − 1 ] Var[y_l]=Var[y_{l-1}] Var[yl]=Var[yl1],这个是和Xavier不一样的地方,这样就可以不考虑激活函数了。那么:

1 2 n l V a r [ W l ] = 1. \frac{1}{2} n_lVar[W_l] =1. 21nlVar[Wl]=1.

  • 如果是用高斯分布采样, W ∼ N ( 0 , 2 n l ) W \sim N(0,\frac{2}{n_l}) WN(0,nl2)

  • 如果是用均匀分布,那么: W ∼ U [ − 6 / n l , 6 / n l ] W \sim U[-\sqrt{6/n_l},\sqrt{6/n_l}] WU[6/nl ,6/nl ]

He init 考虑Leaky ReLU函数

Leaky ReLU激活函数和导函数分别为
在这里插入图片描述
所以:
E [ x l 2 ] = 1 2 ( 1 + α 2 ) V a r [ y l ] . E[x_l^2] = \frac{1}{2}(1+\alpha^2) Var[y_l]. E[xl2]=21(1+α2)Var[yl].

类似上面的推导,可以得到,

1 2 ( 1 + α 2 ) n l V a r [ W l ] = 1. \frac{1}{2}(1+\alpha^2) n_lVar[W_l] =1. 21(1+α2)nlVar[Wl]=1.

  • 如果是用高斯分布采样, W ∼ N ( 0 , 2 ( 1 + α 2 ) n l ) W \sim N(0,\frac{2}{(1+\alpha^2) n_l}) WN(0,(1+α2)nl2)

  • 如果是用均匀分布,那么: W ∼ U [ − 6 / ( 1 + α 2 ) n l , 6 / ( 1 + α 2 ) n l ] W \sim U[-\sqrt{6/(1+\alpha^2) n_l},\sqrt{6/(1+\alpha^2) n_l}] WU[6/(1+α2)nl ,6/(1+α2)nl ]

结束语

好了,到这里本篇就讲完了,介绍了Xavier与He intit的初始化方法,是非常常见的方法。后来还有很多工作来优化初始化,比如进一步考虑resnet网络结构时,有文章引入了Mean field,还有fixup initialization等方法。这些以后有机会再写了。最后说一句BN,因为可以强制要求每一层的数据符合0均值1方差,所以效果上和本文讨论的方法效果很类似。使得前向的数据会相对稳定。但是BN似乎并没有考虑反向梯度的稳定性,这一点目前更多是让resnet中的identity跳边来完成的,有这个identity跳边情况下,梯度至少在在跳边这一路上,可以identity透传,梯度就不容易消失。但是似乎梯度爆炸没有避免,什么情况下会爆炸呢?回看我们前面的分析,比如Xavier中,我们要求 n i + 1 V a r [ W i ] = 1 \quad n_{i+1} Var[W^i] = 1 ni+1Var[Wi]=1,反向就会稳定,如果>1,那么很显然,只要层数深,梯度就指数爆炸了,这样训练也会很难训。因此训练过程中的数据和梯度的稳定性是很重要的。

参考资料

[1] Understanding the difficulty of training deep feedforward neural networks
[2] Delving Deep into Rectifiers: Surpassing Human-Level Performance on ImageNet Classification
[3] https://blog.csdn.net/happynear/article/details/45440811
[4] https://blog.csdn.net/kangroger/article/details/61414426
[5] https://blog.csdn.net/qq_34784753/article/details/78668884
[6] https://blog.csdn.net/dss_dssssd/article/details/83959474
[7] https://blog.csdn.net/weixin_34221773/article/details/86085462
[8] https://www.cnblogs.com/itmorn/p/11132494.html#ct5

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/xbinworld/article/details/107890916

智能推荐

aiXcoder插件安装使用_aixcoder-0.1.12-comm-程序员宅基地

文章浏览阅读713次。https://aixcoder.com/#/localServer法1:将解压缩后「server」目录下的所有文件,手动移动到 C:\Users\24390\aiXcoder\installer\localserver2\current\server下(24390是我的用户文件夹名)法2:直接运行install_localserver.bat文件..._aixcoder-0.1.12-comm

【可供参考】tmux配置文件_# switch panes using alt-arrow without prefix-程序员宅基地

文章浏览阅读317次。# 0 is too far from ` ;)set -g base-index 1# Automatically set window title#set-window-option -g automatic-rename on#set-option -g set-titles on# Send prefixset-option -g prefix C-a unbind-k..._# switch panes using alt-arrow without prefix

PowerDesigner 连接oracle直接生成数据库表的方法_powerdesigner生成oracle表-程序员宅基地

文章浏览阅读586次。创建于 2012-05-08迁移自个人的百度空间--------------------------------首先机子要装有oracle驱动程序(在装oracle服务器端或客户端就自动安装上的oracle的驱动程序) 然后依据下面步骤:1、database->generate database 2、general->Direct generation 如果没有..._powerdesigner生成oracle表

学习JAVA容器之Collections工具类_java 容器工具类-程序员宅基地

文章浏览阅读167次。Collections是一个可以操作set map list的工具类常用方法:T 19:57:25●排序操作: (均为static方 法)➢reverse(List):反转List中元素的顺序➢shuffle(List):对List集合元素进行随机排序➢sort(List):根据元素的自然顺序对指定List 集合元素按升序排序➢sort(List,Comparator): 根据指定..._java 容器工具类

让你提前认识软件开发(47):同行评审_代码同级评审-程序员宅基地

文章浏览阅读3.5k次,点赞5次,收藏4次。第3部分 软件研发工作总结同行评审 在《浪潮之巅》这本书中,吴军老师描述了在Google早期的工作方式,其中有一段是这么写的:我一般会在吃完晚饭后把代码修改的清单发给克雷格做代码审核,他一般晚上10点左右会回复我,给我修改意见,详细到某一行多了一个空格。 吴军老师所描述的内容,其实就是软件开发中的同行评审流程。 几乎在所有的软件项目中,都需要同行评审。_代码同级评审

Vue性能优化_vue 应用性能优化指南-程序员宅基地

文章浏览阅读3.1k次。前言一般来说,你不需要太关心vue的运行时性能,它在运行时非常快,但付出的代价是初始化时相对较慢。在最近开发的一个Hybrid APP里,Android Webview初始化一个较重的vue页面竟然用了1200ms ~ 1400ms,这让我开始重视vue的初始化性能,并最终优化到200 ~ 300ms,这篇文章分享我的优化思路。性能瓶颈在哪里?先看一下常见的vue写法:在html里放一..._vue 应用性能优化指南

随便推点

Linux—nmap、nc命令 –网络探测工具和安全和端口扫描器_nmap 和 nc-程序员宅基地

文章浏览阅读2k次,点赞4次,收藏6次。文章目录nmap命令语法格式:常用参数:参考实例:nc命令语法格式:常用参数:参考实例:nmap命令nmap (“Network Mapper(网络映射器)”) 是一款开放源代码的 网络探测和安全审核的工具。它的设计目标是快速地扫描大型网络,当然用它扫描单个 主机也没有问题。Nmap以新颖的方式使用原始IP报文来发现网络上有哪些主机,那些主机提供什么服务(应用程序名和版本),那些服务运行在什么操作系统(包括版本信息), 它们使用什么类型的报文过滤器/防火墙,以及一堆其它功能。虽然Nmap通常用于安全审核_nmap 和 nc

发票查验API-票据管理自动化_发票查验api是免费的吗-程序员宅基地

文章浏览阅读346次。现如今,随着经济的不断发展,社会的不断进步,企业模式的不断转型,越来越多的业务需要发票进行报销,也正是随着发票的普及,越来越多的假发票混入我们的生活,一些不法分子以此为商机,制售假发票为他人报销提供非正常途径。为防止假发票、问题发票入账,企业要求财务工作者在接收到发票时必须做到“先查验、后报销、再入账”,但如此一来,企业产生的海量发票无疑增加了财务人员的工作量。对于发票查验量小的企业而言,可以通过上税务局官网的方式一张一张免费进行查询,但对于发票查验需求量大的企业而言,传统人工查验的方式不仅速度慢、效率低_发票查验api是免费的吗

win7下安装oracle时,提示程序异常终止,发生未知错误_error in process: e:\oracle\product\19.3.0.0\db_1\-程序员宅基地

文章浏览阅读4.5k次。1、修改oracle安装包内refhost.xml文件2、修改oracle安装包内oraparam.in文件3、以兼容模式运行这个程序,并选择 windows xp(service pack 3)4、以管理员身份运行_error in process: e:\oracle\product\19.3.0.0\db_1\bin\orapwd.exe

Disruptor框架详解-程序员宅基地

文章浏览阅读5.7k次。1.x disruptor框架介绍与Hello World2.x disruptor 详细说明与使用3.x disruptor 应用(并发场景实例讲解)1.1 Disruptor并发框架简介Martin Fowler在自己网站上写了一篇LMAX架构的文章,在文章中他介绍了LMAX是一种新型零售金融交易平台,它能够以很低的延迟产生大量交易。这个系统是建立在JVM平台上,其核心是一个业..._disruptor

星速配资:高毅资产持股量位居首位-程序员宅基地

文章浏览阅读122次。高毅资产在二季度仍是当之无愧的“持有王”,不仅延续一季度对海康威视、紫光国微、紫金矿业和睿创微纳的青睐,还新进了天山铝业、恒立液压、华润三九、久立特材和西部超导等5只个股。据数据显示,二季度高毅资产持有24只个股,合计持有市值为374.42亿元,其中,持有的海康威视市值就高达138.68亿元;其次,持有的紫金矿业市值达68.35亿元;从持股量或持有市值来看,高毅资产均居首位。同时,玄元投资和迎水投资也在同期持有不少个股。玄元投资二季度持有三棵树、中泰化学、伊之密、聚隆科技和沃尔核材等17只个股,合计

1、在不配置CATALINA_HOME环境变量的情况下启动tomcat-程序员宅基地

文章浏览阅读594次。场景:tomcat执行startup.bat的时候,会寻找全局环境变量CATALINA_HOME,如果CATALINA_HOME对应的tomcat目录不是当前tomcat的目录,则就会启动报错,解决方法如下:1、打开bin目录下的startup.bat文件,添加如下代码:这样的话,当前tomcat启动时,就会使用当前的tomcat,而不会去使用环境变量CATALINA_HOM..._linux 启动tomcat 不使用系统变量catalina_home