人工智能的最后一次作业,搭建BP神经网络实现手写体数字识别。
数据集介绍
数据集采用著名的MNIST数据集,来自美国国家标准与技术研究所,由来自250个不同人手写的数字构成,其中50%是高中学生,50%来自人口普查局的工作人员。测试集也是同样比例的手写数字数据。
它包含了四个部分:前两个文件为训练集,后两个文件为测试集。
-数字样本 | -数字标签 |
---|---|
Training set images:train-images-idx3-ubyte.gz (包含60,000个样本) | Training set labels:train-labels-idx1-ubyte.gz (包含60,000个标签) |
Test set images: t10k-images-idx3-ubyte.gz (包含10,000个样本) | Test set labels: t10k-labels-idx1-ubyte.gz (包含10,000个标签) |
算法描述
BP神经网络是一种按误差逆传播算法训练的多层前馈网络,能学习和存贮大量的输入-输出模式映射关系,而无需事前揭示描述这种映射关系的数学方程。它的学习规则是使用梯度下降法,通过反向传播来不断调整网络的权值和阈值,使网络的误差最小,其结构包括输入层、隐藏层和输出层。
本实验中,对于每一张手写图片,我先把它处理成一个28 * 28 的01矩阵,其中1代表数字的笔画着色部分,0则代表空白。然后我们把该矩阵,扁平成一个784维的输入向量,输入到输入层。经过隐藏层到达输出层时,是一个10维的输出向量,每一位分别对应是数字0~9的可能性。通过比较输出层的实际输出与期望输出,进行反向反馈调节,并循环重复上述步骤直到达到指定迭代次数。
代码
代码并不是很长,我用c++进行实现。
BP.h文件
|
|
BP.cpp文件
|
|
算法分析
本实验中,BP神经网络中人为可调的参数就两个,一个是隐含层维度,还有一个是学习率。隐含层维度影响了程序判断的正确性,同时也影响着程序运行的时间。学习率的设置也很有讲究,过小会导致收敛过慢以及陷入局部最优,过大会使得结果发生震荡。
此外,由于BP神经网络在训练时有遗忘旧样本的趋势,所以对于60000组测试数据,我进行了反复利用,设置了迭代次数,使得正确率可以进一步提高,但也不可避免地增加了程序的运行时间。
实验结果
每一轮迭代都完整的使用了60000组训练数据,每训练10000组训练数据,就进行一次测试,取最佳准确率。
- 第几轮迭代 | - 最佳准确率 |
---|---|
1 | 92.22% |
2 | 93.64% |
3 | 94.13% |
4 | 94.47% |
5 | 94.69% |
可以发现,正确率的增长逐渐变得缓慢,程序的运行时间也要相应的加长。
可以改进的地方
由于60000组训练数据被反复训练,所以时间久了会出现过拟合现象,这可以通过画出”学习曲线”来观测,具体可以借鉴吴恩达老师的课程。解决的办法是每次随机地从60000组数据中抽取一部分进行训练,而不是60000组按顺序循环。
此外,学习率我设为了固定值,其实可以根据训练的推进逐步变小,可以达到更好的效果。