动手撸个图像分类任务Pytorch【ImageFolder式】

简介: 动手撸个图像分类任务Pytorch【ImageFolder式】

一.撸前有话说


文件目录形式是较为常见的一种数据集格式,例如最为常见的猫狗数据集,还有花朵、交通工具。


其结构如juejin.cn/post/707813… 中2.2所示,具体可如下:\

image.png

image.png

image.png

类推:每个文件夹下都是同种类别的图像



二.动手开始撸


如果使用文件目录形式进行数据的读取的话就较为轻松了,我们使用torchvision包中的ImageFolder类针对文件目录形式快速创建dataset。


基本流程:


2.1 输入图像的路径(训练测试)


2.2 torchvision.datasets.ImageFolder解决战斗


2.3 对ImageFolder读取的dataset进行DataLoader



代码片段:

"""
使用torchvision包中的ImageFolder类针对文件目录形式快速创建dataset
"""
import torchvision.datasets
from torch.utils.data import DataLoader
# 输入训练和测试集的路径
train_root = '' # 图像的路径
test_root = ''  # 图像的路径
# 将文件夹的内容载入dataset
train_dataset = torchvision.datasets.ImageFolder(root=train_root)
test_dataset = torchvision.datasets.ImageFolder(root=test_root)
# DataLoader 读取数据
train_loader = DataLoader(dataset=train_dataset,  # 输入自己要加载的数据set
                          batch_size=3,  # 一个批量的大小
                          shuffle=True,  # 是否打乱顺序
                          num_workers=4,  # 是否使用多进程,0代表不使用
                          pin_memory=True,  # 是否将数据保存在pin_memory区, pin_memory数据转移到Gpu中会快一些
                          drop_last=True)  # 当为Ture时,dataset中的数据个数不是batch_size整数倍时,将多余出不足一个batch的数据丢弃
test_loader = DataLoader(dataset=test_dataset,  # 输入自己要加载的数据set
                         batch_size=3,  # 一个批量的大小
                         shuffle=True,  # 是否打乱顺序
                         num_workers=4,  # 是否使用多进程,0代表不使用
                         pin_memory=True,  # 是否将数据保存在pin_memory区, pin_memory数据转移到Gpu中会快一些
                         drop_last=True)  # 当为Ture时,dataset中的数据个数不是batch_size整数倍时,将多余出不足一个batch的数据丢弃


接下来就可以参考juejin.cn/post/707813…juejin.cn/post/707783… 把训练部分摘过来稍加改动即可进行训练了\


三.撸完:demo:


"""
使用torchvision包中的ImageFolder类针对文件目录形式快速创建dataset
"""
import torchvision.datasets
import time
import numpy as np
import torch
import torch.nn as nn
import torch.backends.cudnn as cudnn
from PIL import Image
from torch import optim
from torch.autograd import Variable
from torch.utils.data import Dataset, DataLoader
class Net(nn.Module):
    def __init__(self, in_c=1200, out_c=10):
        super(Net, self).__init__()
        # 定义全连接层
        self.fc1 = nn.Linear(in_c, 512)
        # 定义激活层
        self.act1 = nn.ReLU(inplace=True)
        self.fc2 = nn.Linear(512, 256)
        self.act2 = nn.ReLU(inplace=True)
        self.fc3 = nn.Linear(256, 128)
        self.act3 = nn.ReLU(inplace=True)
        self.fc4 = nn.Linear(128, out_c)
    def forward(self, x):
        x = self.act1(self.fc1(x))
        x = self.act2(self.fc2(x))
        x = self.act3(self.fc3(x))
        x = self.fc4(x)
        return x
##
class MnistDataset(Dataset):
    def __init__(self, image_path, image_label, transform=None):
        super(MnistDataset, self).__init__()
        self.image_path = image_path  # 初始化图像路径列表
        self.image_label = image_label  # 初始化图像标签列表
        self.transform = transform  # 初始化数据增强方法
    def __getitem__(self, index):
        """
        获取对应index的图像,并视情况进行数据增强
        """
        image = Image.open(self.image_path[index])
        image = np.asarray(image)
        label = float(self.image_label[index])
        if self.transform is not None:
            image = self.transform(image)
        return image, torch.tensor(label)
    def __len__(self):
        return len(self.image_path)
