软件工程第3次作业 卷积神经网络
【第二部分】代码练习
MNIST_数据集分类
数据的加载和预处理
- torchvision.transforms是pytorch中的图像预处理包。一般用Compose把多个步骤整合到一起:
- 我们可以使用 transforms.ToTensor() 将 PIL.Image/numpy.ndarray 数据进转化为torch.FloadTensor,并归一化到[0, 1.0]:
- Normalize用于标准化图像数据取值 .Normalize(mean, std, inplace=False) input[channel] = (input[channel] - mean[channel]) / std[channel]

显示训练数据

squeeze()从数组的形状中删除单维度条目,即把shape中为1的维度去掉

Softmax函数常用的用法是指定参数dim就可以:
LogSoftmax其实就是对softmax的结果进行log,即Log(Softmax(x))
log下什么都不写默认是自然对数
(1)dim=0:对每一列的所有元素进行softmax运算,并使得每一列所有元素和为1。
(2)dim=1:对每一行的所有元素进行softmax运算,并使得每一行所有元素和为1。
定义网络时,需要继承nn.Module,并实现它的forward方法,把网络中具有可学习参数的层放在构造函数init中。
只要在nn.Module的子类中定义了forward函数,backward函数就会自动被实现(利用autograd)。
-
cpu()将变量放在cpu上,仍为tensor:
-
numpy()将tensor转换为numpy:注意cuda上面的变量类型只能是tensor,不能是其他
-
GPU 上的Tensor 不能直接转换为NumPy ndarray
定义网络结构(可以用Sequential,也可以不使用

model.train()的作用是启用 Batch Normalization 和 Dropout。
model.eval()的作用是不启用 Batch Normalization 和 Dropout。
全连接网络训练结果

卷积神经网络训练结果

但是打乱像素顺序后,全连接网络的性能基本上没有发生变化,但是 卷积神经网络的性能明显下降。
这是因为对于卷积神经网络,会利用像素的局部关系,但是打乱顺序以后,这些像素间的关系将无法得到利用。
(下图为打乱顺序后,全连接和卷积神经网络运行结果)


CIFAR10数据分类
数据图片截图

全连接层是需要特征图像素量总和*通道数作为输入的

微调了神经网络的参数,最终得到了70%左右的正确率

用VGG16进行CIFAR10分类
transform,dataloader 和之前定义的有所不同,不同之处在于训练部分的数据集增加了数据的增强,利用随机裁剪以及随机翻转,以期待增强模型的泛化能力
在训练过程中,数据分布会发生变化,对下一层网络的学习带来困难。Batch Normalization将数据拉回到均值为0,方差为1的正态分布上(归一化),一方面使得数据分布一致,另一方面避免梯度消失、梯度爆炸。
执行GitHub上代码是发现了一个小bug,这里传入的cfg需要改成self.cfg,否则会报未定义的错误

需要删除掉最后的最大池化层,否则无法让全连接层的输入满足2048

略微调整了网络结构,使之与VGG16更相似,由于输入图片大小为32*32,因此我们无法使用过多的池化层,所以难以完全复现VGG16的网络结构

后来因为资源不足了(可能是挂着太久了忘记关了),被迫使用本地运行时

增加先前删除的最大池化层,并修改全连接层的输入为512,再次训练测试结果

使用全连接层输入为2048的正确率为87.38%左右

使用全连接层输入为512的正确率为87.57%左右

发现两者差距并不大

浙公网安备 33010602011771号