上一篇文章,我们用CNN实现了手写识别
改进方案
1、 使用Keras框架,而不是用TensorFlow自己实现,提升编程效率
2、增加网络的深度,这里增加到了20层
3、每次卷积完之后,加入规范层
4、使用最新的SELU激活函数,这是Sepp Hochreiter最新发表在arXiv上的激活函数,Sepp是当年和Jürgen Schmidhuber 一起发明 LSTM 的神级人物。介绍参考这个链接:「自归一化神经网络」提出新型激活函数SELU(https://www.iana.org/domains/reserved)
理论知识补充(最小知识集)
为了避免对数据的感应不铭感,会对数据做处理,使得数据的变化范围不会太大,这个处理叫normalization预处理。Batch normalization 的 batch 是批数据, 把数据分成小批小批进行随机梯度下降. 而且在每批数据进行前向传递 forward propagation 的时候, 对每一层都进行 normalization 的处理。 优点是可以避免数据对激活函数的饱和从而收敛到更好的结果,并且能减少训练时长。
RMSprop 是 Geoff Hinton 提出的一种以梯度的平方来自适应调节学习率的优化方法。 优点是,对于常见参数更新较小,自动更新,不用手动调节学习率 缺点是,因为公式中分母上会累加梯度平方,这样在训练中持续增大的话,会使学习率非常小,甚至趋近无穷小
池化层是在几个数据中挑选出最能代表这个区域的,把一个区域简化成一个数值,可以取最大值、最小值、平均值。这样可以降低计算量,降低过拟合。
sigmoid将一个real value映射到(0,1)的区间(当然也可以是(-1,1)),这样可以用来做二分类。
而softmax把一个k维的real value向量(a1,a2,a3,a4….)映射成一个(b1,b2,b3,b4….)其中bi是一个0-1的数值,b1到bn累加为1,然后可以根据bi的大小来进行多分类的任务,如取权重最大的一维。
交叉熵计算原理是−[ylna+(1−y)ln(1−a)]。不选择MSE的原因是,使用MSE在Y取较大值时,权重和偏置的更新速度会很慢,而用交叉熵作为损失函数可以克服这个问题
代码实现
1、加载数据集,对数据集进行处理,把输入和结果进行分开
2、设相关参数
3、定义模型
4、查看模型结构,可视化模型
5、训练模型,保存和载入模型
6、生成预测结果
上传Kaggle看结果
请注意,训练是有一定随机性的,如果一次训练的不好,可以反复尝试训练。尽量准确度在99.2%以上,再生成提交结果。
kaggle结果
虽然手写识别已经有无数人做过了,但提交到Kaggle的只有1600多人,我们的结果在200多位,进入了前20%,对于新手来错,应该还可以了。
祝大家好运~~~~