《Deep Learning》学习笔记一: BN的理解。

来源:互联网 发布:电脑软件开发学校 编辑:程序博客网 时间:2024/06/06 01:57

先给出大牛的链接:

知乎:https://www.zhihu.com/question/38102762

BN本质上解决的是反向传播过程中的梯度问题。

详细点说,反向传播时经过该层的梯度是要乘以该层的参数的,即前向有:

h_l = w_l^Th_{l-1}

那么反向传播时便有:

\frac{\partial l}{\partial h_{l-1}} = \frac{\partial l}{\partial h_l} . \frac{\partial h_l}{\partial h_{l-1}} = \frac{\partial l}{\partial h_l} w_l

那么考虑从l层传到k层的情况,有:

\frac{\partial l}{\partial h_k} = \frac{\partial l}{\partial h_l} \prod _{i=k+1}^{l} w_i

上面这个 \prod_{i=k+1}^l w_i 便是问题所在。因为网络层很深,如果w_i 大多小于1,那么传到这里的时候梯度会变得很小比如0.9^{100} ;而如果w_i 又大多大于1,那么传到这里的时候又会有梯度爆炸问题 比如1.1^{100}。BN所做的就是解决这个梯度传播的问题,因为BN作用抹去了w的scale影响。

具体有:

h_l=BN(w_lh_{l-1}) =BN(\alpha w_lh_{l-1})

那么反向求导时便有了:

\frac{\partial h_l}{\partial h_{l-1}}=\frac{\partial BN w_lh_{l-1}}{\partial h_{l-1}} =\frac{\partial BN \alpha w_lh_{l-1}}{\partial h_{l-1}}

可以看到此时反向传播乘以的数不再和 w 的尺度相关,也就是说尽管我们在更新过程中改变了w 的值,但是反向传播的梯度却不受影响。更进一步:

\frac{\partial h_l}{\partial w_l} = \frac{\partial BNw_lh_{l-1}}{\partial w_l} = \frac{1}{\alpha}.\frac{\partial BN \alpha w_l h_{l-1}}{\partial w_l}

即尺度较大的 w 将获得一个较小的梯度,在同等的学习速率下其获得的更新更少,这样使得整体w 的更新更加稳健起来。



作者:Jiangqh
链接:https://www.zhihu.com/question/38102762/answer/164790133
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。


另一位大牛的讲解:
http://jiangqh.info/Batch-Normalization%E8%AF%A6%E8%A7%A3/

Batch Normalization详解

By jiangqh on May.02-2017

Batch Normalization广为人知应该是在15年,当时微软亚研院的何恺明提出ResNet在各项视觉比赛中获得冠军并得到了当年的Cvpr best paper。ResNet除了使用跳过式连接还大量使用了Bath Normalization,网络大获成功的同时也证明了BN在深度神经网络训练中的巨大威力。

本文尝试从原理到推导详细的梳理Batch Normalization。下文中为了方便将Batch Normalization简称为BN。

什么是BN?

什么是BN呢?如名字所示,BN所做十分简单,即将某一层输出归一化,使得其均值为0方差为1。值得注意的是BN是在channel维度做的,即将每个channel都进行归一化,如果有n个channel那么便会有n个归一化操作。具体来说如果某个层的输出为x=(x0,x1,xn)x=(x0,x1,…xn),那么BN做的便是:

xk=xkE[xk]Var[xk]xk=xk−E[xk]Var[xk]

而在卷积神经网络中我们有C×H×WC×H×W的输出,遵照卷积层的特性BN在每个H×WH×W上做归一化,也就是做CC个归一化操作。




怎么做BN

说完了为什么我们来看看具体怎么做。根据定义,我们只需要对每个channel求解其均值和方差,然后进行操作即可。假设某个batch内共有m个数据,那么对某一个channel有:

u=1mi=1mxiu=1m∑i=1mxi
var=1mi=1m(xiu)2var=1m∑i=1m(xi−u)2
xi^=xiuvar+ϵxi^=xi−uvar+ϵ
yi=γxi^+βyi=γxi^+β

在上式中前两项为求取均值和方差,第三项分布中ϵϵ是为了防止数值问题而加的一个小数,比如10610−6。最后一项中γγββ是可以学习的参数,通过这两个参数我们使BN保持了更强的学习能力可以自己的分布,那么我们为什么在进行了归一化操作后还要加上这两个参数呢?这是因为加上这两个参数后现在的分布族便包含了原来BN前的分布,但是原来的分布方差和均值由下面层的各种参数weight耦合控制,而现在仅由γγββ控制,这样在保留BN层足够的学习能力的同时,我们使得其学习更加容易。

利用链式求导法则我们有:

lγ=i=1mlyixi^∂l∂γ=∑i=1m∂l∂yixi^
lβ=i=1mlyi∂l∂β=∑i=1m∂l∂yi
lxi^=lyiγ∂l∂xi^=∂l∂yiγ
lvar=i=1mlxi^xi^var=i=1mlyiγ(xiu)12(var+ϵ)32∂l∂var=∑i=1m∂lxi^xi^∂var=∑i=1m∂l∂yiγ(xi−u)−12(var+ϵ)−32
lu=(i=1mlxi^1var+ϵ)+lvarmi=12(xiu)m∂l∂u=(∑i=1m∂l∂xi^−1var+ϵ)+∂l∂var∑i=1m−2(xi−u)m
lxi=lxi^1var+ϵ+lvar2(xiu)m+lu1m∂lxi=∂lxi^1var+ϵ+∂l∂var2(xi−u)m+∂l∂u1m

至此我们完整的梳理了BN的由来和它解决的问题以及详细推导过程,具体实现可以参考caffe或者TensorFlow里相应的代码。值得注意的是在做test的时候为了对一个sample也可以用BN,此时的u,varu,var往往采用做training时候的一个统计平均,同时方差采样的是无差的平均统计,即做test时有:

utest=E[u]utest=E[u]
vartest=mm1E[var]vartest=mm−1E[var]

同时注意在卷积层做BN时也是按照channel来的,即进行channel个BN操作。





原创粉丝点击