软件工程第3次作业 卷积神经网络

【第二部分】代码练习

MNIST_数据集分类

数据的加载和预处理

  1. torchvision.transforms是pytorch中的图像预处理包。一般用Compose把多个步骤整合到一起:
  2. 我们可以使用 transforms.ToTensor() 将 PIL.Image/numpy.ndarray 数据进转化为torch.FloadTensor,并归一化到[0, 1.0]:
  3. Normalize用于标准化图像数据取值 .Normalize(mean, std, inplace=False) input[channel] = (input[channel] - mean[channel]) / std[channel]

image

显示训练数据

image

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

image

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,也可以不使用
image

model.train()的作用是启用 Batch Normalization 和 Dropout。

model.eval()的作用是不启用 Batch Normalization 和 Dropout。

全连接网络训练结果

image

卷积神经网络训练结果
image

但是打乱像素顺序后,全连接网络的性能基本上没有发生变化,但是 卷积神经网络的性能明显下降。

这是因为对于卷积神经网络,会利用像素的局部关系,但是打乱顺序以后,这些像素间的关系将无法得到利用。

(下图为打乱顺序后,全连接和卷积神经网络运行结果)
image

image

CIFAR10数据分类

数据图片截图

image

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

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

用VGG16进行CIFAR10分类

transform,dataloader 和之前定义的有所不同,不同之处在于训练部分的数据集增加了数据的增强,利用随机裁剪以及随机翻转,以期待增强模型的泛化能力

在训练过程中,数据分布会发生变化,对下一层网络的学习带来困难。Batch Normalization将数据拉回到均值为0,方差为1的正态分布上(归一化),一方面使得数据分布一致,另一方面避免梯度消失、梯度爆炸。

执行GitHub上代码是发现了一个小bug,这里传入的cfg需要改成self.cfg,否则会报未定义的错误
image

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

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

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

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

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

发现两者差距并不大

posted @ 2021-10-17 09:39  longTimeNoSee  阅读(98)  评论(0)    收藏  举报