if __name__ == '__main__':
    # 输入训练和测试集的路径
    train_root = './data - 副本/train/'
    test_root = './data - 副本/test/'
    # 将文件夹的内容载入dataset
    train_dataset = torchvision.datasets.ImageFolder(root=train_root,transform=torchvision.transforms.ToTensor())
    test_dataset = torchvision.datasets.ImageFolder(root=test_root,transform=torchvision.transforms.ToTensor())
    # DataLoader 读取数据
    train_data = DataLoader(dataset=train_dataset,  # 输入自己要加载的数据set
                              batch_size=5,  # 一个批量的大小
                              shuffle=True,  # 是否打乱顺序
                              num_workers=4,  # 是否使用多进程,0代表不使用
                              pin_memory=True,  # 是否将数据保存在pin_memory区, pin_memory数据转移到Gpu中会快一些
                              drop_last=True)  # 当为Ture时,dataset中的数据个数不是batch_size整数倍时,将多余出不足一个batch的数据丢弃
    test_data = DataLoader(dataset=test_dataset,  # 输入自己要加载的数据set
                             batch_size=5,  # 一个批量的大小
                             shuffle=True,  # 是否打乱顺序
                             num_workers=4,  # 是否使用多进程,0代表不使用
                             pin_memory=True,  # 是否将数据保存在pin_memory区, pin_memory数据转移到Gpu中会快一些
                             drop_last=True)  # 当为Ture时,dataset中的数据个数不是batch_size整数倍时,将多余出不足一个batch的数据丢弃
    t1 = time.time()
    # 搭建网络
    device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
    net = Net()
    cudnn.benchmark = True
    net = net.to(device)
    # 定义损失函数 -- 交叉熵
    criterion = torch.nn.CrossEntropyLoss().to(device)
    # 定义优化器 -- 随机梯度下降
    optimizer = optim.SGD(net.parameters(), lr=0.01, weight_decay=0.00005)
    # 开始训练
    losses = []  # 记录训练损失
    acces = []  # 记录训练精度
    eval_losses = []  # 记录测试损失
    eval_acces = []  # 记录测试精度
    nums_epoch = 20  # 训练次数
    for epoch in range(nums_epoch):
        train_loss = 0  # 设置训练损失的初始值
        train_acc = 0  # 设置训练精度的初始值
        net.train()
        for batch, (img, label) in enumerate(train_data):
            img = img.reshape(img.size(0), -1)
            img = Variable(img)
            img = img.to(device)
            label = Variable(label)
            label = label.to(device)
            # 向前传播
            out = net(img)
            loss = criterion(out, label.long())
            # 反向传播
            optimizer.zero_grad()
            loss.backward()
            optimizer.step()
            # 记录误差
            train_loss += loss.item()
            # 计算分类正确率
            _, pred = out.max(1)
            num_correct = (pred == label.long()).sum().item()
            acc = num_correct / img.shape[0]
            if (batch + 1) % 200 == 0:
                print(
                    '[INFO] Epoch-{}-Batch-{}: Train: Loss-{:.4f},Accuracy-{:.4f}'.format(epoch + 1, batch + 1,
                                                                                          loss.item(),
                                                                                          acc))
                train_acc += acc
        losses.append(train_acc / len(train_data))
        acces.append(train_acc / len(train_data))
        eval_loss = 0
        eval_acc = 0
        # 测试集不训练
        for img, label in test_data:
            img = img.reshape(img.size(0), -1)
            img = Variable(img)
            img = img.to(device)
            label = Variable(label)
            label = label.to(device)
            out = net(img)
            loss = criterion(out, label.long())
            eval_loss += loss.item()
            _, pred = out.max(1)
            num_correct = (pred == label.long()).sum().item()
            acc = num_correct / img.shape[0]
            eval_acc += acc
        eval_losses.append(eval_loss / len(test_data))
        eval_acces.append(eval_acc / len(test_data))
        # 打印参数
        set_epoch = epoch + 1
        set_lossTrain = train_loss / len(train_data)
        set_AccTrain = train_acc / len(train_data)
        set_lossEval = eval_loss / len(test_data)
        set_AccEval = eval_acc / len(test_data)
        print('[INFO] Epoch-{}: Train: Loss-{:.4f},Accuracy-{:.4f} |Test:Loss-{:.4f}, Accuracy-{:.4f}'.format(set_epoch,
                                                                                                              set_lossTrain,
                                                                                                              set_AccTrain,
                                                                                                              set_lossEval,
                                                                                                              set_AccEval))
    torch.save(net.state_dict(), 'saveNet.pth')
    t2 = time.time()
    t = t2 - t1
    print(t)




