我正在阅读《神经网络与深度学习》(前两章),并尝试按照书中的指导构建自己的ANN来对MNIST数据集中的数字进行分类。
我已经为此苦思冥想了好几天,因为我的实现经过10个epoch后,测试集数字分类的准确率仅达到约57%(约5734/10000)。训练集的准确率在第十个epoch后停滞不前,而测试集的准确率似乎因为过拟合而下降。
我使用的配置几乎与书中相同:2层前馈ANN(784-30-10),所有层完全连接;使用标准的Sigmoid激活函数;采用二次成本函数;权重初始化方式相同(从均值为0,标准差为1的高斯分布中取值)。唯一的不同之处在于我使用的是在线训练而不是批量/小批量训练,并且学习率为1.0而不是3.0(尽管我也尝试过小批量训练和3.0的学习率)。
然而,我的实现经过多个epoch后仍未能超过60%的准确率,而书中在几乎完全相同的配置下,ANN在第一个epoch后就超过了90%。起初,我在实现反向传播算法时出了问题,但经过三次不同的重新实现,每次结果都完全相同,我感到非常困惑……
反向传播算法产生的结果示例:
使用上述相同配置的更简单的前馈网络(在线训练 + 学习率为1.0):3个输入神经元,2个隐藏神经元和1个输出神经元。
初始权重初始化如下:
Layer #0 (3 neurons)Layer #1 (2 neurons) - Neuron #1: weights=[0.1, 0.15, 0.2] bias=0.25 - Neuron #2: weights=[0.3, 0.35, 0.4] bias=0.45Layer #2 (1 neuron) - Neuron #1: weights=[0.5, 0.55] bias=0.6
给定输入[0.0, 0.5, 1.0],输出为0.78900331。对于相同的输入和期望输出1.0进行反向传播,得到以下偏导数(dw = 相对于权重的导数,db = 相对于偏置的导数):
Layer #0 (3 neurons)Layer #1 (2 neurons) - Neuron #1: dw=[0, 0.0066968054, 0.013393611] db=0.013393611 - Neuron #2: dw=[0, 0.0061298212, 0.012259642] db=0.012259642Layer #2 (1 neuron) - Neuron #1: dw=[0.072069918, 0.084415339] db=0.11470326
使用这些偏导数更新网络后,得到的校正输出值为0.74862305。
如果有人能确认上述结果,对我将是极大的帮助,因为我几乎已经排除了反向传播算法有问题这一可能性。
有谁在处理MNIST问题时遇到过类似的问题吗?即使是建议我应该检查的地方也将对我有所帮助,因为我现在真的迷失了方向。
回答:
哦……
原来我的反向传播实现并没有问题……
问题出在我在C++中将图像读入到一个有符号字符数组中,导致像素值溢出,所以当我用255.0除以归一化输入向量到0.0-1.0的范围时,实际上得到了负值…… ;-;
所以我花了大约四天的时间调试和重新实现同样的东西,而问题却完全出在别的地方。