实验六 卷积神经网络(5)使用预训练resnet18实现CIFAR-10分类

5.5 实践:基于ResNet18网络完成图像分类任务

在本实践中,我们实践一个更通用的图像分类任务。

图像分类(Image Classification)是计算机视觉中的一个基础任务,将图像的语义将不同图像划分到不同类别。很多任务也可以转换为图像分类任务。比如人脸检测就是判断一个区域内是否有人脸,可以看作一个二分类的图像分类任务。

这里,我们使用的计算机视觉领域的经典数据集:CIFAR-10数据集,网络为ResNet18模型,损失函数为交叉熵损失,优化器为Adam优化器,评价指标为准确率。

5.5.1 数据处理

5.5.1.1 数据集介绍

CIFAR-10数据集包含了10种不同的类别、共60,000张图像,其中每个类别的图像都是6000张,图像大小均为32×32像素。CIFAR-10数据集的示例如 图5.15 所示。
hhh

5.5.1.2 数据读取

cifar-10 数据集由 60000 张分辨率为 32x32 彩色图像组成,共分为 10 类,每类包含 6000 张图像,cifar-10 数据集有 50000 个训练图像和 10000 个测试图像。
最终的数据集构成为:

  • 训练集:50 000条样本。
  • 验证集:10 000条样本。
  • 测试集:10 000条样本。
    读取一个batch数据的代码如下所示:
import torch
from torchvision.transforms import transforms
import torchvision
from torch.utils.data import DataLoader
 
transformer=transforms.Compose([transforms.ToTensor(),
                               transforms.Normalize(mean=[0.4914, 0.4822, 0.4465], std=[0.2023, 0.1994, 0.2010])])
 
trainset = torchvision.datasets.CIFAR10(root='./cifar10', train=True, download=True, transform=transformer)
devset=torchvision.datasets.CIFAR10(root='./cifar10',train=False,download=True,transform=transformer)
testset=torchvision.datasets.CIFAR10(root='./cifar10',train=False,download=True,transform=transformer)
 
classes = ('plane', 'car', 'bird', 'cat',
           'deer', 'dog', 'frog', 'horse', 'ship', 'truck')

可视化观察其中的一张样本图像和对应的标签,代码如下所示:

image,label=trainset[0]
print(image.size())
image, label = np.array(image), int(label)
plt.imshow(image.transpose(1,2,0))
plt.show()
 
print(classes[label])

运行结果:

torch.Size([3, 32, 32])
frog

1

5.5.2 模型构建

使用torchvision API中的Resnet18进行图像分类实验。

from torchvision.models import resnet18
 
resnet18_model = resnet18(pretrained=True)

Pytorch 提供 torchvision.models 接口,里面包含了一些常用用的网络结构,并提供了预训练模型,可以通过简单调用来读取网络结构和预训练模型。

1. 什么是“预训练模型”?什么是“迁移学习”?

预训练模型

预训练模型是深度学习架构,已经过训练以执行大量数据上的特定任务(例如,识别图片中的分类问题)。这种训练不容易执行,并且通常需要大量资源,超出许多可用于深度学习模型的人可用的资源,我就没有大批次GPU。在谈论预训练模型时,通常指的是在Imagenet上训练的CNN(用于视觉相关任务的架构)。ImageNet数据集包含超过1400万个图像,其中120万个图像分为1000个类别(大约100万个图像含边界框和注释)。

迁移学习

迁移学习是一种机器学习技术,顾名思义就是指将知识从一个领域迁移到另一个领域的能力。
我们知道,神经网络需要用数据来训练,它从数据中获得信息,进而把它们转换成相应的权重。这些权重能够被提取出来,迁移到其他的神经网络中,我们"迁移"了这些学来的特征,就不需要从零开始训练一个神经网络了 。

为什么我们要做预训练模型?

首先,预训练模型是一种迁移学习的应用,利用几乎无限的文本,学习输入句子的每一个成员的上下文相关的表示,它隐式地学习到了通用的语法语义知识。
第二,它可以将从开放领域学到的知识迁移到下游任务,以改善低资源任务,对低资源语言处理也非常有利。
第三,预训练模型在几乎所有NLP任务中都取得了目前最佳的成果。
最后,这个预训练模型+微调机制具备很好的可扩展性,在支持一个新任务时,只需要利用该任务的标注数据进行微调即可,一般工程师就可以实现。

