第一部分 代码练习
part 1
目标:MNIST 数据集分类(构建简单的CNN对 mnist 数据集进行分类,同时在实验中学习池化与卷积操作的基本作用。)
实验中将对数据集中的部分图像和打乱像素顺序后的图像,分别在不同的网络上进行训练和测试,得出相应的测试结果并进行对比分析。具体操作如下:
加载数据:
PyTorch里包含了 MNIST, CIFAR10 等常用数据集,调用 torchvision.datasets 即可把这些数据由远程下载到本地,并显示出来。
![](https://i-blog.csdnimg.cn/blog_migrate/a0b6dac6af080a565e490e34ccb41a7d.png)
创建网络并定义训练和测试函数:
创建网络需要继承nn.Module,并实现它的forward方法,是直接使用Sequential 就定义了网络。以下创建的是全连接网络和卷积神经网络,它们的创建方法不同之处体现在nn.Module的子类中的forward函数(forward 函数的作用是指定网络的运行过程,相比于全连接网络,卷积神经网络就显得复杂得多,在后续测试效果中也更加优秀)
训练函数是从train_loader里的64个样本中以一个batch为单位提取样本数据并送往GPU中进行训练。
测试函数把数据送入模型得到计算结果并计算损失
![](https://i-blog.csdnimg.cn/blog_migrate/064fb17e31e0482736bc63f291e2e367.jpeg)
可以看到卷积神经网络凭借着优良的卷积和池化特性,在像素有序的情况下展现出不错的特性,卷积神经网络采用原始图像作为输入,会利用像素的局部关系,可以有效的从大量样本中学习到相应地特征,避免了复杂的特征提取过程,就可以过滤出有用的信息。
打乱像素顺序在两个网络上重新训练和测试:
考虑到CNN在卷积与池化上的优良特性,如果我们把图像中的像素打乱顺序,这样 卷积 和 池化 就难以发挥作用了,为了验证这个想法,我们把图像中的像素打乱顺序再试试。
![](https://i-blog.csdnimg.cn/blog_migrate/b45535dd2a6bb7d043943037c2c82502.png)
![](https://i-blog.csdnimg.cn/blog_migrate/a13bdf8cc1a3e866f8d9ceec76e68c9a.jpeg)
可以看出小型全连接网络的优势在于处理多样化的数据具有稳定性,这是卷积神经网络所不具备的,在打乱顺序以后,这些像素间的关系将无法得到利用。
part 2
CIFAR10 数据集分类:使用 CNN 对 CIFAR10 数据集进行分类
加载CIFAR10数据集(它包含十个类别:‘airplane’, ‘automobile’, ‘bird’, ‘cat’, ‘deer’, ‘dog’, ‘frog’, ‘horse’, ‘ship’, ‘truck’)并展示数据集图片。
![](https://i-blog.csdnimg.cn/blog_migrate/126c635aaf5347d62fad7b6accc001fa.png)
定义网络,损失函数和优化器及训练函数:
for epoch in range(10): # 重复多轮训练
for i, (inputs, labels) in enumerate(trainloader):
inputs = inputs.to(device)
labels = labels.to(device)
# 优化器梯度归零
optimizer.zero_grad()
# 正向传播 + 反向传播 + 优化
outputs = net(inputs)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
# 输出统计信息
if i % 100 == 0:
print('Epoch: %d Minibatch: %5d loss: %.3f' %(epoch + 1, i + 1, loss.item()))
print('Finished Training')
训练网络:
Epoch: 1 Minibatch: 1 loss: 2.305
Epoch: 1 Minibatch: 101 loss: 1.753
Epoch: 1 Minibatch: 201 loss: 1.809
Epoch: 1 Minibatch: 301 loss: 1.780
Epoch: 1 Minibatch: 401 loss: 1.485
Epoch: 1 Minibatch: 501 loss: 1.579
Epoch: 1 Minibatch: 601 loss: 1.651
Epoch: 1 Minibatch: 701 loss: 1.240
Epoch: 2 Minibatch: 1 loss: 1.545
Epoch: 2 Minibatch: 101 loss: 1.365
Epoch: 2 Minibatch: 201 loss: 1.455
Epoch: 2 Minibatch: 301 loss: 1.714
Epoch: 2 Minibatch: 401 loss: 1.269
Epoch: 2 Minibatch: 501 loss: 1.406
Epoch: 2 Minibatch: 601 loss: 1.195
Epoch: 2 Minibatch: 701 loss: 1.125
Epoch: 3 Minibatch: 1 loss: 1.235
Epoch: 3 Minibatch: 101 loss: 1.414
Epoch: 3 Minibatch: 201 loss: 1.289
Epoch: 3 Minibatch: 301 loss: 1.291
Epoch: 3 Minibatch: 401 loss: 1.227
Epoch: 3 Minibatch: 501 loss: 1.268
Epoch: 3 Minibatch: 601 loss: 1.167
Epoch: 3 Minibatch: 701 loss: 1.327
Epoch: 4 Minibatch: 1 loss: 1.311
Epoch: 4 Minibatch: 101 loss: 0.931
Epoch: 4 Minibatch: 201 loss: 1.090
Epoch: 4 Minibatch: 301 loss: 1.204
Epoch: 4 Minibatch: 401 loss: 0.848
Epoch: 4 Minibatch: 501 loss: 1.120
Epoch: 4 Minibatch: 601 loss: 1.054
Epoch: 4 Minibatch: 701 loss: 0.968
Epoch: 5 Minibatch: 1 loss: 0.871
Epoch: 5 Minibatch: 101 loss: 1.101
Epoch: 5 Minibatch: 201 loss: 1.188
Epoch: 5 Minibatch: 301 loss: 0.882
Epoch: 5 Minibatch: 401 loss: 0.821
Epoch: 5 Minibatch: 501 loss: 0.995
Epoch: 5 Minibatch: 601 loss: 0.916
Epoch: 5 Minibatch: 701 loss: 0.904
Epoch: 6 Minibatch: 1 loss: 1.051
Epoch: 6 Minibatch: 101 loss: 1.273
Epoch: 6 Minibatch: 201 loss: 0.997
Epoch: 6 Minibatch: 301 loss: 1.089
Epoch: 6 Minibatch: 401 loss: 1.002
Epoch: 6 Minibatch: 501 loss: 1.189
Epoch: 6 Minibatch: 601 loss: 0.992
Epoch: 6 Minibatch: 701 loss: 0.909
Epoch: 7 Minibatch: 1 loss: 1.076
Epoch: 7 Minibatch: 101 loss: 0.740
Epoch: 7 Minibatch: 201 loss: 0.970
Epoch: 7 Minibatch: 301 loss: 0.876
Epoch: 7 Minibatch: 401 loss: 0.857
Epoch: 7 Minibatch: 501 loss: 1.033
Epoch: 7 Minibatch: 601 loss: 0.869
Epoch: 7 Minibatch: 701 loss: 1.067
Epoch: 8 Minibatch: 1 loss: 0.966
Epoch: 8 Minibatch: 101 loss: 0.906
Epoch: 8 Minibatch: 201 loss: 0.771
Epoch: 8 Minibatch: 301 loss: 1.173
Epoch: 8 Minibatch: 401 loss: 0.948
Epoch: 8 Minibatch: 501 loss: 0.763
Epoch: 8 Minibatch: 601 loss: 0.760
Epoch: 8 Minibatch: 701 loss: 1.194
Epoch: 9 Minibatch: 1 loss: 1.156
Epoch: 9 Minibatch: 101 loss: 0.864
Epoch: 9 Minibatch: 201 loss: 1.044
Epoch: 9 Minibatch: 301 loss: 0.805
Epoch: 9 Minibatch: 401 loss: 0.789
Epoch: 9 Minibatch: 501 loss: 0.951
Epoch: 9 Minibatch: 601 loss: 0.895
Epoch: 9 Minibatch: 701 loss: 0.886
Epoch: 10 Minibatch: 1 loss: 1.012
Epoch: 10 Minibatch: 101 loss: 0.753
Epoch: 10 Minibatch: 201 loss: 0.989
Epoch: 10 Minibatch: 301 loss: 0.848
Epoch: 10 Minibatch: 401 loss: 0.658
Epoch: 10 Minibatch: 501 loss: 0.903
Epoch: 10 Minibatch: 601 loss: 0.977
Epoch: 10 Minibatch: 701 loss: 0.648
Finished Training
下面将一组图像进行识别并及进行预测,可以发现存在着些许错误
在整个数据集上,识别出的准确率为62%,还需进行优化。
part 3
使用 VGG16 对 上述CIFAR10 分类优化:
定义VGG函数。
这里发现出现几处错误:
self._make_layers(cfg)中的参数cfg未定义,这里应该是打印错误,应改为self._make_layers(self.cfg)
此处出现输入参数和输出参数不匹配的情况,为了提高运算速度,并解决问题,将数据修改如下
使用相同的训练函数,得到结果准确率为80.83%,最终准确率与为优化之前比较提升18%
优化后虽然准确率得到明显提升,但是运算速度却大幅下降,在这里速度和准确率二者不可得兼,还需要其他方法来优化算法。
第二部分 问题总结
dataloader 里面 shuffle 取不同值有什么区别?
DataLoader中的shuffer=False表示不打乱数据的顺序,然后以batch为单位从头到尾按顺序取用数据。shuffer=Ture表示在每一次epoch中都打乱所有数据的顺序,然后以batch为单位从头到尾按顺序取用数据。这样的结果就是不同epoch中的数据都是乱序的。
transform 里,取了不同值,这个有什么区别?
将tansform中数据改变后会发现图像曝光都不一样,数值越小图片越亮。
epoch 和 batch 的区别?
Epoch(批次)是指将整个数据集迭代一遍的过程。 在一个 Epoch 中,模型会对整个数据集进行一次前向传播和反向传播,更新所有的参数。
而Batch(批量)是指为了加速训练而将大规模数据划分成小批次数据的过程
1x1的卷积和 FC 有什么区别?主要起什么作用?
FC等价于一个卷积核是全图大小的卷积,而卷积相当于是一个局部区域的全连接。
residual leanring 为什么能够提升准确率?
它通过使用残差连接来解决深层网络中的梯度消失问题,从而提高网络的准确性和训练速度
代码练习二里,网络和1989年 Lecun 提出的 LeNet 有什么区别?
LeNet有五层模型,处理一个28×28 的灰度图像,先经过一个卷积层,生成 4 通道的 feature map;再进行池化降维,然后通过卷积层,得到 12 通道的 feature map。再次池化之后,用全连接层提取特征。
我观察到练习二中的网络和LeNet 有的区别在于nn.Module的子类中的forward函数中函数体实现不同,具体如下:
![](https://i-blog.csdnimg.cn/blog_migrate/a52f3737880c64c52cb1462f94aef0a8.jpeg)
另外还有池化层有所不同,LeNet采用均值池化(average pooling)和练习二采用最大池化(max pooling),前者计算出一个区域的均值,后者从区域中取最大值。
代码练习二里,卷积以后feature map 尺寸会变小,如何应用 Residual Learning?
有上述问题知道Residual Learning是通过使用残差连接解决深层网络中的梯度消失问题来提高网络的准确性和训练速度的,所以需要将feature map 尺寸还原继续制造残差,经查阅资料,可以使用padding,变换就可以使得卷积之后size不变
有什么方法可以进一步提升准确率?
1、用上述residual leanring方法,采用更深的网络
2、优化激活函数和损失函数
3、在对速度要求不高的情况下,可以牺牲部分运算速度,来提高准确率