MNIST Kaggle Challenge

一、 实验背景
在日常生活中,需要手写大量的数字,在录入这些数字需耗费非常多的
时间和力气,同时还容易出现错误,因此要求设计一个手写体数字照片
智能分类程序,省去人工识别数字 0-9 的麻烦,利用 Kaggle 平台所提供
的数字照片灰度数据进行模型训练,完成该平台的 Digit Recognizer 竞
赛任务。
二、 模型结构图与流程分析
本次实验中我利用了 Keras 深度学习框架来完成该数字识别任务。
Keras 是一个支持卷积神经网路,循环神经网路的 Python 深度学习库,
能够运行在 Theano 或者 Tensorflow 上,本实验中我则是利用
Tensorflow 来进行底层的计算。 Keras 拥有相对简单的学习曲线,但是
与其他深度学习框架相比拥有较差的灵活性。
Kaggle 上的训练集与测试数据都是图片的像素信息,每一个图片都为
28x28 像素


首先读取Kaggle训练集,输入像素信息,共有28x28=784行的信息,将原始数据随机化(BP随机梯度下降),使用ReLU函数激活后,利用二维的卷积层(Conv2D,用于对图像的空间卷积),之后在每一个步长(Stride=1)进行4x4的池化,减少计算量,在进行采样和边界补零(ZeroPadding),减少边界丢失信息对模型的影响。接下来再进行第二次的模型采样和池化,同时加入Dropout函数,在每次训练时以0.1的概率随机的舍弃一些隐层单元,避免过拟合的发生。最后进入全连接层,加入Softmax函数强化特征,使得分类模型中强的特征更加强,弱的特征更加的弱,让分类能更加准确,最后输出分类结果。

  最佳准确率


 从上述截图中,可看出我训练的模型最佳准确率为98.828%,在第二次提交的时候所达成,第三次提交则是修改了池化的大小,结果造成了准确率的降低。原因估计是因为池化的大小增加所造成取样点的精准度降低才会造成准确率的下降。

 

一、     问题思考

 

1.   实验训练什么时候停止是最合适的?简要陈述你的实现方式,并试分析固定迭代次数与通过验证集调整等方法的优缺点。

答: 实验训练停止的条件有两种办法,第一种是设定一个阈值,当已训练的最大值减去本次训练的最大值大于阈值时停止训练。第二种方法是设定固定的迭代次数。我在本实验中使用的是固定迭代次数。

固定迭代次数的优点在于可以跑更多次数的历元(Epoch),能直观的判断模型的优劣,但是缺点是使用的时间较长,例如我在这次实验中一共迭代6次,每次8Epoch就花费了约40分钟的时间,但很大部分也是因为电脑运算能力和GPU运算能力差的缘故(i5-6200U,12GB RAM, AMD M5 R330 2GB)

通过验证集调整的方法的优点在于能快速选择模型,提高效率,但是不能直观的比较模型之间的缺点。

 

2.   实验参数的初始化是怎么做的?不同的方法适合哪些地方?(常见初始化方法为零均值初始化,高斯分布初始化,正交初始化等)。

答:实验参数的初始化使用的是所有权值为小的随机值。一般用均匀或正态的零均值分布来初始化线性层、卷积层的权重矩阵和偏置。而正交初始化适用于 RNN 中参数的初始化,用以解决递归网络下的梯度消失问题。

3.   过拟合是深度学习常见的问题,有什么方法可以防止训练过程陷入过拟合。

答: Batch Normalization 能提高模型的泛化能力,有效防止过拟合,避免了梯度消失,但是如果学习效率设置的不好,会导致收敛速度缓慢。另外一个方法是Dropout, 在每次训练时以一个概率随机的舍弃一些隐层单元,避免过拟合的发生。

4.   试分析CNN(卷积神经网络)相对于全连接神经网络的优点 。

答:全连接神经网路存在一个问题,当参数过多时,以数字识别为例,假设28*28的图像,隐层500个节点,则会有28*28*500+500=392,500个参数,让计算速度十分缓慢,也容易引起过拟合。而CNN相对于全连接神经网路的优点在于CNN透过局部连接,权值共享和池化来解决参数过多的问题。使用卷积层是因为卷积层本质上是在自动提取图片的特征,同时也降低了网路总体待训参数的总量,使CNN克服特征提取困难,参数过多的问题。同时透过池化,可以压缩矩阵,在模型中多加几层卷积层,用于提取更高维复杂的特征,降低计算量。

 

二、     心得体会

本次实验利用课堂上所学到的神经网路架构来完成实验。透过课堂上的三次大作业的编写让我的编程能力得到了较好的提升。最初在选用深度学习架构的时候在考虑是否要学习新的架构,例如PyTorch等,最后还是选择使用在实验室科研中有接触到的Keras来进行实验。最初在训练模型的时候,想要多训练几次使得准确率能有更好的提升,结果因电脑运算的问题导致花费非常长的时间来训练,由于是在代码中每次迭代都会储存一次,所以半路中断了训练,想说试试训练的结果,可能因为训练不完全的原因,导致模型有缺陷,才会造成第一次上传Kaggle的准确率只有10%,而相同的模型在减少训练次数及耐心等待训练完毕后,再次上传,第二次准确率就提升至98.8%,而后续的提交都是进行参数微调,来验证参数对准确率的影响,例如调整Dense层数,DropoutBN的概率,池化层的大小等。本次实验让我接触到了数据的处理,以及最基本的神经网路的运用,同时也能让我与课堂所学的内容有更好的体会。


Comments