batch normalization 理解

论文连接:https://arxiv.org/abs/1502.03167

一、什么是covariate shift

论文中表示,深度学习中,网络难以训练是因为covariate shift导致的。那么什么是covariate shift。这里有篇博客,个人感觉写的不错,其中写道:

那么covariate shift到底是什么?
不用想得太复杂,covariate shift 最早只是机器学习中的一个问题。同时迁移学习会经常涉及到这个概念。
假设x是属于特征空间的某一样本点,y是标签。covariate这个词,其实就是指这里的x,那么covariate shift可以直接根据字面意思去理解:样本点x的变化。
这么简单?没错就是这么简单!
我们讲的规范一点:
假设q1(x)是测试集中一个样本点的概率密度,q0(x)是训练集中一个样本点的概率密度。最终我们估计一个条件概率密度p(y|x,θ),它由x和一组参数θ={θ1,θ2……θm}所决定。对于一组参数来说,对应loss(θ)函数评估性能的好坏
综上,当我们找出在q0(x)分布上最优的一组θ’时,能否保证q1(x)上测试时也最好呢?
传统机器学习假设训练集和测试集是独立同分布的,即q0(x)=q1(x),所以可以推出最优θ’依然可以保证q1(x)最优。但现实当中这个假设往往不成立,伴随新数据产生,老数据会过时,当q0(x)不再等于q1(x)时,就被称作covariate shift

论文中对 Internal Covariate Shift 定义:在训练过程中,由于网络参数的变化,导致的网络中每层输入数据分布的偏移,称为 Internal Covariate Shift。

这篇博客 对于Covariate Shift 和 Internal Covariate Shift 是这样理解的:

2.2 covariate shift和internal covariate shift
2.2.1 covariate shift
假设一个模型的输入是X(比如在MNIST任务,X是一个784的向量),输出是Y(比如MNIST是0-9的10个类别)。很多Discriminative 模型学到的是P(Y|X),神经网络也是这样的模型。而covariate shift问题是由于训练数据的领域模型 Ps(X) 和测试数据的 Pt(X) 分布不一致造成的,这里的下标s和t是source和target的缩写,代表训练和测试。
乍一看这个应该不是什么问题。毕竟我们的目标是分类,只要 Ps(Y|X) 和 Pt(Y|X) 是一样的就行了。和X的分别 Ps(X) 以及 Pt(X) 有什么关系呢?
问题的关键是我们训练的模型一般都是参数化的模型 Ps(Y|X;θ) ,也就是我们用一个参数化的模型来学习X和Y的关系。我们根据训练数据上的loss来选择最佳的 θ∗。但是在很多时候,我们没法学习出一个完美的模型,因此总会有一些X使得 P(Y|X)≠P(Y|X;θ) 。那在这个时候P(X)就会带来影响。
比如说我这个模型在 X1和 X2 都会出错,也就是都有loss。我们可以调整参数,当然完美的情况是调参的结果使得两个点上的loss都变小。可惜这一点做不到,我们只能是一个变小一个变大,那么我们应该倾向与哪个呢?很显然要看 P(X1)和 P(X2) 哪个大。如果 P(X1) 大,也就是说 X1 更容易出现,那么当然应该让 X1 的loss更小(从而分类正确的可能性更大,如果是回归的话更是这样)。
现在问题来了,如果训练数据中Ps(X)和测试数据Pt(X)不一样,那么就会带来问题。举一个极端的例子,假设我们的X只有两种取值数据1和数据2,他们的类别是不同的,但是我们的feature很不好,根本没法区分出X1和X2来,也就是说X1=X2。因此我们的模型肯定无法正确的分类出数据1和数据2来。但是我们的模型必须做出选择,那怎么选择呢?当然要看P(X1)和P(X2)哪个大,我们尽量把出现概率大的那个分对。如训练的时候数据1出现的概率大,那么我们的分类器会把他分类成数据1的类别。但是如果我们测试的数据确实数据2的概率大,那么我们的模型就会有问题。
解决这个问题的方法有很多,其中一种思路是重新训练一个新的模型,对训练数据进行”加权“。不过这和我们的Batch Normalization关系不大,就不展开了。介绍它的目的是让大家知道有这样一个问题,如果在实际的工作中碰到训练数据的分布和测试数据的分布不一样,要想想这个会不会带来问题。
2.2.2 internal covariate shift
通过前面的分析,我们知道如果训练时和测试时输入的分布变化,会给模型带来问题。当然在日常的应用中,这个问题一般不会太明显,因为一般情况数据的分布差别不会太大(尤其是P(Y|X)不会,否则之前的训练数据完全没法用了,可以认为是两个不同的任务了),但是在很深的网络里这个问题会带来问题,使得训练收敛速度变慢。因为前面的层的结果会传递到后面的层,而且层次越多,前面的细微变化就会带来后面的巨大变化。如果某一层的输入分布总是变化的话,那么它就会无所适从,很难调整好参数。我们一般会对输入数据进行”白化“除理,使得它的均值是0,方差是1。但是之后的层就很难保证了,因为随着前面层参数的调整,后面的层的输入是很难保证的。比较坏的情况是,比如最后一层,经过一个minibatch,把参数调整好的比之前好一些了,但是它之前的所有层的参数也都变了,从而导致下一轮训练的时候输入的范围都发生变化了,那么它肯定就很难正确的分类了。这就是所谓的internal covariate shift。

那么在网络训练中,covariate shift 是如何出现的呢?
个人理解:在采用 SGD 策略训练网络时,采用上一次的batch samples 训练,对于参数进行更新,理想情况下,更新后的 网络的loss 将变低。假定,我们针对网络中的第i层,设它的这次迭代是的输入是input1,那么当这次迭代更新后,网络参数发生变化,当发生下一次迭代,更新网络时,第i层网络的输入就变成了input2,input2和input1的数据分布发生变化,就连数据范围都发生了变化,因此网络的上一次更新对这一次不没有太大的帮助。因此网络难以训练,很难收敛。

=====未完待续====

猜你喜欢

转载自blog.csdn.net/feng_jiakai/article/details/81221228