作者:漫湾镇团委 | 来源:互联网 | 2023-10-17 18:12
关于如何快速定义自己的数据集,可以参考我的前一篇文章PyTorch中快速加载自定义数据(入门)_晨曦473的博客-CSDN博客刚开始学习PyTorch,找了很多自定义数据加载的方法,还是使用torch中封装的库函数好用,而且快捷,会根据路径自动返回对应的标签,下面的代码每一行都给了注释。import torchfrom torchvision import transforms, utilsfrom torchvision import datasetsimport torch.utils.dataimport matplotlib.pyplot as plt# 定义图像预处理transform1 = tranhttps://blog.csdn.net/weixin_55737425/article/details/122958584
这里给出一个模板,适合想要快速实现的朋友们(想要快速做出效果),不需要多少理论知识,只需要将文中的文件地址更改为自己的电脑上的地址即可。(注意图片的保存方式有一定的格式,详细可以查阅ImageFolder函数的用法)
此处每一行的代码都已经标记缘由和作用,如果还有疑惑,欢迎垂询问题!
import random
from torch.utils.data import DataLoader
from torchvision.models import resnet50
from imutils import paths
import torch.nn as nn
from torch import optim
import numpy
from torchvision import transforms, utils
import torch
from torchvision import datasets
import matplotlib.pyplot as pltdef load_data():transform1 = transforms.Compose([ # 这里最好加上一个中括号,否则会被认为是意外实参transforms.RandomResizedCrop(224),transforms.RandomHorizontalFlip(p=0.5), # 随机水平翻转,概率为0.3transforms.RandomVerticalFlip(p=0.5), # 随机垂直翻转,概率为0.3# transforms.CenterCrop((400, 400)),transforms.ToTensor(), # 转换成Tensor类型transforms.Normalize(mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.255)) # 这里是为了和官方文档保持一致])batch_size = 8train_data = datasets.ImageFolder(r"C:\Users\asus\Desktop\cnn_data\cnn_data\data\training_data", transform=transform1)# print(train_data.imgs)# 加载数据train_data = DataLoader(train_data, batch_size=batch_size, shuffle=True)return train_data# def im_convert(tensor): # 这里可以不用理睬,我是想要显示原来图片的
# image = tensor
# image = image.numpy().squeeze()
# image = image.transpose(1, 2, 0)
# iamge = image*numpy.array(0.229, 0.224, 0.255) + numpy.array(0.485, 0.456, 0.406)
# image = image.clip(0, 1)
# return imagedef train(train_data):lr = 0.0001EPOCH = 12 # 可以自己调整,多一点会更好,但十分耗时间device = torch.device("cuda" if torch.cuda.is_available() else "cpu") # 利用GPU进行训练model = resnet50(pretrained=True).to(device) # 此处使用迁移学习的方法预加载权重,此处会下载一段时间model.train() # 设置运行模式in_channel = model.fc.in_features # 获取全连接层中输入的维数model.fc = nn.Linear(in_channel, 2) # 重新赋值全连接层criterion = nn.CrossEntropyLoss().to(device) # 分类问题使用交叉熵的方法optimizer = torch.optim.SGD(model.parameters(), lr=lr, momentum=0.9) # 也可以使用Adam,效果也好,momentum根据文献资料,0.9为最优选择scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=2, gamma=0.1) # 每经历2个epoch就衰减十分之一,也可以自己选择running_loss = 0for epoch in range(0, EPOCH):correct = 0for i, (data, target) in enumerate(train_data, 1):data = torch.autograd.Variable(data).to(device)target = torch.autograd.Variable(target).to(device)optimizer.zero_grad() # 清空上一次的梯度值output = model(data)loss = criterion(output, target)running_loss = loss.item()loss.backward()optimizer.step()prediction = torch.argmax(output, dim=1) # 返回维度为dim上最大值的索引correct += (prediction == target).sum().item() # 当prediction==target时会返回“1”,predicton和target在此处都是tensor类型,所以返回的是“tensor(1)”,之后通过item返回数值if i % 2 == 0:print("第{}个EPOCH,第{}个batch,当前损失为{}".format(epoch+1, i, running_loss))print("本轮训练的准确率为{:}".format(correct/len(train_data)))
if __name__ == '__main__':train_data = load_data()train(train_data)