使用Res-Net-18进行CIF-10分类实验

 一、普通卷积神经网络的设计和实验

1.1 加载和预处理数据

使用tf.keras.datasets.cifar10加载CIFAR-10数据集。

对训练和测试数据进行归一化处理,将像素值从[0, 255]缩放到[0, 1]。

1.2. 构建CNN模型

使用tf.keras.Sequential创建顺序模型。

特征提取阶段

第一层:包含两个卷积层,每个卷积层有16个3x3的卷积核,使用ReLU激活函数。然后是一个2x2的最大池化层。

第二层:包含两个卷积层,每个卷积层有32个3x3的卷积核,同样使用ReLU激活函数。然后是一个2x2的最大池化层。

分类识别阶段

第三层:Flatten层将多维特征图展平为一维向量。

第四层:一个全连接层(Dense层),有128个神经元,使用ReLU激活函数。

输出层:一个全连接层,有10个神经元对应10个类别,使用softmax激活函数。

1.3. 配置模型训练方法

使用Adam优化器,这是Keras默认的优化器之一。

损失函数使用sparse_categorical_crossentropy,适用于多分类问题。

准确率使用sparse_categorical_accuracy。

1.4. 训练模型

设置批量大小为64,训练5个epoch,并使用20%的数据作为验证集。

1.5. 评估模型

在测试集上评估模型的性能。

1.6. 保存模型

将训练好的模型权重保存到文件CIFAR10_CNN_weights.h5(这个可以自己选择位置)。

1.7. 结果可视化

绘制训练和测试的损失以及准确率曲线。

1.8. 使用模型进行预测

随机选择测试集中的图像,使用训练好的模型进行预测,并显示原始标签和预测标签。

设计考虑:

卷积层:使用了两个卷积层,每个卷积层后跟一个ReLU激活函数,有助于提取图像特征并引入非线性。

池化层:最大池化用于降低特征的空间维度,减少参数数量,同时保留重要特征。

全连接层:在卷积和池化层之后,使用全连接层来进行分类。

激活函数:ReLU用于隐藏层,softmax用于输出层,分别用于引入非线性和进行多类别概率估计。

损失函数和优化器:稀疏交叉熵损失函数适用于多分类问题,Adam优化器因其自适应学习率而广泛使用。

总结:这个普通CNN使用了两个卷积层和池化层,最后是全连接层。普通CNN的结构简单,易于理解和实现,但是它的准确较低,泛化能力差,有过拟合的风险。使用这个模型在电脑上运行,当迭代次数为5时(测试出的最有次数)是需要20秒左右,准确率为67%。

参考文献(里面附有普通CNN实验的完整代码,本文的CNN结构也是按照这个代码写的):【神经网络与深度学习】CIFAR10数据集介绍,并使用卷积神经网络训练图像分类模型——[附完整训练代码]_cifar-10-CSDN博客

 二、使用残差网络优化后进行分类实验

2.1.残差网络相较于传统网络优势优势

2.1.1.残差学习

ResNet的核心思想是让网络中的每个残差块(Residual Block)学习输入和输出之间的残差(即差异),而不是直接学习映射。这意味着网络的每个部分只需要在现有层的基础上进行微调,而不是从头开始学习整个映射

2.1.2.恒等映射

在残差块中,如果输入和输出相同,那么网络可以简单地通过恒等映射(即直接将输入复制到输出)来实现,而不需要学习任何复杂的变换。这使得网络可以更容易地学习到恒等函数,从而避免了梯度消失或爆炸的问题。

2.1.3.深层网络

由于残差学习框架的引入,ResNet可以构建非常深的网络结构(例如,100层或更深),而不会遭受传统深层网络中的退化问题。这使得网络能够学习到更复杂的特征表示,从而提高性能。

2.1.4.退化问题解决

在传统的深度神经网络中,随着层数的增加,梯度可能会消失或爆炸,导致网络难以训练。ResNet通过残差连接(Skip Connection)直接连接前面的层和后面的层,有效地解决了这个问题

参考文献:ResNet-18超详细介绍!!!!_resnet18-CSDN博客


2.2读取图片和标签

trainloader = torch.utils.data.DataLoader(trainset, batch_size=BATCH_SIZE, shuffle=True, num_workers=2)

使用torchvision.datasets.CIFAR10加载CIFAR-10数据集,并使用之前定义的变换

DataLoader: 接受一个数据集对象(这里是 trainset),以及一些参数来控制数据加载的行为。

batch_size: 定义了每个批次中的样本数量

Shuffle: 决定是否在每个epoch开始时打乱数据。这有助于模型训练时的泛化能力

num_workers: 定义了用于数据加载的工作进程数量。使用多进程加载数据可以加快数据读取速度

使用torch.utils.data.DataLoader创建数据加载器,它支持批量加载、打乱数据和多线程加载