相关实践学习
部署Stable Diffusion玩转AI绘画(GPU云服务器)
本实验通过在ECS上从零开始部署Stable Diffusion来进行AI绘画创作,开启AIGC盲盒。
相关文章
|
9月前
|
自然语言处理 PyTorch 算法框架/工具
自然语言生成任务中的5种采样方法介绍和Pytorch代码实现
在自然语言生成任务(NLG)中,采样方法是指从生成模型中获取文本输出的一种技术。本文将介绍常用的5中方法并用Pytorch进行实现。
313 0
|
9月前
|
机器学习/深度学习 PyTorch 算法框架/工具
Pytorch CIFAR10图像分类 Swin Transformer篇(一)
Pytorch CIFAR10图像分类 Swin Transformer篇(一)
|
9月前
|
机器学习/深度学习 数据可视化 算法
Pytorch CIFAR10图像分类 Swin Transformer篇(二)
Pytorch CIFAR10图像分类 Swin Transformer篇(二)
|
9月前
|
机器学习/深度学习 PyTorch 算法框架/工具
【PyTorch实战演练】使用Cifar10数据集训练LeNet5网络并实现图像分类(附代码)
【PyTorch实战演练】使用Cifar10数据集训练LeNet5网络并实现图像分类(附代码)
582 0
|
7月前
|
资源调度 PyTorch 调度
多任务高斯过程数学原理和Pytorch实现示例
本文探讨了如何使用高斯过程扩展到多任务场景,强调了多任务高斯过程(MTGP)在处理相关输出时的优势。通过独立多任务GP、内在模型(ICM)和线性模型(LMC)的核心区域化方法,MTGP能够捕捉任务间的依赖关系,提高泛化能力。ICM和LMC通过引入核心区域化矩阵来学习任务间的共享结构。在PyTorch中,使用GPyTorch库展示了如何实现ICM模型,包括噪声建模和训练过程。实验比较了MTGP与独立GP,显示了MTGP在预测性能上的提升。
143 7
|
9月前
|
机器学习/深度学习 PyTorch 测试技术
PyTorch实战:图像分类任务的实现与优化
【4月更文挑战第17天】本文介绍了使用PyTorch实现图像分类任务的步骤,包括数据集准备(如使用CIFAR-10数据集)、构建简单的CNN模型、训练与优化模型以及测试模型性能。在训练过程中,使用了交叉熵损失和SGD优化器。此外,文章还讨论了提升模型性能的策略,如调整模型结构、数据增强、正则化和利用预训练模型。通过本文,读者可掌握基础的PyTorch图像分类实践。
|
9月前
|
机器学习/深度学习 算法 PyTorch
【PyTorch实战演练】深入剖析MTCNN(多任务级联卷积神经网络)并使用30行代码实现人脸识别
【PyTorch实战演练】深入剖析MTCNN(多任务级联卷积神经网络)并使用30行代码实现人脸识别
736 2
|
9月前
|
机器学习/深度学习 自然语言处理 PyTorch
PyTorch在NLP任务中的应用:文本分类、序列生成等
【4月更文挑战第18天】PyTorch在NLP中应用于文本分类和序列生成,支持RNN、CNN、Transformer等模型构建。其动态计算图、丰富API及强大社区使其在NLP研究中备受欢迎。预训练模型和多模态学习的发展将进一步拓宽PyTorch在NLP的应用前景。
|
9月前
|
机器学习/深度学习 数据采集 PyTorch
【单点知识】基于实例讲解PyTorch中的ImageFolder类
【单点知识】基于实例讲解PyTorch中的ImageFolder类
230 0
|
9月前
|
机器学习/深度学习 数据采集 PyTorch
PyTorch搭建卷积神经网络(ResNet-50网络)进行图像分类实战(附源码和数据集)
PyTorch搭建卷积神经网络(ResNet-50网络)进行图像分类实战(附源码和数据集)
530 1