Batch Normalization笔记
Batch Normalization的来源
简化版的Convolutional Layer
X
(
l
+
1
)
=
f
(
Y
l
)
=
f
(
3
d
_
c
o
n
v
(
X
l
,
F
)
+
b
)
X^{(l+1)}=f(Y^l)=f(3d\_conv(X^l,F)+b)
X(l+1)=f(Yl)=f(3d_conv(Xl,F)+b)
f
f
f 是激活函数,一般是
L
e
a
k
y
Leaky
Leaky或者
R
e
L
U
ReLU
ReLU,早年比较火的
s
i
g
m
o
i
d
(
x
)
=
1
/
(
1
−
e
−
x
)
sigmoid(x)=1/(1 - e^{-x})
sigmoid(x)=1/(1−e−x)函数因为计算量大(要计算
e
−
x
e^{-x}
e−x),效果不好(容易出现梯度消失)已经基本不用。
但对于
y
=
s
i
g
m
o
i
d
(
x
)
y=sigmoid(x)
y=sigmoid(x) ,
y
y
y 的均值为0,如果不考虑计算量,将来可以研究研究。
为了保持书写习惯,下文用
W
W
W 表示卷积核。
下面分析中假设卷积核数量为1, X l X^l Xl的深度为1,3d卷积 3 d _ c o n v 3d\_conv 3d_conv 换成 2d卷积 c o n v 2 conv2 conv2。
梯度消失的问题
在神经网络很深的情况下,数据向前传播的时候经常容易进入饱和区(不过感觉用 L e a k y Leaky Leaky 或者 R e L U ReLU ReLU 作为激活函数这个问题不大),对数据进行规范化,使其满足(至少看起来满足)高斯分布,可以避免进入饱和区而出现梯度消失的问题。
相关文章:
详解深度学习中的Normalization,BN/LN/WN
什么是批标准化 (Batch Normalization)
Batch Normalization阅读笔记
Normalization的变体
最基本的数据规范化
对输入进行规范化。若
X
X
X 是
N
×
N
N×N
N×N 的矩阵。
μ
=
1
N
2
∑
i
=
0
N
−
1
∑
j
=
0
N
−
1
x
i
,
j
\mu = \frac{1}{N^2}\sum_{i=0}^{N-1}\sum_{j=0}^{N-1}x_{i,j}
μ=N21i=0∑N−1j=0∑N−1xi,j
σ 2 = 1 N 2 ∑ i = 0 N − 1 ∑ j = 0 N − 1 ( x i , j − μ ) 2 \quad\quad\sigma^2= \frac{1}{N^2}\sum_{i=0}^{N-1}\sum_{j=0}^{N-1}(x_{i,j}-\mu)^2 σ2=N21i=0∑N−1j=0∑N−1(xi,j−μ)2
σ = σ 2 = 1 N ∑ i = 0 N − 1 ∑ j = 0 N − 1 ( x i , j − μ ) 2 \quad\quad\quad\quad\quad\quad\sigma=\sqrt {\sigma^2}= \frac{1}{N}\sqrt {\sum_{i=0}^{N-1}\sum_{j=0}^{N-1}(x_{i,j}-\mu)^2} σ=σ2=N1i=0∑N−1j=0∑N−1(xi,j−μ)2
X ^ = { X − μ σ σ ≠ 0 X σ = 0 \hat{X}=\begin{cases}\frac{X-\mu}{\sigma} \quad\sigma\neq0\\X\quad\quad\sigma=0\end{cases}\quad X^={σX−μσ̸=0Xσ=0
批规范化
一小批(Batch)的数据平均化的规范化。吸取了mini batch-SGD的思路,为的应该是增加数据的样本空间,记Batch数为
m
m
m,Batch Normalization的均值为
μ
′
\mu'
μ′
μ
‾
=
1
m
∑
i
∈
m
μ
i
,
σ
‾
=
1
m
∑
i
∈
m
σ
i
\overline \mu=\frac{1}{m}\sum_{i\in m}\mu_i,\quad\quad\overline \sigma=\frac{1}{m}\sum_{i\in m}\sigma_i
μ=m1i∈m∑μi,σ=m1i∈m∑σi
X
^
=
{
X
−
μ
‾
σ
‾
σ
‾
≠
0
X
σ
‾
=
0
\hat{X}=\begin{cases}\frac{X-\overline\mu}{\overline\sigma} \quad\overline\sigma\neq0\\X\quad\quad\overline\sigma=0\end{cases}\quad
X^={σX−μσ̸=0Xσ=0
问题来了,如果 σ ‾ = 0 \overline\sigma=0 σ=0,那说明全部的数据都是 μ ‾ = 0 \overline\mu=0 μ=0,这样的数据我们训练它有啥意义?这个且排除掉,得到
X ^ = X − μ ‾ σ ‾ \hat X=\frac{X-\overline\mu}{\overline \sigma} X^=σX−μ
有论文说 m m m 应该取32。64,128,256等数也应该试试看。也有论文说 m m m 过大的话效果可能会较差。
在Yolo中,默认的输入尺寸是416×416(浮点数),一级中最多有256个3×3的卷积核,一个卷积结果需要的内存存储量为416×416×256÷1024÷1024=42.25MB,如果 m = 32 m=32 m=32, X ^ \hat X X^的内存需求为1352MB≈1.32GB。
但深度网络中,不见得上面计算的
X
^
\hat X
X^ 未必是我们想要的,所以要有机会对其进行修正。
Y
=
γ
X
^
+
β
Y=\gamma \hat X+\beta\quad
Y=γX^+β
初始值
γ
0
=
1
,
β
0
=
0
\gamma_0=1, \beta_0=0
γ0=1,β0=0
加了Batch Normalization的卷积层
Batch Normalization放在哪里
放在卷积之后,激活之前,即从原来的
Y
l
=
c
o
n
v
2
(
X
l
,
W
)
+
b
Y^l=conv2(X^l,W)+b
Yl=conv2(Xl,W)+b
变成
Y
l
=
Y
=
γ
Z
^
l
+
β
=
γ
l
(
c
o
n
v
2
(
X
l
,
W
)
−
μ
‾
l
σ
‾
l
)
+
β
l
Y^l=Y=\gamma \hat Z^l+\beta =\gamma^l \left(\frac {conv2(X^l,W)-\overline\mu^l}{\overline\sigma^l}\right)+\beta^l
Yl=Y=γZ^l+β=γl(σlconv2(Xl,W)−μl)+βl
这里 b b b 被忽略,合并到 β \beta β 里面了。且暂不考虑 σ ‾ = 0 \overline\sigma=0 σ=0 的情况。
增加一个变量 Z l Z^l Zl, Z l = c o n v 2 ( X l , W ) Z^l=conv2(X^l,W) Zl=conv2(Xl,W)。
前向传播算法
为简单考虑,
X
l
X^l
Xl的通道数为1,唯一卷积核为
W
l
W^l
Wl 。卷积层的输出
X
l
+
1
=
f
(
Y
l
)
=
f
(
γ
l
(
c
o
n
v
2
(
X
l
,
W
l
)
−
μ
‾
l
σ
‾
l
)
+
β
l
)
X^{l+1}=f(Y^l)=f\left (\gamma^l \left(\frac {conv2(X^l,W^l)-\overline\mu^l}{\overline\sigma^l}\right)+\beta^l \right )
Xl+1=f(Yl)=f(γl(σlconv2(Xl,Wl)−μl)+βl)
反向传播算法
已知 d X l + 1 dX^{l+1} dXl+1,也就是 X l + 1 X^{l+1} Xl+1的导数,求以下值:
d
X
l
dX^l
dXl ,为了往后面一层继续传播,使
x
i
,
j
←
x
i
,
j
−
η
⋅
d
x
i
,
j
x_{i,j}\gets x_{i,j}-\eta·dx_{i,j}
xi,j←xi,j−η⋅dxi,j
d
W
l
dW^l
dWl ,为了更新本层的卷积参数,使
w
i
,
j
←
w
i
,
j
−
η
⋅
d
w
i
,
j
w_{i,j}\gets w_{i,j}-\eta·dw_{i,j}
wi,j←wi,j−η⋅dwi,j
d
γ
l
d\gamma^l
dγl ,
d
β
l
d\beta^l
dβl 为了更新本层的规范化参数
d X l + 1 dX^{l+1} dXl+1 准确讲应该是 Δ E Δ X l + 1 \frac{\Delta E}{\Delta X^{l+1}} ΔXl+1ΔE , 而 d X l = Δ E Δ X l = Δ E Δ X l + 1 ⋅ Δ X l + 1 Δ X l dX^l=\frac{\Delta E}{\Delta X^l}=\frac{\Delta E}{\Delta X^{l+1}}·\frac{\Delta X^{l+1}}{\Delta X^l} dXl=ΔXlΔE=ΔXl+1ΔE⋅ΔXlΔXl+1
因此, d Y l = d X l + 1 ⋅ f ′ ( Y ) dY^l=dX^{l+1}·f'(Y) dYl=dXl+1⋅f′(Y)。
我们从 d Y l dY^l dYl 开始。
d γ l d\gamma^l dγl 和 d β l d\beta^l dβl 的推导
d γ l = d Y l ⋅ Δ Y l Δ γ l = d Y l ⋅ X ^ l d\gamma^l=dY^l·\frac{\Delta Y^l}{\Delta \gamma^l}=dY^l·\hat X^l dγl=dYl⋅ΔγlΔYl=dYl⋅X^l
在实际系统中, X ^ \hat X X^ , d Y l dY^l dYl 为 N × N N×N N×N 矩阵, γ \gamma γ 和 β \beta β 为浮点数(不是数组也不是矩阵)
后续的更新计算中,也希望有使 γ ← γ − η ⋅ d γ \gamma\gets \gamma-\eta·d\gamma γ←γ−η⋅dγ 的形式。,因此需要有 d γ l d\gamma^l dγl 从 N × N N×N N×N 矩阵到浮点数的转换方式。Understanding the backward pass through Batch Normalization Layer中用的算法是 d γ l = ∑ i ∑ j x ^ i , j l ⋅ d y i , j l d\gamma^l=\sum_i \sum_j \hat x_{i,j}^l·dy^l_{i,j} dγl=∑i∑jx^i,jl⋅dyi,jl ,(和推导过程不同)
类似地, d β l = ∑ i ∑ j d y i , j l d\beta^l=\sum_i \sum_j dy^l_{i,j} dβl=∑i∑jdyi,jl。
d X l dX^l dXl 的推导
显然, ∂ Y l / ∂ Z ^ = γ l \partial Y^l/\partial \hat Z=\gamma^l ∂Yl/∂Z^=γl。
又有
d
X
l
=
d
Y
l
⋅
∂
Y
l
∂
Z
^
l
⋅
∂
Z
^
l
∂
X
l
=
d
Y
l
⋅
γ
l
⋅
∂
Z
^
l
∂
X
l
dX^l=dY^l·\frac{\partial Y^l}{\partial \hat Z^l}·\frac{\partial \hat Z^l}{\partial X^l}=dY^l·\gamma^l·\frac{\partial \hat Z^l}{\partial X^l}
dXl=dYl⋅∂Z^l∂Yl⋅∂Xl∂Z^l=dYl⋅γl⋅∂Xl∂Z^l
变成了计算 ∂ Z ^ l / ∂ X l \partial \hat Z^l / \partial X^l ∂Z^l/∂Xl 的问题了,先计算 ∂ Z ^ l / ∂ Z l \partial \hat Z^l / \partial Z^l ∂Z^l/∂Zl 。
Z ^ = Z − μ ‾ σ ‾ \hat Z=\frac{Z-\overline\mu}{\overline \sigma} Z^=σZ−μ
对于Batch Normalizaiton ,
μ ‾ = 1 m ∑ i ∈ m 1 N 2 ∑ j ∈ N ∑ k ∈ N z j , k ( i ) \overline\mu=\frac{1}{m}\sum_{i \in m}\frac{1}{N^2}\sum_{j \in N}\sum_{k \in N} z_{j,k}^{(i)} μ=m1i∈m∑N21j∈N∑k∈N∑zj,k(i)
σ
‾
=
1
m
∑
i
∈
m
1
N
∑
j
∈
N
∑
k
∈
N
(
z
j
,
k
(
i
)
−
μ
‾
)
2
\overline\sigma=\frac{1}{m}\sum_{i \in m}\frac{1}{N}\sum_{j \in N}\sum_{k \in N} \sqrt{ \left( z_{j,k}^{(i)}-\overline\mu \right)^2}
σ=m1i∈m∑N1j∈N∑k∈N∑(zj,k(i)−μ)2
即
σ
‾
=
1
m
∑
i
∈
m
1
N
∑
j
∈
N
∑
k
∈
N
∣
z
j
,
k
(
i
)
−
μ
‾
∣
\overline\sigma=\frac{1}{m}\sum_{i \in m}\frac{1}{N}\sum_{j \in N}\sum_{k \in N} \left| z_{j,k}^{(i)}-\overline\mu \right|
σ=m1i∈m∑N1j∈N∑k∈N∑∣∣∣zj,k(i)−μ∣∣∣
Z Z Z 的变化会引起 μ ‾ \overline \mu μ 和 σ ‾ \overline \sigma σ 变化,我们需要计算 μ ‾ \overline \mu μ 和 σ ‾ \overline \sigma σ 的导数值。但目前的这个 σ ‾ \overline \sigma σ 是有绝对值号的,不可导。给它做一点小小的处理:
σ ‾ = 1 m ∑ i ∈ m 1 N ∑ j ∈ N ∑ k ∈ N ( z j , k ( i ) − μ ‾ ) 2 + ϵ \overline\sigma=\frac{1}{m}\sum_{i \in m}\frac{1}{N}\sum_{j \in N}\sum_{k \in N} \sqrt{ \left( z_{j,k}^{(i)}-\overline\mu \right)^2+\epsilon } σ=m1i∈m∑N1j∈N∑k∈N∑(zj,k(i)−μ)2+ϵ
ϵ \epsilon ϵ 是一个很小的常数,通常取值1.0e-8可以,这样 σ ‾ \overline\sigma σ 的值基本不会改变,但可导了。
∂ Z ^ ∂ σ ‾ = 1 σ ‾ 2 , ∂ Z ^ ∂ μ ‾ ∗ = − 1 σ ‾ \frac{\partial \hat Z}{\partial \overline \sigma}=\frac{1}{\overline \sigma^2}, \quad\quad\frac{\partial \hat Z}{\partial \overline \mu}^*=-\frac{1}{\overline \sigma} ∂σ∂Z^=σ21,∂μ∂Z^∗=−σ1
接着求 ∂ σ ‾ / ∂ Z \partial\overline \sigma/\partial Z ∂σ/∂Z 和 ∂ μ ‾ / ∂ Z \partial\overline \mu/\partial Z ∂μ/∂Z
考虑到Batch Normalizaiton中一个batch中的训练样本相互独立,因此
∂
μ
‾
∂
z
i
,
j
=
1
m
⋅
N
2
\frac{\partial \overline\mu}{\partial z_{i,j}}=\frac{1}{m·N^2}
∂zi,j∂μ=m⋅N21
记
t
i
,
j
=
z
i
,
j
−
μ
t_{i,j}=z_{i,j}-\mu
ti,j=zi,j−μ ,
σ
‾
(
t
i
,
j
)
=
t
i
,
j
2
+
ϵ
m
⋅
N
\overline\sigma(t_{i,j})=\frac{\sqrt{t_{i,j}^2+\epsilon}}{m·N}
σ(ti,j)=m⋅Nti,j2+ϵ ,
σ
‾
′
(
t
i
,
j
)
=
t
i
,
j
m
⋅
N
⋅
t
i
,
j
2
+
ϵ
≈
z
i
,
j
−
μ
m
⋅
N
⋅
σ
‾
\overline\sigma'(t_{i,j})=\frac{t_{i,j}}{m·N·\sqrt{t_{i,j}^2+\epsilon}}\approx \frac{z_{i,j}-\mu}{m·N·\overline\sigma}
σ′(ti,j)=m⋅N⋅ti,j2+ϵti,j≈m⋅N⋅σzi,j−μ
因此,
∂
σ
‾
∂
Z
=
1
m
⋅
N
⋅
σ
‾
⋅
R
N
×
N
\frac{\partial \overline \sigma}{\partial Z}=\frac{1}{m·N·\overline\sigma}·R_{N×N}
∂Z∂σ=m⋅N⋅σ1⋅RN×N
∂
σ
‾
∂
μ
‾
=
−
1
m
⋅
N
⋅
σ
‾
⋅
R
N
×
N
\frac{\partial \overline \sigma}{\partial \overline \mu}=\frac{-1}{m·N·\overline\sigma}·R_{N×N}
∂μ∂σ=m⋅N⋅σ−1⋅RN×N
∂
Z
^
∂
Z
=
∂
Z
^
∂
Z
∗
+
∂
Z
^
∂
σ
‾
⋅
∂
σ
‾
∂
Z
+
∂
Z
^
∂
σ
‾
⋅
∂
σ
‾
∂
μ
‾
⋅
∂
μ
‾
∂
Z
+
∂
Z
^
∂
μ
‾
∗
⋅
∂
μ
‾
∂
Z
=
1
σ
‾
+
1
σ
‾
2
⋅
1
m
⋅
N
⋅
σ
‾
+
1
σ
‾
2
⋅
(
−
1
m
⋅
N
⋅
σ
‾
)
⋅
1
m
⋅
N
2
+
(
−
1
σ
‾
)
⋅
1
m
⋅
N
2
=
1
σ
‾
⋅
R
N
×
N
+
1
m
⋅
N
⋅
σ
‾
⋅
(
1
σ
‾
2
−
1
m
⋅
N
2
σ
‾
2
−
1
N
)
⋅
R
N
×
N
\frac{\partial \hat Z}{\partial Z}=\frac{\partial \hat Z}{\partial Z}^*+\frac{\partial \hat Z}{\partial \overline \sigma}·\frac{\partial \overline \sigma}{\partial Z}+\frac{\partial \hat Z}{\partial \overline \sigma}·\frac{\partial \overline \sigma}{\partial \overline \mu}·\frac{\partial \overline \mu}{\partial Z}+\frac{\partial \hat Z}{\partial \overline \mu}^*·\frac{\partial \overline \mu}{\partial Z}\\=\frac{1}{\overline\sigma}+\frac{1}{\overline\sigma^2}·\frac{1}{m·N·\overline\sigma}+\frac{1}{\overline\sigma^2}·\left(\frac{-1}{m·N·\overline\sigma}\right)·\frac{1}{m·N^2}+\left(-\frac{1}{\overline \sigma}\right)·\frac{1}{m·N^2}\\=\frac{1}{\overline\sigma}·R_{N×N}+\frac{1}{m·N·\overline\sigma}·\left(\frac{1}{\overline\sigma^2}-\frac{1}{m·N^2\overline\sigma^2}-\frac{1}{N}\right)·R_{N×N}
∂Z∂Z^=∂Z∂Z^∗+∂σ∂Z^⋅∂Z∂σ+∂σ∂Z^⋅∂μ∂σ⋅∂Z∂μ+∂μ∂Z^∗⋅∂Z∂μ=σ1+σ21⋅m⋅N⋅σ1+σ21⋅(m⋅N⋅σ−1)⋅m⋅N21+(−σ1)⋅m⋅N21=σ1⋅RN×N+m⋅N⋅σ1⋅(σ21−m⋅N2σ21−N1)⋅RN×N
R N × N R_{N×N} RN×N 是元素全为1的 N × N N×N N×N矩阵。
在Yolo中, N N N 通常为416以上的值, σ ‾ \overline\sigma σ接近0.1的倍数,当 m m m 取32时,式子的第二项和第一项相比几乎可以忽略不计。因此,我认为 ∂ Z ^ / ∂ Z = 1 / σ ‾ ⋅ R N × N \partial \hat Z/\partial Z=1/\overline\sigma·R_{N×N} ∂Z^/∂Z=1/σ⋅RN×N即可。减少很多计算量。
中间的推导可能有错误,不过不影响最终的结论。
卷积部分的计算
见我之前写的文章 卷积神经网络CNN的前向和后向传播(二)
其他
Batch Normalization部分,借一张图,来自Understanding the backward pass through Batch Normalization Layer