一、为什么要使用Batch-Norm?
从效果来看,Batch-Norm可以使用较大的lr,不用太小心翼翼的care参数初始化的问题,还可以加速收敛。
对于深度网络的训练是一个复杂的过程,只要网络的前面几层发生微小的改变,那么后面几层就会被累积放大下去。一旦网络某一层的输入数据的分布发生改变,那么这一层网络就需要去适应学习这个新的数据分布,所以如果训练过程中,训练数据的分布一直在发生变化,那么将会影响网络的训练速度。
我们知道网络一旦train起来,那么参数就要发生更新,除了输入层的数据外(因为输入层数据,我们已经人为的为每个样本归一化),后面网络每一层的输入数据分布是一直在发生变化的,因为在训练的时候,前面层训练参数的更新将导致后面层输入数据分布的变化。以网络第二层为例:网络的第二层输入,是由第一层的参数和input计算得到的,而第一层的参数在整个训练过程中一直在变化,因此必然会引起后面每一层输入数据分布的改变。我们把网络中间层在训练过程中,数据分布的改变称之为:“Internal Covariate Shift”。
二、Batch-Norm怎么实现?
1.正向传播
2.反向传播
batch-norm子网络的反向传播求梯度同样是根据链式求导法则
三、测试中要使用吗?怎么用?
你可能会想,既然训练时用了批量归一化,那么测试时也该用批量归一化吗?其实这个问题乍一想不是很好回答,因为:
- 不用的话,训练出的模型参数很可能在测试时就不准确了;
- 用的话,万一测试的数据就只有一个数据实例就不好办了。
事实上,在测试时我们还是需要继续使用批量归一化的,只是需要做些改动。在测试时,我们需要把原先训练时用到的批量均值和方差替换成整个训练数据的均值和方差。但
是当训练数据极大时,这个计算开销很大。因此,我们用移动平均的方法来近似计算(参见实现中的moving_mean
和moving_variance
)。