1. Batch Normalization
(Batch Normalization是由Sergey Ioffe et al.在2015年提出)
机器学习假设training data和testing data是IID独立同分布,从而在testing data上有很好的效果。实际应用会出现Internal Covariate Shift问题。Batch Normalization(2014年提出)就是在深度神经网络训练过程中使得每一层神经网络的输入保持相同分布的,克服梯度消失问题,保证了更深的网络能够被有效训练。
BN可以理解为对深层神经网络每个隐层神经元的激活值做简化版本的白化操作(就是对输入数据分布变换到0均值,单位方差的正态分布)。
BN为了保证非线性的获得,防止网络表达能力的下降,对变换后的满足均值为0方差为1的x又进行了scale加上shift操作(y=scale*x+shift)
公式表达如下:
是上一层激活函数的输出,然后计算
,BN在这一步进行,计算
和
得到
,
再进行scale和shift操作得到
最后过一层的激活函数
注意BN是对当前batch中的samples的每一个特征维度(即下一层神经元的个数)独立做Normalization。
做testing data的inference时,当一个unseen sample进来时,用的是全量training data的均值和方差。
BN的优点还有调参过程也简单多了,对于初始化要求没那么高,而且可以使用大的学习率等。
Batch normalization的python代码实现见我的github:
https://github.com/weidong1/tf_ai_algorithm/blob/master/tf_batch_norm.py
2. 权重初始化
2.1 random initialization
W=tf.Variable(np.random.randn(node_in,node_out)) * 0.01
这样初始化权重的均值是0,方差是0.01
但随着层数的增加,输出值迅速向0靠拢,因为back propogation时gradient越来越小,参数更新困难。
2.2 Xavier initialization
(Xavier initialization是由Xavier Glorot et al.在2010年提出)
基本思想是保持输入和输出的方差一致,这样就避免了所有输出值都趋向于0。
W = tf.Variable(np.random.randn(node_in, node_out)) / np.sqrt(node_in)
但是其对ReLU等非线性神经元依然存在多层传递后输出值趋向于零。
2.3 He initialization
(He initialization是由Kaiming He et al.在2015年提出)
He initialization是Xavier Initialization的变种。的思想是:在ReLU网络中,假定每一层有一半的神经元被激活,另一半为0,所以,要保持variance不变,只需要在Xavier的基础上再除以2:
W = tf.Variable(np.random.randn(node_in,node_out)) / np.sqrt(node_in/2)
2.4 Batch Normalization Layer
正如我在另一个帖子中介绍,BN的目的也是为了保证输入数据和输出数据分布一致。
使用Batch Normalization Layer可以有效降低深度网络对weight初始化的依赖,因而只需要对权重随机初始化就行。
W = tf.Variable(np.random.randn(node_in, node_out)) * 0.01
fc = tf.matmul(X, W)
# put this before nonlinear transformation
fc = tf.contrib.layers.batch_norm(fc, center=True, scale=True,
is_training=True)
fc = tf.nn.relu(fc)
参考:
https://zhuanlan.zhihu.com/p/25110150