2. 比较“使用预训练模型”和“不使用预训练模型”的效果。

resnet = models.resnet18(pretrained=True)
resnet = models.resnet18(pretrained=False)
pytorch学习笔记之加载预训练模型_AI算法札记的博客-CSDN博客_pytorch加载预训练模型

5.5.3 模型训练

复用RunnerV3类,实例化RunnerV3类,并传入训练配置。
使用训练集和验证集进行模型训练,共训练30个epoch。
在实验中,保存准确率最高的模型作为最佳模型。代码实现如下:

import torch.nn.functional as F
import torch.optim as opt
from Runner import RunnerV3
from metric import Accuracy
 
#指定运行设备
torch.cuda.set_device('cuda:0')
 
# 学习率大小
lr = 0.001
# 批次大小
batch_size = 64
# 加载数据
train_loader = DataLoader(trainset, batch_size=batch_size, shuffle=True)
dev_loader = DataLoader(devset, batch_size=batch_size)
test_loader = DataLoader(testset, batch_size=batch_size)
# 定义网络
model = resnet18_model
# 定义优化器,这里使用Adam优化器以及l2正则化策略,相关内容在7.3.3.2和7.6.2中会进行详细介绍
optimizer = opt.Adam(lr=lr, params=model.parameters(), weight_decay=0.005)
# 定义损失函数
loss_fn = F.cross_entropy
# 定义评价指标
metric = Accuracy(is_logist=True)
# 实例化RunnerV3
runner = RunnerV3(model, optimizer, loss_fn, metric)
# 启动训练
log_steps = 3000
eval_steps = 3000
runner.train(train_loader, dev_loader, num_epochs=30, log_steps=log_steps,
             eval_steps=eval_steps, save_path="best_model.pdparams")

运行结果:

[Train] epoch: 0/30, step: 0/23460, loss: 14.40919
[Train] epoch: 3/30, step: 3000/23460, loss: 0.77919
[Evaluate]  dev score: 0.69040, dev loss: 0.92100
[Evaluate] best accuracy performence has been updated: 0.00000 --> 0.69040
[Train] epoch: 7/30, step: 6000/23460, loss: 0.64090
[Evaluate]  dev score: 0.72860, dev loss: 0.83435
[Evaluate] best accuracy performence has been updated: 0.69040 --> 0.72860
[Train] epoch: 11/30, step: 9000/23460, loss: 0.72482
[Evaluate]  dev score: 0.73170, dev loss: 0.80458
[Evaluate] best accuracy performence has been updated: 0.72860 --> 0.73170[Train] epoch: 15/30, step: 12000/23460, loss: 0.76655
[Evaluate]  dev score: 0.72200, dev loss: 0.83292
[Train] epoch: 19/30, step: 15000/23460, loss: 0.44270[Evaluate]  dev score: 0.74660, dev loss: 0.77437
[Evaluate] best accuracy performence has been updated: 0.73170 --> 0.74660
[Train] epoch: 23/30, step: 18000/23460, loss: 0.60689
[Evaluate]  dev score: 0.73190, dev loss: 0.79955
[Train] epoch: 26/30, step: 21000/23460, loss: 0.64202
[Evaluate]  dev score: 0.75310, dev loss: 0.74181
[Evaluate] best accuracy performence has been updated: 0.74660 --> 0.75310
[Evaluate]  dev score: 0.71180, dev loss: 0.88972
[Train] Training done!

额,这个模型用的时间好长。。。可能是有一点点复杂吧

5.5.4 模型评价

使用测试数据对在训练过程中保存的最佳模型进行评价,观察模型在测试集上的准确率以及损失情况。代码实现如下:

# 加载最优模型
runner.load_model('best_model.pdparams')
# 模型评价
score, loss = runner.evaluate(test_loader)
print("[Test] accuracy/loss: {:.4f}/{:.4f}".format(score, loss))

