小白经典CNN论文复现系列(一):LeNet1989 (2)

H2层:同样的,这里是由5 x 5的卷积核以及对应的偏置进行特征图的计算,输入的图片的尺寸是之前的H1层的[12, 8, 8],卷积核会将这个输入数据输出成[12, 4, 4]的尺寸。然后这里就出现了和上面一层同样的问题,他没给说明使用的stride和padding是多少,而且有无穷多组解······真的看到这里我已经打算放弃复现这个论文了,但是,没办法毕竟都看到这里了,自己作的死,跪着也要作完TAT。这里选取的参数也是stride = (2,2),padding = (2,2),大家可以计算一下,这个和给出的那个尺寸是一致的。并且这里和LeNet-5一样,用到了一个比较特别的计算方式,当我们计算特征图的时候,并没有直接拿所有的H1层的输出作为输入,而是每一次都从那12个特征图中调出8个来进行计算,但是,理由并没有说,而且很可气的就是里面有一句话

···according a scheme that will not be described here.
"我知道,但我就是不说,气不气"

我感觉我撕了论文的心都有了······,所以这里我们不理他,就直接用正常的卷积来做,反正相关的东西在后面的LeNet-5里面也有说到底怎么选,这里就先这样。

H3层:到这一层卷积结束,进入到全连接层的范围。由于我们的输入特征图的尺寸是[12, 4, 4],将这个图片转换成向量以后的维度是12 x 4 x 4 = 192,并且要求输出的尺寸是30,因此这里的线性层的尺寸是192 x 30

output层:在这一层要进行分类输出啦,所以我们的线性层理所当然的是30 x 10

网络结构就是这些啦,是不是很简单?而且和之后的LeNet-5也是很像呢。其实这篇文章我是觉得,如果他能把里面的一些东西说得更加清楚的话,其实蛮适合初学者进行复现的,然而就是因为一大堆东西没有说清楚,结果整出了一个月球表面来,到处都是坑。

训练相关参数部分:

在关于模型的训练上,主要有以下几件事需要注意:

使用的基本思路是随机梯度下降(SGD),注意这里的SGD不是那种有mini-batch的,而是就真的每次就使用一个样本进行参数的更新,这也是为什么之前我在说图片尺寸的时候让大家先不要考虑batch_size的问题,因为这个是1。

关于更新方法的问题,在这篇论文里面使用的是二阶精度的方法,具体的更新算法在LeCun的《Improving the Convergence of Back-Propagation Learning with Second-Order Methods》中有介绍,实际上就是对BFGS算法进行了一些改进,大家有兴趣可以看一下这篇文章。但是,实际上在后来的LeNet-5的这篇文章中,LeCun指出,在这种较大数据量的训练上面,用二阶方法的人都是吃饱了没事干的铁憨憨(我骂我自己.jpg),所以在这篇复现里面,我们就采用一阶方法的SGD。

使用的损失函数为MSELoss,但是这部分我没看懂他说的输出部分用place coding是个啥······所以这个部分我就假设他用的是one-hot编码啦,如果评论区有大佬能够指点一下这个place coding到底是啥的话,我到时候再抽时间把这个部分重新搞一下。

训练代数为23,因为原文使用的参数更新方法是二阶方法所以不用人为设置学习率(这一部分在2017年的CS231n中是有说明的,建议大家直接去看一下网课),但是我们这里用的是一阶的方法,所以需要设置学习率,并且训练代数也要相对地增加一些,因为一阶方法的收敛毕竟还是相对较慢。

各部分代码简析

我们先把需要用到的模块啥的全都搞到一起吧

import torch import torch.nn as nn import torch.optim as optim from torchvision import datasets from torchvision import transforms as T from torch.utils.data import DataLoader import matplotlib.pyplot as plt

首先是关于数据的处理部分。相关的内容在我的浙大AI作业系列的口罩识别部分有详细说明,在这里就不具体解释原理了,直接贴代码

picProcessor = T.Compose([ T.Resize((16, 16)), #图片尺寸的重整 T.ToTensor(), #将图片转化为像素值为[0, 1]的tensor T.Normalize( mean = [0.5], std = [0.5] ), #将图片的数据范围从[0, 1]转换为[-1, 1] ])

有了这个图片的转换器之后,我们要加载一下我们的数据集,并且用这个转换器进行图片的处理。由于Pytorch提供了自己的MNIST数据的加载方式,因此我们在这里直接就用Pytorch提供的方法就好了。

dataPath = "F:\\Code_Set\\Python\\PaperExp\\DataSetForPaper\\" #在使用的时候请改成自己实际的MNIST数据集路径 mnistTrain = datasets.MNIST(dataPath, train = True, download = False, transform = picProcessor) #如果是第一次加载,请将download设置为True mnistTest = datasets.MNIST(dataPath, train = False, download = False, transform = picProcessor)

详细的关于datasets.MNIST的使用方法,建议大家查一下官方文档以及自行百度,这里就不多做解释了。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpssyw.html