Earyant的技术博客

欢迎来到Earyant的技术博客,在这里我将与你分享新技术。

调参-权重初始化

前言

本节先对一些常见的初始化方案进行描述,然后依托于 Pytorch , 论述 Pytorch 中提供的几个初始化方案,最后提出一些使用建议。

权重初始化为何如此重要?

虽然 Batch Normalization, Layer Normalization 等 Trick 大大减轻了我们需要精选权重初始化方案的需要,但对于大多数情况下, 选择合适的初始化方案依旧有利于加速我们模型的收敛。

从根本上看,选择合适的初始化方案能够使得我们的损失函数便于优化(有些优化面坑坑洼洼,有些优化面比较光滑); 从另一个角度来说, 合适的权重初始化有利于减轻梯度消失,梯度爆炸问题(参考公式推导)。

Xavier 初始化

  • 目的: 减轻梯度消失问题。

在对梯度的研究中, 发现反向梯度从输出层到输入层逐渐减小, 同时反向梯度的方差随网络反向也逐渐减小,针对这种现象,提出了Xavier initialization。

其的基本思想为:保持每一层输入的方差,反向梯度的方差一致。通过方差可以控制输入输出分布以及分布密度之间不要相差太大, 这可以使得信息在网络中能够更平滑的传播。

Kaiming 初始化

kaiming初始化的出现是因为xavier存在一个不成立的假设。xavier在推导中假设激活函数都是线性的,而在深度学习中常用的ReLu等都是非线性的激活函数。而kaiming初始化本质上是高斯分布初始化,与上述高斯分布初始化有所不同,其是个满足均值为0,方差为2/n的高斯分布:

  • n 为所在曾的输入维度

初始化方案

1. 常量初始化

  • 初始化为 0: 当我们在初始化的时候,最容易想到的就是初始化为0,但是,将W初始化为0, 那么在前向计算的时候,我们的所有神经元的输出均为相同, 然后在反向传播中, 梯度相同权重更新相同,这明显是不可行的。

    所以, 千万不要初始化为0。

1
torch.nn.init.constant_(tensor, val)

2. 随机初始化

如果我们采用随机初始化,因为我们不知道我们的参数会初始化为多少, 如果初始化不合理, 造成梯度消失的可能性是相当之大,另一方面,如果初始化在优化面坑坑洼洼的那一面,我们的优化过程将变得异常曲折,局部最小值,鞍点以及大的平坦区会造成优化的噩梦。

2. 均匀分布初始化 - U(a,b)

1
torch.nn.init.uniform_(tensor, a=0.0, b=1.0)

3. 高斯分布 - N(mean, std)

1
torch.nn.init.normal_(tensor, mean=0.0, std=1.0)

4. 单位矩阵初始化

1
torch.nn.init.eye_(tensor)

5. Xavier 初始化

  • Xavier 均匀分布

    1
    torch.nn.init.xavier_uniform_(tensor, gain=1.0)
  • Xavier 正态分布

    1
    torch.nn.init.xavier_normal_(tensor, gain=1.0)

6. Kaiming 初始化(MSRA初始化)

  • Kaiming 均匀分布

    1
    torch.nn.init.kaiming_uniform_(tensor, a=0, mode='fan_in', nonlinearity='leaky_relu')
  • Kaiming 正态分布

    1
    torch.nn.init.kaiming_normal_(tensor, a=0, mode='fan_in', nonlinearity='leaky_relu')

7. 正交初始化

1
torch.nn.init.orthogonal_(tensor, gain=1)

8. 稀疏初始化

1
torch.nn.init.sparse_(tensor, sparsity, std=0.01)

QA

1. 推导一下 Xavier 的过程

单层网络

假设我们使用线性激活函数 $f(x)$,那么对于一层网络来说有:

根据方差展开式有:

那么,当 $E(x_i) = E(w_i) = 0, \,\,\,\, i = 1\cdots n$ 时, 输出 y 的方差为:

如果 $w_1, \cdots, w_n $ 独立同分布, $x_1, \cdots, x_n$ 也独立同分布, 那么有:

那么,我们就可以得出:

于是,为了保证方差的一致性,则应该有:

现在我们延伸到多层网络中,我们假设 $z^i$ 是第 $i$ 层激活函数的输出向量, $s^i$ 是第 $i$ 层激活函数的输入向量。

前向传播

那么在前向传播中, 第 $i$ 层的方差可以累积表达为:

反向传播

而在反向传播公式中, 损失函数对于 $s^i$ 梯度公式为:

那么在d层网络中,第 $i$ 层梯度的累计方差为:

我们的目的是,要求各层输入方差一致且各层梯度的方差也一致,这也就意味着:

那么必须有:

我们的W需要同时满足以上两个条件, 因此作为折中,有:

如果我们假设 W 服从均匀分布,则W在区间[a,b]内均匀分布的方差为:

那么带入就可以得到W的分布:

适用范围

Reference

[1] Xavier Glorot et al., Understanding the Difficult of Training Deep Feedforward Neural Networks

[2] Kaiming He et al., Delving Deep into Rectifiers: Surpassing Human-Level Performance on ImageNet Classfication

聊一聊深度学习的weight initialization

吴恩达团队:神经网络如何正确初始化?

欢迎关注我的其它发布渠道