首先,隐藏层只有30个节点。由我们之前对隐藏层的启发式理解可以猜测,神经网络的识别能力其实与隐藏层对一些细节的识别能力正相关。如果隐藏层的节点更多的话,其识别能力应该会更强的。那么我们设定100个隐藏层节点试试?
net = network.Network([784, 100, 10]) net.SGD(training_data, 30, 10, 3.0, test_data=test_data)发现结果如下:
Epoch 0: 6669 / 10000 Epoch 1: 6755 / 10000 Epoch 2: 6844 / 10000 Epoch 3: 6833 / 10000 Epoch 4: 6887 / 10000 Epoch 5: 7744 / 10000 Epoch 6: 7778 / 10000 Epoch 7: 7876 / 10000 Epoch 8: 8601 / 10000 Epoch 9: 8643 / 10000 Epoch 10: 8659 / 10000 Epoch 11: 8665 / 10000 Epoch 12: 8683 / 10000 Epoch 13: 8700 / 10000 Epoch 14: 8694 / 10000 Epoch 15: 8699 / 10000 Epoch 16: 8715 / 10000 Epoch 17: 8770 / 10000 Epoch 18: 9611 / 10000 Epoch 19: 9632 / 10000 Epoch 20: 9625 / 10000 Epoch 21: 9632 / 10000 Epoch 22: 9651 / 10000 Epoch 23: 9655 / 10000 Epoch 24: 9653 / 10000 Epoch 25: 9658 / 10000 Epoch 26: 9653 / 10000 Epoch 27: 9664 / 10000 Epoch 28: 9655 / 10000 Epoch 29: 9672 / 10000发现,我们只是改了一个超参数,准确率就从94.76%提升到96.72%!
这里强调一下,更加规范的模型调优方法是将多个模型用交叉验证集的结果来横向比较,选出最优模型后再用一个新的测试集来最终评估该模型。本文为了与之前的结果比较,才采用了测试集而不是交叉验证集。读者千万不要学博主这样做哈,因为这很有可能会过拟合。这是工程实践中数据挖掘人员经常犯的错误,我们之后会专门写篇博文探讨。
我们现在回来继续调优我们的模型。那么还有其他的隐藏节点数更合适吗?这个我们也不知道。常见的方法是用几何级数增长的数列(如:10,100,1000,……)去尝试,然后不断确定合适的区间,最终确定一个相对最优的值。
但是即便如此,我们也只尝试了一个超参数,还有其他的超参数没有调优呢。我们于是尝试另一个超参数:步长。之前的步长是3.0,但是我们可能觉得学习速率太慢了。那么尝试一个更大的步长试试?比如100?
net = network.Network([784, 30, 10]) net.SGD(training_data, 30, 10, 100.0, test_data=test_data)发现结果如下:
Epoch 0: 1002 / 10000 Epoch 1: 1002 / 10000 Epoch 2: 1002 / 10000 Epoch 3: 1002 / 10000 Epoch 4: 1002 / 10000 Epoch 5: 1002 / 10000 Epoch 6: 1002 / 10000 Epoch 7: 1002 / 10000 Epoch 8: 1002 / 10000 Epoch 9: 1002 / 10000 Epoch 10: 1002 / 10000 Epoch 11: 1002 / 10000 Epoch 12: 1001 / 10000 Epoch 13: 1001 / 10000 Epoch 14: 1001 / 10000 Epoch 15: 1001 / 10000 Epoch 16: 1001 / 10000 Epoch 17: 1001 / 10000 Epoch 18: 1001 / 10000 Epoch 19: 1001 / 10000 Epoch 20: 1000 / 10000 Epoch 21: 1000 / 10000 Epoch 22: 999 / 10000 Epoch 23: 999 / 10000 Epoch 24: 999 / 10000 Epoch 25: 999 / 10000 Epoch 26: 999 / 10000 Epoch 27: 999 / 10000 Epoch 28: 999 / 10000 Epoch 29: 999 / 10000发现准确率低得不忍直视,看来步长设得太长了。根本跑不到最低点。那么我们设定一个小的步长试试?比如0.01。
net = network.Network([784, 100, 10]) net.SGD(training_data, 30, 10, 0.001, test_data=test_data)