运行结果:

[Test] accuracy/loss: 0.7270/1.8212

5.5.5 模型预测

同样地,也可以使用保存好的模型,对测试集中的数据进行模型预测,观察模型效果,具体代码实现如下:

#获取测试集中的一个batch的数据
for X, label in test_loader:
 
    logits = runner.predict(X)
    #多分类,使用softmax计算预测概率
    pred = F.softmax(logits)
    #获取概率最大的类别
    pred_class = torch.argmax(pred[2]).numpy()
    label = label[2].data.numpy()
    #输出真实类别与预测类别
    print("The true category is {} and the predicted category is {}".format(classes[label], classes[pred_class]))
    #可视化图片
    X=np.array(X)
    X=X[1]
    plt.imshow(X.transpose(1, 2, 0))
    plt.show()
    break

运行结果:

The true category is 8 and the predicted category is 8

用自己的话简单评价:LeNet、AlexNet、VGG、GoogLeNet、ResNet

LeNet
手写体数字识别模型,是一个广为人知的商用的卷积神经网络, 当年美国大多数银行用它来识别支票上面的手写数字。Lenet-5 原始结构如下图所示,包括:卷积层,降采样,卷积层,降采样,卷积层(实现全连接),全连接层,高斯连接层(进行分类)。
1
LeNet特点:

(1)每个卷积层包含三个部分:卷积、池化和非线性激活函数
(2)使用卷积提取空间特征
(3)降采样(Subsample)的平均池化层(Average Pooling)
(4)双曲正切(Tanh)或S型(Sigmoid)的激活函数
MLP作为最后的分类器
(5)层与层之间的稀疏连接减少计算复杂度

AlexNet

AlexNet,它本质上就是扩展 LeNet 的深度,并应用一些 ReLU、Dropout 等技巧。AlexNet 有 5 个卷积层和 3 个最大池化层,它可分为上下两个完全相同的分支,这两个分支在第三个卷积层和全连接层上可以相互交换信息。与 Inception 同年提出的优秀网络还有 VGG-Net,它相比于 AlexNet 有更小的卷积核和更深的层级。
2
AlexNet使用两个GPU训练来提升速度,使用GPU训练。与CPU不同的是,GPU转为执行复杂的数学和几何计算而设计,AlexNet使用了2个GPU来提升速度,分别放置一半卷积核。并且使用Dropout防止过拟合,

VggNet

VGG的泛化性能非常好,常用于图像特征的抽、目标检测候选框生成等。VGG 最大的问题就在于参数数量,VGG-19 基本上是参数量最多的卷积网络架构。这一问题也是第一次提出 Inception 结构的 GoogLeNet 所重点关注的,它没有如同 VGG-Net 那样大量使用全连接网络,因此参数量非常小。
3

GoogLeNet

GoogLeNet 最大的特点就是使用了 Inception 模块,它的目的是设计一种具有优良局部拓扑结构的网络,即对输入图像并行地执行多个卷积运算或池化操作,并将所有输出结果拼接为一个非常深的特征图。因为 11、33 或 5*5 等不同的卷积运算与池化操作可以获得输入图像的不同信息,并行处理这些运算并结合所有结果将获得更好的图像表征。
4

ResNet

Resnet从避免梯度消失或爆炸的角度,使用残差连接结构使网络可以更深

主要的创新在残差网络,其实这个网络的提出本质上还是要解决层次比较深的时候无法训练的问题。这种借鉴了Highway Network思想的网络相当于旁边专门开个通道使得输入可以直达输出,而优化的目标由原来的拟合输出H(x)变成输出和输入的差H(x)-x,其中H(X)是某一层原始的的期望映射输出,x是输入。

总结

