有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)
f f 是激活函数,一般是 L e a k y Leaky 或者 R e L U ReLU ,早年比较火的 s i g m o i d ( x ) = 1 / ( 1 e x ) sigmoid(x)=1/(1 - e^{-x}) 函数因为计算量大(要计算 e x e^{-x} ),效果不好(容易出现梯度消失)已经基本不用。

但对于 y = s i g m o i d ( x ) y=sigmoid(x) y y 的均值为0,如果不考虑计算量,将来可以研究研究。
为了保持书写习惯,下文用 W W 表示卷积核。

下面分析中假设卷积核数量为1, X l X^l 的深度为1,3d卷积 3 d _ c o n v 3d\_conv 换成 2d卷积 c o n v 2 conv2

梯度消失的问题

在神经网络很深的情况下,数据向前传播的时候经常容易进入饱和区(不过感觉用 L e a k y Leaky 或者 R e L U ReLU 作为激活函数这个问题不大),对数据进行规范化,使其满足(至少看起来满足)高斯分布,可以避免进入饱和区而出现梯度消失的问题。

相关文章:
详解深度学习中的Normalization,BN/LN/WN
什么是批标准化 (Batch Normalization)
Batch Normalization阅读笔记

Normalization的变体

最基本的数据规范化

对输入进行规范化。若 X X 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}

σ 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 = 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}

X ^ = { X μ σ σ 0 X σ = 0 \hat{X}=\begin{cases}\frac{X-\mu}{\sigma} \quad\sigma\neq0\\X\quad\quad\sigma=0\end{cases}\quad

批规范化

一小批(Batch)的数据平均化的规范化。吸取了mini batch-SGD的思路,为的应该是增加数据的样本空间,记Batch数为 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
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

问题来了,如果 σ = 0 \overline\sigma=0 ,那说明全部的数据都是 μ = 0 \overline\mu=0 ,这样的数据我们训练它有啥意义?这个且排除掉,得到

X ^ = X μ σ \hat X=\frac{X-\overline\mu}{\overline \sigma}

有论文说 m m 应该取32。64,128,256等数也应该试试看。也有论文说 m m 过大的话效果可能会较差。

在Yolo中,默认的输入尺寸是416×416(浮点数),一级中最多有256个3×3的卷积核,一个卷积结果需要的内存存储量为416×416×256÷1024÷1024=42.25MB,如果 m = 32 m=32 X ^ \hat X 的内存需求为1352MB≈1.32GB。

但深度网络中,不见得上面计算的 X ^ \hat X 未必是我们想要的,所以要有机会对其进行修正。
Y = γ X ^ + β Y=\gamma \hat X+\beta\quad
初始值 γ 0 = 1 , β 0 = 0 \gamma_0=1, \beta_0=0

加了Batch Normalization的卷积层

Batch Normalization放在哪里

放在卷积之后,激活之前,即从原来的
Y l = c o n v 2 ( X l , W ) + b Y^l=conv2(X^l,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

这里 b b 被忽略,合并到 β \beta 里面了。且暂不考虑 σ = 0 \overline\sigma=0 的情况。

增加一个变量 Z l Z^l Z l = c o n v 2 ( X l , W ) Z^l=conv2(X^l,W)

前向传播算法

为简单考虑, X l X^l 的通道数为1,唯一卷积核为 W l W^l 。卷积层的输出
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 )

反向传播算法

已知 d X l + 1 dX^{l+1} ,也就是 X l + 1 X^{l+1} 的导数,求以下值:

d X l dX^l ,为了往后面一层继续传播,使 x i , j x i , j η d x i , j x_{i,j}\gets x_{i,j}-\eta·dx_{i,j}
d W l dW^l ,为了更新本层的卷积参数,使 w i , j w i , j η d w i , j w_{i,j}\gets w_{i,j}-\eta·dw_{i,j}
d γ l d\gamma^l d β l d\beta^l 为了更新本层的规范化参数

d X l + 1 dX^{l+1} 准确讲应该是 Δ E Δ X l + 1 \frac{\Delta E}{\Delta X^{l+1}} , 而 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}

因此, d Y l = d X l + 1 f ( Y ) dY^l=dX^{l+1}·f'(Y)

我们从 d Y l dY^l 开始。

d γ l d\gamma^l d β l d\beta^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

在实际系统中, X ^ \hat X , d Y l dY^l N × N N×N 矩阵, γ \gamma β \beta 为浮点数(不是数组也不是矩阵)

后续的更新计算中,也希望有使 γ γ η d γ \gamma\gets \gamma-\eta·d\gamma 的形式。,因此需要有 d γ l d\gamma^l 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 j d y i , j l d\beta^l=\sum_i \sum_j dy^l_{i,j}

d X l dX^l 的推导

显然, Y l / Z ^ = γ l \partial Y^l/\partial \hat Z=\gamma^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}

变成了计算 Z ^ l / X l \partial \hat Z^l / \partial X^l 的问题了,先计算 Z ^ l / Z l \partial \hat Z^l / \partial Z^l

Z ^ = Z μ σ \hat Z=\frac{Z-\overline\mu}{\overline \sigma}

对于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)}

σ = 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}

σ = 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|

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 }

ϵ \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 \partial\overline \sigma/\partial Z μ / Z \partial\overline \mu/\partial Z

考虑到Batch Normalizaiton中一个batch中的训练样本相互独立,因此
μ z i , j = 1 m N 2 \frac{\partial \overline\mu}{\partial z_{i,j}}=\frac{1}{m·N^2}

t i , j = z i , j μ t_{i,j}=z_{i,j}-\mu , σ ( t i , j ) = t i , j 2 + ϵ m N \overline\sigma(t_{i,j})=\frac{\sqrt{t_{i,j}^2+\epsilon}}{m·N} , σ ( 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}
因此,
σ Z = 1 m N σ R N × N \frac{\partial \overline \sigma}{\partial Z}=\frac{1}{m·N·\overline\sigma}·R_{N×N}
σ μ = 1 m N σ R N × N \frac{\partial \overline \sigma}{\partial \overline \mu}=\frac{-1}{m·N·\overline\sigma}·R_{N×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}

R N × N R_{N×N} 是元素全为1的 N × N N×N 矩阵。

在Yolo中, N N 通常为416以上的值, σ \overline\sigma 接近0.1的倍数,当 m m 取32时,式子的第二项和第一项相比几乎可以忽略不计。因此,我认为 Z ^ / Z = 1 / σ R N × N \partial \hat Z/\partial Z=1/\overline\sigma·R_{N×N} 即可。减少很多计算量。

中间的推导可能有错误,不过不影响最终的结论。

卷积部分的计算

见我之前写的文章 卷积神经网络CNN的前向和后向传播(二)

其他

Batch Normalization部分,借一张图,来自Understanding the backward pass through Batch Normalization Layer

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_41665225/article/details/84197727