初始权重优化
(二)中提出通过改变损失函数以解决输出层对错误学习慢的问题,但是这个并不会解决隐藏层的训练慢问题。隐藏层采用的是S函数,回归S函数的特征,当输入值绝对值|x|比较大,对x做微小的改变,S的输出改变很小。因为|x|越大,S的偏倒越接近0。前面文章中均采用标准正太分布的方式给予权重。研究第一个隐藏层,例如手写识别输入向量是784维度,然后对输入进行归一化(数据本来就已经归一化处理了)。以一个节点为例:带权输出z接近784个标准正太分布相加,mean = 0, std= sqrt(785),Z的峰度会很低,|z|的取值有很大几率会很大:
z = w[1]x[1] + w[2]x[2] +...+w[784]x[784] + b
- 上面的启发,如果初始化采用std=1 / sqrt(N)的正态分布,便接解决上面问题了,N前一层输入样本的个数
实证对比
code采用(3)下,然后对模型的权重初始化方法做出更改,更改的代码如下
...
def NewInitWeight(self):
self.bias = [np.random.randn(num) for num in self.size[1:]] # 输入层没有bias
# 每层的权重取决于row取决于该层的节点数量,从来取决于前面一层的输出即节点数
self.weight = [np.random.randn(row, col) / np.sqrt(col) for row, col in zip(self.size[1:], self.size[:-1])]
...
采用同样的参数对比:
- 新方法虽然在初始迭代期弱势(初始权重随机因素导致),后面优化结果迅速超越原先的初始权重的方法*。参数采用三(下)的参数。
- 采用新方法初始权重效果
Epoch 0: 540/1000
Epoch 1: 742/1000
Epoch 2: 797/1000
Epoch 3: 799/1000
Epoch 4: 819/1000
Epoch 5: 807/1000
Epoch 6: 821/1000
Epoch 7: 838/1000
Epoch 8: 843/1000
Epoch 9: 853/1000
Epoch 10: 846/1000
Epoch 11: 847/1000
Epoch 12: 851/1000
Epoch 13: 857/1000
Epoch 14: 857/1000
Epoch 15: 855/1000
- 原先方法初始权重效果
Epoch 0: 676/1000
Epoch 1: 727/1000
Epoch 2: 778/1000
Epoch 3: 719/1000
Epoch 4: 768/1000
Epoch 5: 794/1000
Epoch 6: 731/1000
Epoch 7: 724/1000
Epoch 8: 798/1000
Epoch 9: 698/1000
Epoch 10: 802/1000
Epoch 11: 812/1000
Epoch 12: 817/1000
Epoch 13: 824/1000
Epoch 14: 807/1000
Epoch 15: 806/1000