2.3.数据增强

transforms.RandomCrop(32, padding=4),  #先四周填充0,在把图像随机裁剪成32*32

transforms.RandomHorizontalFlip(),  #图像一半的概率翻转,一半的概率不翻转
数据在增强后使模型具有更好的泛化能力

2.4.优化方式

定义损失函数和优化方式

criterion = nn.CrossEntropyLoss()  #损失函数为交叉熵,多用于多分类问题

optimizer = optim.SGD(net.parameters(), lr=LR, momentum=0.9, weight_decay=5e-4)

net.parameters():  这是模型(net)的参数集合。在PyTorch中,每个神经网络模型都可以通过.parameters()方法获得其所有可训练参数。这些参数将被优化器用于计算梯度和更新权重

lr=LR:  lr代表学习率(Learning Rate),LR是学习率的具体数值。学习率是优化算法中一个非常重要的超参数,它决定了在每次迭代中更新模型权重时所采用的步长。如果学习率过大,可能会导致训练过程中的震荡甚至发散;如果学习率过小,训练过程可能会非常缓慢

momentum=0.9:  momentum是动量(Momentum)参数,这里的0.9表示动量的数值。动量是一种加速SGD算法的技术,它可以帮助梯度下降算法更快地收敛,同时减轻震荡。动量方法通过在连续的迭代中累加一定比例的梯度来实现,这有助于克服小的局部最小值,并加速通过平坦区域

weight_decay=5e-4:  weight_decay是权重衰减(Weight Decay)参数,这里的5e-4表示衰减的强度。权重衰减是一种正则化技术,用于防止模型过拟合。它通过在损失函数中添加一个与权重大小成比例的惩罚项来实现,鼓励模型学习到较小的权重值

2.5参数调整


2.5.1超参数调整


对学习率:原学习率为0.1,在调整为0.05或者0.01后,损失函数下降更快,意味着模型能够迅速适应训练数据,学习到数据中的模式,但是在90成功率以上后进步缓慢,在同样的120个epoch下,原学习率有95%的成功率,降低学习率后只有91%的成功率,猜测是由于学习率过小陷入了局部最优解。

对数据增强的方式调整:删去了图片有一半概率翻转的函数,在经过多轮训练后,效果不如保留数据增强的效果好。

对BATCH_SIZE的调整:从128调整1024,相同epoch下,最终成功率有所下降,猜测较小的BATCH_SIZE通常会产生更嘈杂的梯度估计,但有助于模型探索参数空间。较大的BATCH_SIZE可能提供更稳定的梯度估计,但也可能使模型陷入局部最优解,从而影响泛化能力。

2.5.2内部参数调整


在ResNet18神经网络内部尝试加上原本的池化层并且采用原本的7*7卷积,发现效果其实和原来差不多,并且这个参数调整要求高,很容易造成图片输出尺寸过小,建议参考相应公式进行调整。

卷积层输出特征图(feature map)的尺寸可以通过以下公式计算:

Output Size=⌊(Input Size+2×Padding−Kernel Size)/  Stride​⌋+1

其中:

Input Size: 是输入特征图的尺寸(对于第一层是原始图片的尺寸)

Padding: 是边缘填充的大小,通常用于保持特征图尺寸或实现特定的边界效应

Kernel Size: 是卷积核(或滤波器)的尺寸,常见的卷积核尺寸有3x3、5x5等

Stride: 是卷积核移动的步长,步长为1表示每次移动一个像素,步长为2表示每次移动两个像素。

注意,上述公式中的 ⌊⋅⌋ 表示向下取整,因为输出尺寸必须是整数。

此外,如果卷积层后接有池化层(如最大池化或平均池化),则池化层的尺寸也会对输出特征图的尺寸产生影响。池化层的尺寸计算公式类似:

 Output Size=⌊(Input Size −Kernel Size)/Stride​⌋+1

其中,Kernel Size 和 Stride 分别是池化核的尺寸和步长,Input Size:是输入特征图的尺寸。

通过这些公式,你可以计算出卷积神经网络中任何层的输出尺寸。

三、问题


无论是对超参数的调整(批次,学习率,优化函数等)还是对内部网络结构的简单调整都会出现一个问题,就是在测试集准确率到达80以前训练集的准确率和测试集差不多,但是在80以后两者经常相差7%到10%,同时测试集准确率提升缓慢,可见存在过拟合问题,不过经过多轮训练以后准确率还是能上90也说明了残差网络的优势,不会像普通CNN那样在某个轮次后再也上不去,你们也可以尝试一下调整一下超参数或者修改内部网络结构看看能不能取得更高的准确率。

参考文献(包括残差网络进行图片分类实验代码):
Pytorch实战2:ResNet-18实现Cifar-10图像分类(测试集分类准确率95.170%)_resnet18 cifar10-CSDN博客

  • 15
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值