具有 sigmoid 神经元的神经网络不会学习是否在初始化后将一个因子添加到所有权重和偏差
Neural network with sigmoid neurons does not learn if a factor is added to all weights and biases after initialization
我将要试验用于手写识别的神经网络,可在此处找到:
https://github.com/mnielsen/neural-networks-and-deep-learning/blob/master/src/network.py
如果权重和偏差是随机初始化的,它会在几个 epoch 后识别出超过 80% 的数字。如果我在初始化后给所有的权重和偏差加上一个 0.27 的小因子,学习会慢很多,但最终它达到了相同的 80% 以上的准确率:
self.biases = [np.random.randn(y, 1)+0.27 for y in sizes[1:]]
self.weights = [np.random.randn(y, x)+0.27 for x, y in zip(sizes[:-1], sizes[1:])]
Epoch 0 : 205 / 2000
Epoch 1 : 205 / 2000
Epoch 2 : 205 / 2000
Epoch 3 : 219 / 2000
Epoch 4 : 217 / 2000
...
Epoch 95 : 1699 / 2000
Epoch 96 : 1706 / 2000
Epoch 97 : 1711 / 2000
Epoch 98 : 1708 / 2000
Epoch 99 : 1730 / 2000
如果我在初始化后将 0.28 的小因子添加到所有权重和偏差,网络将不再学习。
self.biases = [np.random.randn(y, 1)+0.28 for y in sizes[1:]]
self.weights = [np.random.randn(y, x)+0.28 for x, y in zip(sizes[:-1], sizes[1:])]
Epoch 0 : 207 / 2000
Epoch 1 : 209 / 2000
Epoch 2 : 209 / 2000
Epoch 3 : 209 / 2000
Epoch 4 : 209 / 2000
...
Epoch 145 : 234 / 2000
Epoch 146 : 234 / 2000
Epoch 147 : 429 / 2000
Epoch 148 : 234 / 2000
Epoch 149 : 234 / 2000
我认为这与 sigmoid 函数有关,它在接近 1 和 0 时变得非常平坦。但是当权重和偏差的平均值为 0.28 时会发生什么?为什么可识别数字的数量会急剧下降?为什么会出现上述429这样的异常值?
初始化在训练网络中起着重要作用。一个好的初始化可以使训练和收敛更快,而一个不好的初始化会使它慢很多倍。它甚至可以完全允许或阻止收敛。
您可能想阅读本文以获取有关该主题的更多信息
https://towardsdatascience.com/weight-initialization-in-neural-networks-a-journey-from-the-basics-to-kaiming-954fb9b47c79
通过将 0.27 添加到所有权重和偏差,您可能会使网络偏离最佳解决方案并增加梯度。根据层数,这可能会导致梯度爆炸。现在你每次迭代都有非常大的权重更新。可能发生的情况是您的权重为 0.3(在添加 0.27 之后),我们说最佳值为 0.1。现在你得到一个 -0.4 的更新,现在你在 -0.1。下一次更新可能是 0.4(或接近),您又回到了最初的问题。因此,优化并没有慢慢接近最佳值,而是超越了一切并来回反弹。这可能会在一段时间后得到修复,或者可能导致完全不收敛,因为网络只是反弹。
另外,通常您希望将偏差初始化为 0 或非常接近于零。如果你进一步尝试这个,你可能想尝试不将 0.27 添加到偏差中并将它们设置为 0 或最初接近 0 的值。也许通过这样做它实际上可以再次学习。
我将要试验用于手写识别的神经网络,可在此处找到: https://github.com/mnielsen/neural-networks-and-deep-learning/blob/master/src/network.py 如果权重和偏差是随机初始化的,它会在几个 epoch 后识别出超过 80% 的数字。如果我在初始化后给所有的权重和偏差加上一个 0.27 的小因子,学习会慢很多,但最终它达到了相同的 80% 以上的准确率:
self.biases = [np.random.randn(y, 1)+0.27 for y in sizes[1:]]
self.weights = [np.random.randn(y, x)+0.27 for x, y in zip(sizes[:-1], sizes[1:])]
Epoch 0 : 205 / 2000
Epoch 1 : 205 / 2000
Epoch 2 : 205 / 2000
Epoch 3 : 219 / 2000
Epoch 4 : 217 / 2000
...
Epoch 95 : 1699 / 2000
Epoch 96 : 1706 / 2000
Epoch 97 : 1711 / 2000
Epoch 98 : 1708 / 2000
Epoch 99 : 1730 / 2000
如果我在初始化后将 0.28 的小因子添加到所有权重和偏差,网络将不再学习。
self.biases = [np.random.randn(y, 1)+0.28 for y in sizes[1:]]
self.weights = [np.random.randn(y, x)+0.28 for x, y in zip(sizes[:-1], sizes[1:])]
Epoch 0 : 207 / 2000
Epoch 1 : 209 / 2000
Epoch 2 : 209 / 2000
Epoch 3 : 209 / 2000
Epoch 4 : 209 / 2000
...
Epoch 145 : 234 / 2000
Epoch 146 : 234 / 2000
Epoch 147 : 429 / 2000
Epoch 148 : 234 / 2000
Epoch 149 : 234 / 2000
我认为这与 sigmoid 函数有关,它在接近 1 和 0 时变得非常平坦。但是当权重和偏差的平均值为 0.28 时会发生什么?为什么可识别数字的数量会急剧下降?为什么会出现上述429这样的异常值?
初始化在训练网络中起着重要作用。一个好的初始化可以使训练和收敛更快,而一个不好的初始化会使它慢很多倍。它甚至可以完全允许或阻止收敛。
您可能想阅读本文以获取有关该主题的更多信息
https://towardsdatascience.com/weight-initialization-in-neural-networks-a-journey-from-the-basics-to-kaiming-954fb9b47c79
通过将 0.27 添加到所有权重和偏差,您可能会使网络偏离最佳解决方案并增加梯度。根据层数,这可能会导致梯度爆炸。现在你每次迭代都有非常大的权重更新。可能发生的情况是您的权重为 0.3(在添加 0.27 之后),我们说最佳值为 0.1。现在你得到一个 -0.4 的更新,现在你在 -0.1。下一次更新可能是 0.4(或接近),您又回到了最初的问题。因此,优化并没有慢慢接近最佳值,而是超越了一切并来回反弹。这可能会在一段时间后得到修复,或者可能导致完全不收敛,因为网络只是反弹。
另外,通常您希望将偏差初始化为 0 或非常接近于零。如果你进一步尝试这个,你可能想尝试不将 0.27 添加到偏差中并将它们设置为 0 或最初接近 0 的值。也许通过这样做它实际上可以再次学习。