Task2:预训练模型预测
参考代码:B站up主同济子豪兄开源在GitHub的图像分类代码
task 2是使用预训练模型进行预测。但是我的数据集本身与ImageNet的数据差别过大了,是无法准确识别的。不过倒是可以判断出一些零件像什么。
使用resnet18进行预测
参考up主子豪大佬的代码,首先使用了resnet18模型进行预测。
载入模型
from torchvision import models
model = models.resnet18(pretrained=Ture) #即载入预训练模型
不过在这里我出现了一个问题,载入权重文件失败。(大概是网络不好吧)
所以需要手动下载一个权重文件,并手动载入。
model = models.resnet18(pretrained=False)
model.load_state_dict(torch.load('resnet18-f37072fd.pth'))
这里我下载的是resnet18-f37072fd.pth(链接奉上)
图像预处理
from torchvision import transforms
# 测试集图像预处理-RCTN:缩放裁剪、转 Tensor、归一化
test_transform = transforms.Compose([transforms.Resize(256),
transforms.CenterCrop(224),
transforms.ToTensor(),
transforms.Normalize(
mean=[0.485, 0.456, 0.406],
std=[0.229, 0.224, 0.225])
])
图像预处理的目的: 图像预处理的主要目的是消除图像中无关的信息,恢复有用的真实信息,增强有关信息的可检测性和最大限度地简化数据,从而改进特征抽取、图像分割、匹配和识别的可靠性。
(更多关于图像预处理移步这位大佬的博客)
载入图像
然后使用pillow载入图像
# 用 pillow 载入
from PIL import Image
img_pil = Image.open(img_path)
之所以用pillow,是因为transforms的方法仅支持处理PIL格式或张量。
执行图像分类预测
input_img = test_transform(img_pil)
input_img = input_img.unsqueeze(0).to(device) #如果之前有定义了device的话
pred_logits = model(input_img)
import torch.nn.functional as F
pred_softmax = F.softmax(pred_logits, dim=1) # 对 logit 分数做 softmax 运算
随后对置信度最大的一个或几个,解析出索引与置信度。(详细代码建议阅读up主同济子豪兄的GitHub仓库)
由原预训练权重得出的结果
赫然可见它最有可能是小发夹,实际上它是一个螺旋齿轮,不过ImageNet这个数据集中应该是没有的,所以载入resnet18模型当然也测不出来。悲
稍稍迁移学习一下
model = torch.load("./checkpoints/mec11点54分.pth")
# 本来该是 model = models.resnet18(pretrained=False) 的,不过我之前训练过一轮,loss有点大,所以有训练了一轮。
# 载入自己的权重文件使用torch.load()
model.fc = nn.Linear(model.fc.in_features, n_class)
optimizer = optim.Adam(model.parameters())
(其余代码略)
似乎效果还是可以,下面我使用这个新生成的权重文件来预测,方法与之前使用resnet18差不多。
emmm,可以说是相当尴尬了,不过应该是索引的问题,因为置信度很高。可能是我建数据集的时候生成的csv文件就是错的,可能是我之前建立数据集的时候重命名那一步出了问题(感觉这里的可能性是最大的),总之,置信度很高,但结果歪了啊。
问题解决(2023年1月20日)
确实是我的索引出现了问题,最开始生成的索引文件并没有按顺序,打开csv文件后我发现了这一点,应该是由于最初的索引是与训练集与验证集一起生成的,当时的文件夹并没有完成排序,可能与我按帧读取时的视频文件夹排序有关,因为我的视频文件是按照大小顺序排列的,大概是有这方面原因在。所以在生成索引文件时要注意原文件的排序。
但我当时并没有立刻发现训练出的权重文件是按什么顺序的,也没有意识到我的索引文件是有问题的,我的第一反应是Linux上文件的排列顺序与Windows上文件的排列顺序是不同的,由此导致我的置信度很高但结果错误。经过查证,虽然Ubuntu与Windows的文件排列顺序确实有一些不同的地方,比如当时从jupyter lab的文件夹里看,英文开头的文件排在后面,但这并不是我错误的原因,况且我对该文件夹进行了 ‘os.dirlist’ ,发现文件目录列表依然是英文排在前面的,看来文件夹中看到英文在后并不是训练的顺序,英文在前这种排列才是训练时采用的。但还是应当注意在不同操作系统之间传递文件时要注意文件的变化,排列顺序只是一部分,还有编码等让人头大的问题。
随后我发现第77位是螺旋齿轮的排序就是我昨天使用tree命令得到的文件夹结构的排序,调整后能得到正确的结果了。
补充:在训练时我采用的是tensorboard进行可视化。因为连不上wandb。最后的损失大概有0.4。
我在恒源云上进行训练,这几天全代金券白嫖,用的3090,24G显存,1.5元一小时。可以直接打开jupyter lab和tensorboard。也可以自己用Xshell或者是VSCode、Pycharm来连服务器。
也不隐瞒什么,那个恒源云的注册链接是我的邀请链接,从这里进去比在官网进去可以多得10元代金券,一份代金券是可以分多次使用直到用完的。并且只要你不充值一百元以上我都不会有啥邀请奖励。