我这边使用的是Windows10系统,显卡是1080Ti,实际上这部分的代码实测也是可以在Linux上运行的(Ubuntu可以,CentOS没试过,不过这个代码不涉及到跨平台的问题,所以应该没问题),只是需要把各部分涉及到文件路径的地方全都改成Linux的对应路径以及格式就行了。然后我是用notepad++写的,如果是用Pycharm或者VScode的,把项目结构和路径自己搞定就行啦。
经过漫——长——地等待之后,我们的模型终于训练结束了。训练结果看下面啦:
损失函数曲线:
在测试集上的错误率曲线(%):
可以发现,损失函数基本收敛,到最后一轮损失函数值为0.010078,然后在测试集上的错误率是4.24%,这两个结果和论文上对应的结果······好吧毕竟在训练方式和数据集上有一些差距,所以结果上有点区别是很正常的。(论文上训练集损失函数值为2.5e-3,测试集错误率为5.0%,而且从曲线趋势上讲,我们的复现工作如果降低学习率再多跑几个epoch可能还能继续优化,但是实在是没必要┓( ´∀` )┏)
然后呢为了验证一下我们的模型到底行不行,我们可以从测试集里面随机挑几个数送到模型里面,看一看输出的结果和实际结果。如果还想验证一下模型的真实性能,也可以自己手写几张图片然后传输到模型里面,看看能输出个什么鬼东西。如果要自己手写几张图片传输到模型里面,那需要注意下面的几个问题:
自己拍摄或者是在画图里面画的图片,实际上是三通道的RGB图片,而模型接收的参数是单通道的灰度图,所以你需要用PIL库把图片转化为单通道灰度图,相关的方法可以百度一下啦(convert('L'),搜这个函数哟)
你可以从MNIST的数据集里面随便找出一个输出一下,发现里面所有的图片都是黑底白字的,你可以尝试一下如果你把自己写的白底黑字的灰度图传进去,基本正确率是0吧(大概只有0,1,8能够正确识别出来)。所以要想正确的得到识别结果,你需要把上一步转化的白底黑字的灰度图转化成黑底白字的灰度图,具体做法你可以先将PIL图(假设变量名为image)转化为numpy数组,用255 - image之后(numpy的广播操作),再转回成PIL图,这样就是黑底白字了(别问我为啥知道要这么搞,问就是这坑我掉进去过)