手写数字识别实验报告
一、实验介绍
这是个分类问题,可以用传统的机器学习,例如决策树、SVM等等方法,深度学习的火热,当然是选择加入它了。
在本次实验中,本人先实现了一个lenet5的版本,而且未进行任何优化,防止过拟合等的操作,在第一次提交的时候,达到了0.97742的分数。随后了解到每个输入的像素点的值在0-255之间,进行除以255的操作后再次提交,分数达到0.98371。在下一次的提交版本中,加入了BN层以及dropout层,成绩得到了提高,0.99028。最后一次提交,将lenet5中的5\*5卷积换成了两个3\*3的卷积,采用类似VGG的改进,最终提交版本为0.99414的得分。
二、实验过程
1、数据预处理
traindata_pd = pd.read_csv("./data/train.csv")
traindata_x_np = (traindata_pd.to_numpy()[:, 1:].reshape(-1, 1, 28, 28) / 255.0 - 0.5) / 0.5
traindata_y_np = traindata_pd.to_numpy()[:, 0].astype(int)
traindata_x_t = torch.from_numpy(traindata_x_np).float()
traindata_y_t = torch.from_numpy(traindata_y_np).long()
traindata = TensorDataset(traindata_x_t, traindata_y_t)
train_size = int(0.8 * len(traindata))
valid_size = len(traindata) - train_size
# train_dataset = traindata
train_dataset, valid_dataset = torch.utils.data.random_split(traindata, [train_size, valid_size])
testdata_pd = pd.read_csv("./data/test.csv")
testdata_t = torch.from_numpy(((testdata_pd.to_numpy().reshape(-1, 1, 28, 28) / 255.0) - 0.5) / 0.5).float()
testdata = TensorDataset(testdata_t)
在第一次提交的时候,我没有进行归一化,使数据分布在-1到1之间,效果不是很好。随后我进行了正态分布归一化。进行归一化后带来了比较大的提升,可以降低梯度计算的复杂性,加快网络的收敛,还能统一量纲(例如某一特征的范围是在0到1e-6,而有的特征在0到1e6,本人专业上电路设计优化就存在这样的情况)。除此之外,还将训练集留出1/5大小作为验证集,用于评估模型好坏。
在翻阅kaggle中的NoteBook发现,别人提到了数据增强的手段,尝试使用后发现迭代速度变慢了,而且未看到明显效果,可能自己使用有误,而且对这一优化手段的代码不是很熟,最后并未使用(似乎要用上torchvision库中的transforms)。
2、模型的设计与选择
在这一环节中,由于要求使用多个baseline,在此还实现了MLP以及LSTM,CNN方面则实现了lenet5和Vgg。
(1)MLP即多层感知机,或全连接神经网络
网络结构大体如上图,是一个三层网络,在本人实验中选择的是第一个隐藏层120节点,第二个隐藏层84个节点,输出层10个节点。和lenet5最后的全连接层采用一样的结构。最终在训练集中取得了0.988的准确率,在验证集为0.979的准确率。
在进一步的探索中,我对全连接层的第一个隐藏层的节点个数进行了探索,以32到1024之间取了六种数值训练网络,看在验证集上的表现。
其中参数个数为:
$num_params=hiddensize \times 28 \times 28 +hiddensize + 84 \times hiddensize + 84 + 10 \times 84 + 10 $
即469×hiddensize+938469 \times hiddensize + 938469×hiddensize+938,对于hiddensize=128hiddensize=128hiddensize=128,num_params=60790num\_params=60790num_params=60790
准确率如下图:
可以发现,对于全连接网络增加节点数量对网络的性能提升有非常明显的影响,不过可以发现512节点与1024个时候变化并不大,也就是说并不是一味得增加节点数量就可以提高性能。个人认为,增加全连接层节点数带来性能提升的原因是,增强了拟合能力,但同时也带来了过拟合风险,但网络过于简单,最后并没继续上升,相反可能下降,而且节点数过多会使训练速度变慢。
在1024节点的时候,MLP网络达到的最大验证集准确率为0.9863。
(2)RNN循环神经网络与LSTM
RNN网络的理解花费了一定的时间。如上图,可以认为它有四个单层的神经网络,这四个神经网络一模一样,共享一样的权值,但前一个的输出会对后一个的输出有影响。在没有相互联系的情况,应该有这个单层网络是这样的输出形式:h(t)=Φ(Ux(t)+b)h^{(t)}=\Phi(Ux^{(t)}+b)h(t)=Φ(Ux(t)+b)。而RNN网络在该时刻的输出与之前的状态有关,变成了h(t)=Φ(Ux(t)+Wh(t−1)+b)h^{(t)}=\Phi(Ux^{(t)}+Wh^{(t-1)}+b)h(t)=</