之前两篇文章分别通过keras深度学习框架构建简单神经网络和卷积神经网络实现过手写数字识别实验。这篇文章分享我根据LeNet5模型构建的卷积神经网络来实现手写数字识别。
这个实验是根据LeNet5模型构建卷积神经网络,LeNet5模型的原理图如下所示:
相信大家在很多地方见过这个模型,但是实际上,很多代码里面并没有严格按照这个模型来做实验。为什么?主要是手写数字识别模型数据mnist规格是28*28,而这个LeNet5模型需要的数据输入是32*32。大家为了凑合,就私自改了这个模型的参数,最后输入变为了28*28,然后经历第一次卷积之后,特征图就变成了6@24*24 ,下采样再缩小一半:6@12*12。到了全连接层的时候,特征图就变为了16@4*4。
其实这样修改,没有什么毛病,最后也能达到实验的目的,而且训练模型之后,测试准确率可以达到98%以上。
真正要按照这个LeNet5模型就需要32*32输入形状,而现如今好像只有KNN手写数字识别那个实验好像有32*32=1024规格的训练数据集trainingDigits和测试数据集testDigits,而且那个数据量比较少,训练数据集2000个,测试数据集900多个,另一个就是它的数据是文本,要得到那个数据,还需要读文本转换。
有一个折中的办法,就是我们可以通过opencv提供的resize方法把mnist数据集的28*28形状转为32*32形状,可能就是会丢失一些精度,而现在测试数据和用来预测图片数据也一样会修改,所以精度问题可以认为抵消。
其实本身这个模型也有一些模糊的地方,就是这图里面并没有给出下采样层的具体方式,是使用最大值采样,还是平均值采样,还有卷积层的激活函数,只有细看论文才能找到答案。
所以在实现中,卷积层的激活函数一般使用tanh,但是使用relu也没有问题,同理,下采样层SubSampling这里采用MaxPool2D,AveragePooling2D都行。
简单说一下这个模型:
输入图片矩阵形状 (32,32)
第一层卷积层:6个卷积核,卷积核大小5*5,所以输出特征图(feature maps)大小就是6@(32-5+1) * (32-5+1) = 6@28*28
第二层下采样(SubSampling):2*2大小,结果就是特征图大小继续减半6@14*14
第三层卷积层:16个卷积核,卷积核大小5*5,输出特征图大小:16@(14-5+1)*(14-5+1)=16@10*10
第四层下采样:2*2大小,特征图减小一半16@5*5
第五层展平层:120个神经元
第六层全连接层:84个神经元
第七层输出层:10个神经元
下面根据mnist数据集以及LeNet5数据模型搭建神经网络并训练测试,代码如下:
from keras.models import Seque