总结

  • 6
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: PyTorch的ResNet-18CIFAR-10数据集的预训练模型是指在经过大规模的图像数据集上进行预训练后的ResNet-18模型,以便在CIFAR-10数据集上进行更好的图像分任务。 ResNet-18是一个由18个卷积层和全连接层组成的深度神经网络。预训练模型是指在大规模数据上进行训练得到的模型参数,因此具有更好的泛化性能。CIFAR-10是一个包含10个别的图像分数据集,用于在小尺寸图像上进行模型训练和评估。 通过使用预训练ResNet-18模型,在CIFAR-10数据集上进行图像分任务时,我们可以利用预训练模型的权重参数来加快训练过程并提高准确率。预训练模型的好处是可以从大规模数据中学习到更多的特征表示,这些特征表示通常具有更高的鉴别性,因此可以更好地捕捉图像的关键特征。 对于CIFAR-10数据集,预训练模型可以有效地缩短训练时间并提高模型的收敛速度,因为在预训练模型中已经包含了对图像的一些共享特征的学习。通过在CIFAR-10数据集上进行微调,即在预训练模型的基础上进行进一步的训练,可以逐步调整模型参数以适应CIFAR-10数据集的特定要求,从而提高最终的图像分性能。 总而言之,PyTorch的ResNet-18CIFAR-10的预训练模型是通过在大规模数据上进行训练,在CIFAR-10数据集上进行图像分任务时使用预训练模型。这个预训练模型可以帮助提高训练速度和分准确率,并且在模型训练和微调时起到了重要作用。 ### 回答2: PyTorch的ResNet-18是一种在CIFAR-10数据集上进行预训练的深度神经网络模型。CIFAR-10是一个包含10个别的图像分数据集,包括飞机、汽车、鸟、猫、鹿、狗、青蛙、马、船和卡车。 ResNet-18是指由18个卷积层和全连接层组成的深度残差网络。该网络的设计思想是通过残差连接(即跳过连接)来解决深度网络中的梯度消失问题,使得网络具有更好的训练效果。这意味着在每个卷积层之后,输入信号可以通过两条路径传递:一条直接连接到后续层,另一条通过卷积操作后再进行连接。这种设计可以使网络更加容易学习输入和输出之间的映射关系。 在CIFAR-10上预训练ResNet-18模型具有多个优点。首先,这个模型具有较小的参数量和计算复杂度,适合在资源有限的环境下使用。其次,该模型经过在CIFAR-10数据集上的预训练,可以直接用于图像分任务。通过在CIFAR-10上进行预训练,模型可以学习到一般的图像特征和模式,使其能够更好地泛化到其他似的图像分任务中。 通过使用预训练ResNet-18模型,我们可以利用其已经学到的特征和知识,节省训练时间,并为我们的具体图像分任务提供一个良好的起点。此外,该模型可以通过微调(fine-tuning)进一步优化,以适应特定任务的需求。 综上所述,PyTorch的ResNet-18CIFAR-10的预训练模型是一个有价值的工具,可以用于图像分任务,具有较小的参数量和计算复杂度,预先学习了一般的图像特征和模式,并可以通过微调进一步适应特定任务的需求。 ### 回答3: PyTorch的预训练模型ResNet-18CIFAR-10数据集上表现出色。首先,CIFAR-10是一个包含10个不同别的图像数据集,每个别有6000个图像,共计60000个图像。ResNet-18是一个基于深度残差网络的模型,它具有18个卷积层和全连接层。该模型在ImageNet数据集上进行了预训练,其中包含了1000个别的图像。 当我们将预训练ResNet-18模型应用于CIFAR-10数据集时,可以得到很好的结果。因为CIFAR-10数据集的图像尺寸较小(32x32),相对于ImageNet数据集中的图像(224x224),所以ResNet-18模型在CIFAR-10上的训练速度更快。此外,ResNet-18模型通过残差连接解决了深度网络中的梯度消失问题,这使得它在CIFAR-10数据集上的表现也非常稳定。 通过使用预训练模型,我们可以通过迁移学习的方式节省训练时间。我们可以先将ResNet-18加载到内存中,然后只需针对CIFAR-10数据集的最后一层或几层进行微调即可。这样可以有效地提高模型在CIFAR-10上的性能。 总之,PyTorch中的预训练模型ResNet-18CIFAR-10数据集上表现优秀。它通过残差连接解决了深度网络中的梯度消失问题,具有较快的训练速度和较好的稳定性。使用预训练模型可以节省训练时间,并通过微调模型的方式进一步提高性能。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值