神经网络权重初始化

在神经网络模型训练过程中需要对参数 weight 进行更新,在更新前需要进行初始化操作,当模型足够复杂时,一个好的初始化对模型优化至关重要。

为什么不能全部初始化为0?

如果所有参数都是0,那么所有神经元的输出都是相同的,在 forward 和 back 时每一层的神经元的值和梯度都是一样的,使模型过于简单。

pre-training

pre-training一般分两个阶段:① pre-training 阶段,对神经网络的每一层取出构造一个 auto-encoder 做训练,使得输出层能够复现输出层,在这个过程中得到初始参数 ② fine-tuning 阶段,将上一步得到的参数作为初始化参数对模型进行整体调整。

感觉现在不太流行这种做法,个人对此不太熟悉。

高斯分布初始化

直接对参数进行高斯分布初始化,通常均值为0,标准差为0.01。

1
W = tf.Variable(np.random.randn(node_in, node_out)) * 0.01

Xavier 初始化

Xavier 初始化方法来自论文[1],文章假设激活函数为线性且满足0点处导数为1.

如果
$$
y = w_1x_1 + \cdots + w_nx_n + b
$$
根据概率统计知识有下面的方差公式:
$$
Var(w_ix_i) = E[w_i]^2Var(x_i) + Var(w_i)E(x_i)^2 + Var(w_i)Var(x_i) \ \ \ \ \ \ \ \ \ (1)
$$
特别的,当我们假设输入和权重都是零均值时(可以通过Batch Normalization),上式可以简化为:
$$
Var(w_ix_i) = Var(w_i)Var(x_i)
$$
进一步假设输入x和权重w独立同分布,则有:
$$
Var(y) = nVar(w_i)Var(x_i)
$$
于是,为了保证输入输出方差一致,则应该有:
$$
Var(w_i) = \frac{1}{n}
$$
考虑前向和后向传播时每一层的方差一致,应该满足上式,最终我们的权重方差应该满足:
$$
Var(W) = \frac{2}{node_{in}+node_{out}}
$$
因为[a,b]区间均匀分布的方差为:
$$
Var = \frac{(b-a)^2}{12}, E = \frac{a+b}{2}
$$
因此,Xavier 初始化就是下面的均匀分布:
$$
W \sim U[-\frac{\sqrt{6}}{\sqrt{(node_{in}+node_{out})}}, \frac{\sqrt{6}}{\sqrt{(node_{in}+node_{out})}}]
$$

1
W = tf.Variable(np.random.uniform(-np.sqrt(6/(in+out))), np.sqrt(6/(in+out)))
W = tf.Variable(np.random.randn(in, out)) * np.sqrt(2./(in+out))

MSRA 权重初始化

MASR 权重初始化方法来自论文[2],因为 Xavier 推导的时候假设激活函数是线性的,显然常用的激活函数 ReLU 并不满足。推导过程与 Xavier 类似,在得到(1)式后,输入的均值不为0,所以:
$$
Var(w_ix_i) = Var(w_i)E(x_i)^2 + Var(w_i)Var(x_i) = Var(w_i) E({x_i}^2)
$$
所以有:
$$
Var(y) = nVar(w_i)E({x_i}^2)
$$
对于 ReLU 函数,
$$
x_l = f(y_{l-1}), \ \ \ \ \ \ \ E(x^2_l) = \frac{1}{2} Var(y_{l-1})
$$
带入上式得,
$$
Var(y_l) = \frac{1}{2}n_l Var(w_l)Var(y_{l-1})
$$
为了使得每一层数据的方差保持一致,则权重应该满足:
$$
\frac{1}{2}n_l Var(w_l) = 1, \forall l
$$

$$
Var(W) = \frac{2}{n}
$$

1
W = tf.Variable(np.random.randn(in, out)) * np.sqrt(4./(in+out))

Batch Normalization

BN是在进行非线性激活函数前,对输入值做 normalize,来自论文[3]。
$$
\mu \leftarrow \frac{1}{m}\sum_{i=1}^m{x_i}
$$

$$
\sigma ^2 \leftarrow \frac{1}{m}\sum_{i=1}^m{(x_i-\mu)^2}
$$

$$
x_i \leftarrow \frac{x_i-\mu}{\sqrt{\sigma^2+\epsilon}}
$$

$$
y_i \leftarrow \gamma x_i + \beta
$$

BN 中所有的操作都是平滑可导的,这使得反向传播可以有效运行并学到相应的参数。需要注意的一点是 BN 在训练和测试的时候有所差别。训练的时候由当前 batch 计算得出,在测试的时候应该使用训练时保存的均值或类似的经过处理的值,而不是由当前 batch 计算。

1
layer = tf.contrib.layers.batch_norm(layer, center=True, scale=True, is_training=True)

参考文献

[1] Glorot X, Bengio Y. Understanding the difficulty of training deep feedforward neural networks[C]//Aistats. 2010, 9: 249-256.

[2] He K, Zhang X, Ren S, et al. Delving deep into rectifiers: Surpassing human-level performance on imagenet classification[C]//Proceedings of the IEEE international conference on computer vision. 2015: 1026-1034.

[3] Ioffe S, Szegedy C. Batch normalization: Accelerating deep network training by reducing internal covariate shift[J]. arXiv preprint arXiv:1502.03167, 2015.

[4] http://blog.csdn.net/shuzfan/article/details/51338178

[5] http://blog.csdn.net/shuzfan/article/details/51347572

[6] http://www.leiphone.com/news/201703/3qMp45aQtbxTdzmK.html