2.ResNet——使用resnet101实例化一个具有101层的卷积神经网络

  我们将使用resnet101来实例化一个具有101层的卷积神经网络。下面所有的代码和数据我都会进行上传,并且也会整个可以运行的代码,前期是前面的环境配置好了。(相关文件代码正在上传中...)

 

一、加载预训练模型

书上所用指示函数下载resnet101在ImageNet数据集上训练好的权重的代码为,但是运行之后会报下面的错误。

resnet = models.resnet101(pretrained=True)

  报错原因为这些警告表明 torchvision 中使用 pretrained 参数来加载预训练模型的方式已经过时,并将在未来版本中移除。现在应该使用 weights 参数来代替 pretrained 参数。 所有解决方法为导入相关库函数并修改原来的代码。

from torchvision import models, transforms
from torchvision.models import ResNet101_Weights

# 加载预训练模型
resnet = models.resnet101(weights=ResNet101_Weights.IMAGENET1K_V1)

  其中我们可以打印一下resnet的信息,可以看到这个resnet的网络结构非常的庞大,下面只展示部分

二、预处理 

1.预处理输入图像

  要想可以正常调用resnet,在此之前需要对输入图像进行预处理,使其大小正确,使其值(颜色)大致处于相同的数值范围。在这里使用torchvision模块提供的转换功能进行转换。

from torchvision import models, transforms

# 定义预处理步骤
preprocess = transforms.Compose([
    transforms.Resize(256),   # 调整短边为256像素
    transforms.CenterCrop(224),   # 从中心裁剪224x224图像
    transforms.ToTensor(),   # 转换为张量
    transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])   # 归一化
])

 2.进行图像的导入

  现在我们需要选择一张我们喜欢的图片,对其进行预处理,然后查看ResNet对它的识别结果。我们可以使用一个Python的图像操作模块Pillow从本地加载一张图片。

from PIL import Image

# 打开和预处理图像
image = Image.open("./pic/bobby.jpg")
image_t = preprocess(image)

 3.转化为张量并进行处理

  然后我们可以按照网络期望的方式对输入的张量(这里不懂没关系,后面对说,想象为线性代数里面的n维矩阵就行)进行重塑、裁剪和归一化处理。在这里就要开始使用Pytorch模块了。

import torch

# 批处理维度
batch_t = torch.unsqueeze(image_t, dim=0)

三、推理模型  

  在深度学习中,在新数据上运行训练过的模型的过程被称为推理(inference)。为了进行推理,我们需要将网络置于eval模式。

# 评估模式
resnet.eval()

  现在eval设置好了,我们准备进行推理(也就是逆推,向前传播)

# 前向传播
out = resnet(batch_t)

四、读取标签并得到结果  

  通过上面的步骤可以得出1000个分数向量,也就相当于1000个标签,我们现在需要找出得分高的类的标签,也就是符合预期的标签。要查看预测标签的列表,我们需要加载一个文本文件,按照训练中呈现给网络的顺序列出标签。

   让我们为ImageNet数据集类加载一个包含1000个标签的文件。相关的文件到时会引用在文章中。

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

  此时,我们需要确定不同分高对应的索引。可以使用pytorch的max()函数来做到这一点,它可以输出一个张量中的最大值以及最大值所在的索引。

_, index = torch.max(out, 1)

  现在我们可以使用索引来访问标签。在这里并非普通的python索引,而是张量索引,如torch([20])。因此我们需要使用index[0]获得实际的数字作为标签列表的索引,还可以使用 torch.nn.functional.softmax()将输出归一化带[0,1]之间然后除以总和,就可以得到大致的预测置信度。

# 获取预测结果
_, index = torch.max(out, 1)
percentage = torch.nn.functional.softmax(out, dim=1)[0] * 100
print(labels[index[0]], percentage[index[0]].item())

    最后我们获取前五个预测结果来看一下。

# 获取前5个预测结果
_, indices = torch.sort(out, descending=True)
result = [(labels[idx], percentage[idx].item()) for idx in indices[0][:5]]
print(result)

五、整体代码  

整体代码如下:

import torch
from torchvision import models, transforms
from torchvision.models import ResNet101_Weights
from PIL import Image

# 加载预训练模型
resnet = models.resnet101(weights=ResNet101_Weights.IMAGENET1K_V1)

# 定义预处理步骤
preprocess = transforms.Compose([
    transforms.Resize(256),   # 调整短边为256像素
    transforms.CenterCrop(224),   # 从中心裁剪224x224图像
    transforms.ToTensor(),   # 转换为张量
    transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])   # 归一化
])

# 打开和预处理图像
image = Image.open("./pic/bobby.jpg")
image_t = preprocess(image)

# 批处理维度
batch_t = torch.unsqueeze(image_t, dim=0)

# 评估模式
resnet.eval()

# 前向传播
out = resnet(batch_t)

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

# 获取预测结果
_, index = torch.max(out, 1)
percentage = torch.nn.functional.softmax(out, dim=1)[0] * 100
print(labels[index[0]], percentage[index[0]].item())

# 获取前5个预测结果
_, indices = torch.sort(out, descending=True)
result = [(labels[idx], percentage[idx].item()) for idx in indices[0][:5]]
print(result)


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值