权重初始化

204 阅读4分钟

在机器学习和深度学习研究中,主要目的是使损失值最小。为了尽快做到这一点,有必要根据我们的问题来启动权重。这个问题被称为**"权重初始化"。**我们需要知道的第一件事是,这是一个设计决定。在我们训练网络之前,我们需要初始化所有的权重。权重的初始值会对训练过程产生重大影响。根据深度学习模型在训练过程中的起点,它可以收敛到不规则损失面中任何可能的局部最小值。

image.png

让我们一起思考。如果我们把所有的权重都从0开始,从时间和成本上来说都是一个糟糕的选择。还是说全部从0.5开始是有意义的?从错误的权重开始是否会导致梯度下降的爆炸或消失?答案是肯定的!这就是为什么我们需要初始化。让我们来总结一下。

为什么我们需要权重初始化?

  • 人工神经网络的学习在很大程度上取决于权重和偏差的初始设置。
  • "随机梯度下降 "收敛到局部最小值。
  • 避免了梯度消失和爆炸的问题。(太大的初始化会导致梯度爆炸,太小的初始化会导致梯度消失)。

image.png

权重初始化技术

  1. 零初始化
  2. 随机初始化
  3. 泽维尔初始化
  4. H-at-al初始化
  5. LeCun初始化

让我们更深入地研究它们中的每一个!为了简化问题,让我对每个初始化技术使用相同的基本模型。

 model = tf.keras.models.Sequential([        tf.keras.layers.Flatten(input_shape=(64, 32)),        tf.keras.layers.Dense(128, activation='relu', kernel_initializer,            bias_initializer)    ])

1.零初始化

顾名思义,零初始化就是将所有神经网络的权重初始化为0。请注意,这样做的前提是一半的最终权重为正,一半的权重为负。

如果网络的所有权重都被初始化为零,所有的激活都是零,相应的梯度也是零。事实上,即使权重被初始化为任何其他常数也没有关系。在这种情况下,激活可能不是零,但它们仍然是相同的。因此,我们可以排除零/常数的初始化。

model = tf.keras.models.Sequential([        tf.keras.layers.Flatten(input_shape=(64, 32)),        tf.keras.layers.Dense(128,                               activation='relu',                               kernel_initializer='zeros',                              bias_initializer='zeros')    ])

2.随机初始化

当激活函数为Sigmoid时,权重值离0越远,标准差越大,输出值就越偏向于接近0和1,然后就会失去梯度。解决这个问题的方法之一是以小标准差的正态分布来初始化权重。一般来说,初始权重以正态分布(高斯分布)随机初始化,其平均值为0,标准差为0.01,如下所示

# With normal distributionsmodel = tf.keras.models.Sequential([        tf.keras.layers.Flatten(input_shape=(64, 32)),        tf.keras.layers.Dense(128,                               activation='relu',                               kernel_initializer='RandomNormal',                              bias_initializer='zeros')    ])'''# With Uniform Distributionsmodel = tf.keras.models.Sequential([        tf.keras.layers.Flatten(input_shape=(64, 32)),        tf.keras.layers.Dense(128,                               activation='relu',                               kernel_initializer='RandomUniform',                              bias_initializer='zeros')'''

3.泽维尔(Glorot)初始化

随机初始化对于深度网络来说很快就会崩溃。其原因是,激活度在几层之后会迅速下降到零(梯度也是如此)。Xavier初始化的目的是初始化权重,使每一层的方差都是相同的。换句话说,每层输出的方差必须等于输入的方差,而且在反向传播中通过各层之前和之后的梯度方差必须相同。

# With normal distributionsmodel = tf.keras.models.Sequential([        tf.keras.layers.Flatten(input_shape=(64, 32)),        tf.keras.layers.Dense(128,                               activation='relu',                               kernel_initializer='glorot_normal',                              bias_initializer='zeros')    ])'''# With Uniform Distributionsmodel = tf.keras.models.Sequential([        tf.keras.layers.Flatten(input_shape=(64, 32)),        tf.keras.layers.Dense(128,                               activation='relu',                               kernel_initializer='glorot_uniform',                              bias_initializer='zeros')'''

4.He-at-al初始化

何凯明提出了一种适合ReLU的初始值,以他的名字命名,称为何初始值。他的初始化与Xavier的初始化几乎相似,但与Xavier初始化不同。这种差异与ReLU激活函数的非线性有关,他们对权重使用了不同的缩放系数。

# With normal distributionsmodel = tf.keras.models.Sequential([        tf.keras.layers.Flatten(input_shape=(64, 32)),        tf.keras.layers.Dense(128,                               activation='relu',                               kernel_initializer='he_normal',                              bias_initializer='zeros')    ])'''# With Uniform Distributionsmodel = tf.keras.models.Sequential([        tf.keras.layers.Flatten(input_shape=(64, 32)),        tf.keras.layers.Dense(128,                               activation='relu',                               kernel_initializer='he_uniform',                              bias_initializer='zeros')'''

5.LeCun初始化

它也被称为 "高效反推",考虑到每一层的输入和输出的大小。这种方法可用于不一定围绕零对称的激活函数,如双曲切线。它产生的权重是随机选择的数字乘以方差1/(input_layer_size)。

# With normal distributionsmodel = tf.keras.models.Sequential([        tf.keras.layers.Flatten(input_shape=(64, 32)),        tf.keras.layers.Dense(128,                               activation='relu',                               kernel_initializer='lecun_normal',                              bias_initializer='zeros')    ])'''# With Uniform Distributionsmodel = tf.keras.models.Sequential([        tf.keras.layers.Flatten(input_shape=(64, 32)),        tf.keras.layers.Dense(128,                               activation='relu',                               kernel_initializer='lecun_uniform',                              bias_initializer='zeros')'''

我们如何理解好的初始化?

  • 导致训练和测试集上的损失较小。
  • 不会使大多数sigmoid/tanh单元饱和。
  • 不会使ReLu单元爆炸。
  • 各层梯度的大小相似。

如何找到合适的初始化值?

  • 激活的平均值应该是零。
  • 激活的方差应该在每一层保持相同。

参考文献

  1. sebastianraschka.com/pdf/lecture…
  2. machinelearningmastery.com/weight-init…
  3. networks/#:~:text=Weight%20initialization%20is%20procedure,of%20neural%20network%20model.
  4. heartbeat.comet.ml/weight-init…
  5. wandb.ai/sauravmahes…
  6. medium.com/guidona-sof…
  7. machinelearningmastery.com/weight-init….
  8. koreascience.kr/article/JAK…
  9. web.eecs.umich.edu/~justincj/s…
  10. sebastianraschka.com/pdf/lecture…
  11. bigmeca.minesparis.psl.eu/wp-content/…
  12. www.deeplearning.ai/ai-notes/in…
  13. www.tensorflow.org/api_docs/py…