先给出大牛的链接:
知乎:https://www.zhihu.com/question/38102762
BN本质上解决的是反向传播过程中的梯度问题。
详细点说,反向传播时经过该层的梯度是要乘以该层的参数的,即前向有:
那么反向传播时便有:
那么考虑从l层传到k层的情况,有:
上面这个 便是问题所在。因为网络层很深,如果
大多小于1,那么传到这里的时候梯度会变得很小比如
;而如果
又大多大于1,那么传到这里的时候又会有梯度爆炸问题 比如
。BN所做的就是解决这个梯度传播的问题,因为BN作用抹去了w的scale影响。
具体有:
(
) =
(
)
那么反向求导时便有了:
可以看到此时反向传播乘以的数不再和 的尺度相关,也就是说尽管我们在更新过程中改变了
的值,但是反向传播的梯度却不受影响。更进一步:
即尺度较大的 将获得一个较小的梯度,在同等的学习速率下其获得的更新更少,这样使得整体
的更新更加稳健起来。
作者: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=xk−E[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=1m∑i=1mxiu=1m∑i=1mxi
var=1m∑i=1m(xi−u)2var=1m∑i=1m(xi−u)2
xi^=xi−uvar+ϵ‾‾‾‾‾‾‾√xi^=xi−uvar+ϵ
yi=γxi^+βyi=γxi^+β
在上式中前两项为求取均值和方差,第三项分布中ϵϵ是为了防止数值问题而加的一个小数,比如10−610−6。最后一项中γγ和ββ是可以学习的参数,通过这两个参数我们使BN保持了更强的学习能力可以自己的分布,那么我们为什么在进行了归一化操作后还要加上这两个参数呢?这是因为加上这两个参数后现在的分布族便包含了原来BN前的分布,但是原来的分布方差和均值由下面层的各种参数weight耦合控制,而现在仅由γγ和ββ控制,这样在保留BN层足够的学习能力的同时,我们使得其学习更加容易。
利用链式求导法则我们有:
∂l∂γ=∑i=1m∂l∂yixi^∂l∂γ=∑i=1m∂l∂yixi^
∂l∂β=∑i=1m∂l∂yi∂l∂β=∑i=1m∂l∂yi
∂l∂xi^=∂l∂yiγ∂l∂xi^=∂l∂yiγ
∂l∂var=∑i=1m∂lxi^xi^∂var=∑i=1m∂l∂yiγ(xi−u)−12(var+ϵ)−32∂l∂var=∑i=1m∂lxi^xi^∂var=∑i=1m∂l∂yiγ(xi−u)−12(var+ϵ)−32
∂l∂u=(∑i=1m∂l∂xi^−1var+ϵ‾‾‾‾‾‾‾√)+∂l∂var∑mi=1−2(xi−u)m∂l∂u=(∑i=1m∂l∂xi^−1var+ϵ)+∂l∂var∑i=1m−2(xi−u)m
∂lxi=∂lxi^1var+ϵ‾‾‾‾‾‾‾√+∂l∂var2(xi−u)m+∂l∂u1m∂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=mm−1E[var]vartest=mm−1E[var]
同时注意在卷积层做BN时也是按照channel来的,即进行channel个BN操作。