更多隐藏层
书中分别对比了不同学习率,不同隐藏层结点数和不同训练世代的模型学习效果,没有对比多隐藏层的模型,我自己添加了一层隐藏层的代码,得出的训练结果如下:
世代 | 隐藏层 | 隐藏层结点数 | 学习率 | 识别率 | 训练时长(s) |
---|---|---|---|---|---|
1 | 2 | 10*10 | 0.2 | 0.7677 | 11.5368 |
1 | 2 | 20*20 | 0.2 | 0.8066 | 17.0215 |
1 | 2 | 30*30 | 0.2 | 0.8442 | 17.4176 |
1 | 2 | 20*30 | 0.2 | 0.7984 | 16.7845 |
1 | 2 | 30*20 | 0.2 | 0.8412 | 17.7463 |
1 | 2 | 50*50 | 0.2 | 0.8471 | 20.3632 |
1 | 2 | 100*100 | 0.2 | 0.8496 | 31.0611 |
2 | 2 | 100*100 | 0.2 | 0.8635 | 65.3597 |
可见多一层隐藏层学习效果不但没有提高,反而下降了。
相同训练世代相同学习率的识别率:
10 * 10 < 20 * 30 < 20 * 20 < 30 * 20 < 30 * 30 < 50 * 50
看看训练集的数字图像
把训练集的数组转换成图像,大概浏览一下手写的样子
转换代码:
import numpy as np
import matplotlib.pyplot as plt
with open(r'mnist/mnist_train.csv', 'r') as datafile:
line = datafile.readline()
i = 1
while line and i < 50:
all_values = line.split(',')
label = all_values[0]
img_array = np.asfarray(all_values[1:]).reshape((28, 28))
# plt.axis('off')
plt.imshow(img_array, cmap='Greys')
filename = 'mnist/mnist_images/test' + str(i) +\
'_' + label + '.png'
plt.savefig(filename)
i += 1
line = datafile.readline()
更多的训练数据
MNIST有60,000条训练数据,书上为了获得更多的训练数据把每一条训练数据的图像分别顺时针、逆时针旋转了10度,这样就添加了两倍的训练样本。
世代 | 隐藏层 | 隐藏层结点数 | 学习率 | 识别率 | 训练时长(s) | 是否训练旋转数据 |
---|---|---|---|---|---|---|
1 | 1 | 100 | 0.2 | 0.9518 | 25.4991 | 否 |
1 | 1 | 100 | 0.2 | 0.9471 | 70.7045 | 是 |
1 | 1 | 100 | 0.1 | 0.9503 | 25.7134 | 否 |
1 | 1 | 100 | 0.1 | 0.9544 | 70.7045 | 是 |
1 | 1 | 100 | 0.01 | 0.9131 | 26.4683 | 否 |
1 | 1 | 100 | 0.01 | 0.9329 | 72.5362 | 是 |
1 | 1 | 100 | 0.05 | 0.9443 | 27.1351 | 否 |
1 | 1 | 100 | 0.05 | 0.9519 | 73.1557 | 是 |
1 | 1 | 200 | 0.01 | 0.9065 | 97.4234 | 否 |
1 | 1 | 200 | 0.01 | 0.9338 | 296.3523 | 是 |
10 | 1 | 200 | 0.01 | 0.9677 | 1115.5962 | 否 |
10 | 1 | 200 | 0.01 | 0.9777 | 2890.7095 | 是 |
当学习率为0.2时,加入旋转训练数据的模型识别率反倒更低,将学习率减小为0.01以后增加旋转数据可以提高识别率,通过学习率0.01和0.05两个模型进一步判断学习率越小,增加旋转训练数据带来的学习率提高越多。但问题是很明显训练样本增多反而导致识别率下降。于是我怀疑我的代码有问题,下载了作者的代码跑,他是200个隐藏层结点、0.01的学习率跑了10个世代,github上他代码跑的结果是0.9754,我下载下来跑的是0.9779,然后我把我的代码改成一样的跑法用了2890.709569秒合48分钟,识别率是0.9777,看来代码没问题。然后我对比了一下10世代不用旋转数据的,识别率是0.9677,看来大样本要进行多世代的学习以后效果才显现,另外正如书上说的,样本量大了以后可以采用更小、更谨慎的学习步长,因此将学习率减少到0.01。
另外我对比了一下我的代码和作者代码的执行效率,100个隐藏层结点0.2学习率1世代我的代码跑了71.5秒,作者的跑了74秒。
问题
上一篇笔记中提到初始化权重的时候正态分布方差使用的是传入链接数也就是上一层结点数,而书上用的是当前结点数,我在看github上的代码时作者已经修正为上一层结点数了。