Batch Normalization和Internal Covariate Shift
其实一开始接触深度学习我没有看公开课的,所以看到这个名词我觉得实在是太恐怖了,就没看了。
后面看了CS231n,然后自己又在知乎这些平台查了查,查了查,开始慢慢看懂了。
本文参考:
https://www.zhihu.com/question/38102762?utm_campaign=webshare&utm_source=weibo&utm_medium=zhihu
https://blog.****.net/malefactor/article/details/51476961(Internal Covariate Shift,author: 张俊林)
在上一篇提到Xavier,里面假设了数据和权重的期望为0。权重我们知道,我们自己初始化的想要它0就0,那数据呢?我们一般就是通过Batch Normalization这些措施让它的期望为0的,甚至方差为1。
前向传播过程
这是Batch Normalization的过程图。别一下子就很排斥,其实不难。我们求出数据的均值和方差(都是按很正常的方法),然后通过这些均值和方差我们进行z-score标准化。至于原理,刚好找到了一张图片解释它为什么经过这种变化之后期望会变成0,方差变成1。
除以的是,是因为怕方差为0时分母等于0。当然,这是我猜的,看的文章也没有解释。这个应该是一个很小的数,用来规避分母等于0的情况,所以大家也可以对它视而不见。
至于最后一行的Scale and shift操作,我还是引用知乎大神的原话:
保证整个network的capacity。(有关capacity的解释:实际上BN可以看作是在原模型上加入的“新操作”,这个新操作很大可能会改变某层原来的输入。当然也可能不改变,不改变的时候就是“还原原来输入”。如此一来,既可以改变同时也可以保持原输入,那么模型的容纳能力(capacity)就提升了。)
我的理解是,如果真的把深度学习看成一个自动的过程,那我们提供了一个方法给它优化数据,它也可以自己看情况不优化。我私底下觉得,其实我们为了减小梯度弥散的问题不用强行把所有的数据都拉到中间(tanh**函数的中间跟线性差不多),而且Relu**函数对于负的输入值是直接闭合的。
后向传播过程
相信看着上面前向传播的过程,这一个通过链式法则的求导也并不难。但需要注意的是,和前面是有个的,因为前向传播过程中,它们跟所有的进行运算的和才是。
Internal Covariate Shift
在我参考链接的第二篇里面,作者介绍了这个概念。
先了解下IID(Independent Identically Distributed,即独立同分布)假设。机器学习假设数据集和我们的测试集是属于独立同分布的。看了知乎杨淳的一个回答,里面说到:
随机变量X1和X2独立,是指X1的取值不影响X2的取值,X2的取值也不影响X1的取值。
随机变量X1和X2同分布,意味着X1和X2具有相同的分布形状和相同的分布参数,对离散随机变量具有相同的分布律,对连续随机变量具有相同的概率密度函数,有着相同的分布函数,相同的期望、方差。
也就是说,我们之所以可以通过拟合训练集的数据,来推断测试集的结果,是因为它们的分布具有相同的参数(我觉得这点比较重要)。为什么这个假设成立?大概是因为深度学习的确学习到了内容,并且可以用到实践上。
参考链接的作者提到,在训练的时候,我们传入的数据并不遵循一定的分布(因为内容不同)。既然这个假设成立,那我们把数据转化成固定的输入分布,来避免这个问题。这也是BN带来的好处。
当然,说精深的我也不会,只是看着别人的文章来理解。
顺便一提的是,作者说,在推理过程(也就是测试过程),由于进来的不再是一个Batch的数据,而是一个实例。我们使用的期望和方差是训练过程中的数值的平均。
大家可以再仔细看下文章,我认为讲的挺清楚易懂的。