首页人工智能Pytorch【深度学习(PyTorch...

【深度学习(PyTorch篇)】2.使用预训练模型完成图像识别分类


本系列文章配套代码获取有以下两种途径:

  • 通过百度网盘获取:
链接:https://pan.baidu.com/s/1XuxKa9_G00NznvSK0cr5qw?pwd=mnsj 提取码:mnsj
  • 前往GitHub获取
https://github.com/returu/PyTorch





作为深度学习的第一次尝试,我们将使用一个预训练网络模型来完成图像分类任务。
01

预训练模型


预训练网络模型是在大型数据集上进行训练后得到的模型,可以用于各种任务,如图像分类、目标检测、自然语言处理等。这些模型通常包含大量的参数,并且已经在大量的数据上进行了优化,因此可以用于各种不同的应用场景。使用预训练网络模型的好处是可以利用已经在大型数据集上训练好的模型,避免从头开始训练模型,节省时间和计算资源。
在计算机视觉领域,有许多预训练网络模型可供选择,如VGGResNetInception等。这些模型在ImageNet等大型图像数据集上进行训练,可以用于图像分类、目标检测、语义分割等任务。
PyTorch中使用预训练模型也十分简单,可以从torchvision中获取,其作为PyTorch深度学习框架的一部分,提供了丰富的工具和函数来方便用户进行图像处理和模型训练,主要包含以下几个部分:
  • torchvision.datasets:提供了一些加载数据的函数及常用的数据集接口,方便用户快速加载数据集;
  • torchvision.models:包含了常用的模型结构(含预训练模型),如AlexNetVGGResNet等,用户可以直接使用这些模型或者作为自己模型的起点进行微调;
  • torchvision.transforms:提供了常用的图像预处理操作,如裁剪、旋转等。这些操作可以通过Compose类进行串联,方便用户构建自己的图像处理流程;
  • torchvision.utils:包含其他一些有用的方法,如可视化工具等。

本次我们将使用torchvision.models来加载预训练模型,可以通过以下代码查看其包含的预定义模型:

import torchvision.models as models

dir(models)

返回列表中的首字母大写通常表示类名,这些类是用来实例化特定模型的。例如,’AlexNet’, ‘VGG’, ‘ResNet’, 和 ‘DenseNet’ 都是类,可以通过调用这些类(加上括号和任何必要的参数)来创建模型实例,例如:
# 使用类名创建模型实例
resnet = models.ResNet(blocks=[3463], num_classes=1000)
小写字母的名称,如 ‘resnet18′, ‘resnet50’ 等,通常是模块级别的便捷函数,它们会直接返回对应类的预配置实例。这些函数通常是为了方便用户快速获取常用的模型配置而提供的。在这些函数中,有些可能还会自动下载并加载预训练权重(如果pretrained参数设置为True的话)例如
# 使用便捷函数创建预训练模型实例
resnet18_pretrained = models.resnet18(pretrained=True)


02

使用resnet101完成图像识别分类


resnet101torchvision.models模块中提供的一个预定义模型,它是ResNetResidual Network)家族中的一员,具体表示具有101层深度的ResNet网络。ResNet是由微软研究院提出的,用于解决深度神经网络训练过程中的梯度消失和表示瓶颈问题,通过引入残差连接(residual connection)来改进网络的训练。
当使用torchvision.models.resnet101(pretrained=True)时,会得到一个在ImageNet数据集上预训练的ResNet-101模型。ImageNet是一个包含超过一百万张图片和一千个类别的大型数据集,预训练模型通常在这个数据集上进行训练,以学习通用的图像特征。
接下来,我们将使用resnet101来实例化一个具有101层的卷积神经网络来完成图像识别分类任务,待预测图像为一只猫的图片:

下面,简要介绍下代码框架,具体内容可以查看文章配套的Notebook文件。

  • 1、实例化一个resnet101模型:
# 使用resnet101来实例化一个具有101层的卷积神经网络
resnet = models.resnet101(pretrained=True)
# 查看网络结构信息,返回结果中的每一行就是深度学习中的层layers
resnet
输出结果:
ResNet(
  (conv1): Conv2d(364, kernel_size=(77), stride=(22), padding=(33), bias=False)
  (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)
  (relu): ReLU(inplace=True)
  (maxpool): MaxPool2d(kernel_size=3, stride=2, padding=1, dilation=1, ceil_mode=False)
  (layer1): Sequential(
    (0): Bottleneck(
      (conv1): Conv2d(6464, kernel_size=(11), stride=(11), bias=False)
......(略)......
 )
  )
  (avgpool): AdaptiveAvgPool2d(output_size=(11))
  (fc): Linear(in_features=2048, out_features=1000, bias=True)
)
  • 2、加载预测图像并做预处理:
  • 读取图像:

from PIL import Image

# 读取预测图像
img = Image.open('./image.jpg')
  • 图像预处理:

# 定义图像预处理函数
from torchvision import transforms

preprocess = transforms.Compose([
    transforms.Resize(256), # 将输入图像缩放到256*256大小
    transforms.CenterCrop(224), # 围绕图像中心点将其裁剪为224*224大小
    transforms.ToTensor(), # 将其转换为一个张量tensor
    transforms.Normalize( # 对图像RGB分量进行归一化处理,使其具有定义的均值和方差
        mean=[0.485,0.456,0.406],
        std=[0.229,0.224,0.225]
    )
])

img_t = preprocess(img)
  • 按照网络输入要求对输入的张量进行维度扩展

import torch

# 使用unsqueeze()函数进行维度扩展,维度变化为:[3224224] --> [13224224]
batch_t = torch.unsqueeze(img_t , 0)
  • 3、运行模型:
# 要进行推理,需要将网络置于eval模式
resnet.eval()

# 模型输出结果:一个由1000个分数的向量,每一个分数对应ImageNet中的每个类
out = resnet(batch_t)
out

输出结果:

tensor([[-3.2444e+00, -1.9064e+00, -3.7759e+00, -2.9615e+00, -3.5997e+00,
         -2.9952e+00, -4.6614e+00, -2.3487e+00, -1.9136e+00, -2.0267e+00,
         -7.4748e-01, -3.2986e+00,  3.9570e-01, -2.3369e+00, -1.6109e+00,
                                   ............
         -2.1636e+00,  2.6281e-01, -2.6963e+00,  1.1257e+00,  3.9239e+00]]
,
       grad_fn=<AddmmBackward0>)
  • 4、获取模型预测结果标签及置信度:
  • 读取文件生成标签列表:

该txt文件为ImageNet数据集包含的1000个标签。

with open('./imagenet_classes.txt'as f:
    labels 
= [line.strip() for line in f.readlines()]

labels

输出结果:

['tench, Tinca tinca',
 'goldfish, Carassius auratus',
   ............
 'ear, spike, capitulum',
 'toilet tissue, toilet paper, bathroom tissue']
  • 获取最高分对应的索引:

通过max()函数获得输出结果中最高分数及其对应的索引。

_ , index = torch.max(out , 1)
  • 使用softmax将输出结果归一化到[0,1]范围,可以认为是模型预测结果的置信度:

percentage = torch.nn.functional.softmax(out , dim=1)[0]*100
  • 获取预测结果标签及置信度:

labels[index[0]] , percentage[index[0]].item()

输出结果:

('tabby, tabby cat', 55.32239532470703)
  • 获取预测结果前五名的标签及置信度:

_ , indices = torch.sort(out , descending=True)

n = 1
for idx in indices[0][0:5]:
    print(f"预测第{n}名:类别为{labels[idx]},置信度为{percentage[idx].item()}")
    n += 1

输出结果:

预测第1名:类别为tabbytabby cat,置信度为55.32239532470703
预测第2名:类别为Egyptian cat,置信度为25.100072860717773
预测第3名:类别为tiger cat,置信度为17.506240844726562
预测第4名:类别为lynxcatamount,置信度为0.30555540323257446
预测第5名:类别为quiltcomfortercomfortpuff,置信度为0.09972941875457764

Reference:  Antiga, Luca Pietro Giovanni, et al. Deep Learning with PyTorch. United States, Manning, 2020.


更多内容可以前往官网查看

https://pytorch.org/


本篇文章来源于微信公众号: 码农设计师

RELATED ARTICLES

欢迎留下您的宝贵建议

Please enter your comment!
Please enter your name here

- Advertisment -

Most Popular

Recent Comments