本周偷懒写LeNet-5,但是看了论文发现,LeNet-5本身网络结构设计上与现在通用的一些层结构由很大差别,比如
使用Sigmoid激活函数(这个还好)卷积之后的下采样时,逐个特征图地对池化感受野中的元素求和,再进行一次线性变换,然后在进行非线性变换,这与当前的CONV+RELU+POOL的做法顺序有区别,且池化操作也有区别天秀的CONV操作,玄学选择特征图池化径向基输出层卷积kernel size 都是5值得注意的是,LeNet中的5×5×16到120的过程实际上是卷积操作,而非全连接操作
所以我放弃写原生的LeNet-5,采用现在的网络设计方式来写LeNet-5
class NewLeNet(nn.Module): def __init__(self, num_classes=10): super(NewLeNet, self).__init__() self.conv1 = nn.Conv2d(3, 6, 5) self.conv2 = nn.Conv2d(6, 16, 5) self.conv3 = nn.Conv2d(16, 120, 5) self.fc1 = nn.Linear(120, 84) self.fc2 = nn.Linear(84, num_classes) def forward(self, x): x = F.max_pool2d(F.relu(self.conv1(x)), 2) x = F.max_pool2d(F.relu(self.conv2(x)), 2) x = F.relu(self.conv3(x)) x = x.view((x.size(0), -1)) x = F.relu(self.fc1(x)) x = self.fc2(x) return x真是so easy,在cifar 10上训练结果在测试集上acc达到75.06%,如图所示 lr=0.01,momentum=0.9,在32k和48k时分别除以10,可见ResNet的训练方法还是不错的~