1.BN(Batch Normalization)算法作用
神经网络学习过程本质就是为了学习数据分布,一旦训练数据与测试数据的分布不同,那么网络的泛化能力也大大降低;另外一方面,一旦每批训练数据的分布各不相同(batch 梯度下降),那么网络就要在每次迭代都去学习适应不同的分布,这样将会大大降低网络的训练速度,这也正是为什么我们需要对数据都要做一个归一化预处理的原因。 BN的作用是通过规范化的手段,将越来越偏的分布拉回到标准化的分布,使得激活函数的输入值落在激活函数对输入比较敏感的区域,从而使梯度变大,加快学习收敛速度,避免梯度消失的问题。
BN算法过程:首先,BN算法在每一次iteration中的每一层输入都进行了归一化,将输入数据的分布归一化为均值为0,方差为1的分布,如下式:
但是这种做法有一种致命的缺陷,就是尽管这样把每层的数据分布都固定了,但是这种分布不一定是前面一层的要学习到的数据分布,这样强行归一化就会破坏掉刚刚学习到的特征,BN算法的第二步就解决了这个缺点。
BN算法在第二步中设置了两个可学习的变量和
,然后用这两个变量去学习上一层学习到的数据分布。
添加这种操作的目的就是还原出上一层需要学习的数据分布,这样BN就把原来不固定的数据分布全部转换为固定的数据分布,而这种数据分布恰恰就是要学习到的分布,从而加速了网络的训练。
2.Dropout 层的原理、应用
Dropout说的简单一点就是:我们在前向传播过程中,通过让某个神经元的激活值以一定概率P停止工作,这样可以使模型泛化性更强,因为它不会依赖某些局部特征。在每个训练批次中,通过忽略一定比例的特征检测器(让一半的隐层节点值为0),可以明显地减少过拟合现象。这种方式可以减少特征检测器(隐层节点)间的相互作用,检测器相互作用是指某些检测器依赖其他检测器才能发挥作用。
3.BN,LN,IN,GN的区别
BN是在batch上,对NHW做归一化,每一层的Batch有相同的数据分布,对小batch效果不好。
LN是在通道上,对CHW做归一化,每一个通道的输入有相同的数据分布,主要对RNN作用明显。
IN在图像像素上,对HW做归一化,用在风格化迁移。
GN将channel分组,然后再做归一化。
BN算法过程: (1)、沿着通道计算每个batch的均值u (2)、沿着通道计算每个batch的方差σ^2 (3)、对x做归一化,x’=(x-u)/开根号(σ^2+ε) (4)、加入缩放和平移变量γ和β ,归一化后的值,y=γx’+β 加入缩放平移变量的原因是: 不一定每次都是标准正态分布,也许需要偏移或者拉伸。保证每一次数据经过归一化后还保留原有学习来的特征,同时又能完成归一化操作,加速训练。 这两个参数是用来学习的参数。
整体公式:
前向传播CODE:
其中x为(N,C * H * W)
mu = np.mean(x,axis=0)
sigma2 = np.var(x,axis=0)
x_hat = (x-mu)/np.sqrt(sigma2+eps)
out = gamma*x_hat + beta
batch normalization存在以下缺点:
(1)、对batchsize的大小比较敏感,由于每次计算均值和方差是在一个batch上,所以如果batchsize太小,则计算的均值、方差不足以代表整个数据分布; (2)、BN实际使用时需要计算并且保存某一层神经网络batch的均值和方差等统计信息,对于对一个固定深度的前向神经网络(DNN,CNN)使用BN,很方便;但对于RNN来说,sequence的长度是不一致的,换句话说RNN的深度不是固定的,不同的time-step需要保存不同的statics特征,可能存在一个特殊sequence比其他sequence长很多,这样training时,计算很麻烦。
与BN不同,LN是针对深度网络的某一层的所有神经元的输入按以下公式进行normalize操作。
BN与LN的区别在于:
(1)、LN中同层神经元输入拥有相同的均值和方差,不同的输入样本有不同的均值和方差; (2)、BN中则针对不同神经元输入计算均值和方差,同一个batch中的输入拥有相同的均值和方差。 (3)、LN用于RNN效果比较明显,但是在CNN上,不如BN。 前向传播代码:
x = x.T # (D, N)
mu = np.mean(x, axis=0) # (N,)
sigma2 = np.var(x, axis=0) # (N,)
x_hat = (x - mu) / np.sqrt(sigma2 + eps)
x_hat = x_hat.T # (N, D)
out = gamma * x_hat + beta
inv_sigma = 1 / np.sqrt(sigma2 + eps)
cache = (x_hat,