动手撸个图像分类任务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)




相关实践学习
基于阿里云DeepGPU实例,用AI画唯美国风少女
本实验基于阿里云DeepGPU实例,使用aiacctorch加速stable-diffusion-webui,用AI画唯美国风少女,可提升性能至高至原性能的2.6倍。
相关文章
|
2月前
|
自然语言处理 PyTorch 算法框架/工具
自然语言生成任务中的5种采样方法介绍和Pytorch代码实现
在自然语言生成任务(NLG)中,采样方法是指从生成模型中获取文本输出的一种技术。本文将介绍常用的5中方法并用Pytorch进行实现。
120 0
|
3月前
|
机器学习/深度学习 数据可视化 算法
Pytorch CIFAR10图像分类 Swin Transformer篇(二)
Pytorch CIFAR10图像分类 Swin Transformer篇(二)
|
3月前
|
机器学习/深度学习 PyTorch 算法框架/工具
Pytorch CIFAR10图像分类 Swin Transformer篇(一)
Pytorch CIFAR10图像分类 Swin Transformer篇(一)
|
1月前
|
机器学习/深度学习 PyTorch 算法框架/工具
【PyTorch实战演练】使用Cifar10数据集训练LeNet5网络并实现图像分类(附代码)
【PyTorch实战演练】使用Cifar10数据集训练LeNet5网络并实现图像分类(附代码)
59 0
|
1月前
|
机器学习/深度学习 算法 PyTorch
【PyTorch实战演练】深入剖析MTCNN(多任务级联卷积神经网络)并使用30行代码实现人脸识别
【PyTorch实战演练】深入剖析MTCNN(多任务级联卷积神经网络)并使用30行代码实现人脸识别
55 2
|
3月前
|
机器学习/深度学习 数据可视化 PyTorch
Pytorch CIFAR10图像分类 ZFNet篇
Pytorch CIFAR10图像分类 ZFNet篇
|
4月前
|
机器学习/深度学习 数据采集 PyTorch
PyTorch搭建卷积神经网络(ResNet-50网络)进行图像分类实战(附源码和数据集)
PyTorch搭建卷积神经网络(ResNet-50网络)进行图像分类实战(附源码和数据集)
96 1
|
4月前
|
机器学习/深度学习 PyTorch TensorFlow
如何使用TensorFlow或PyTorch进行机器学习任务?
如何使用TensorFlow或PyTorch进行机器学习任务?
|
6月前
|
机器学习/深度学习 数据采集 PyTorch
PyTorch应用实战二:实现卷积神经网络进行图像分类
PyTorch应用实战二:实现卷积神经网络进行图像分类
94 0
|
8月前
|
机器学习/深度学习 人工智能 PyTorch
【图像分类】基于OpenVINO实现PyTorch ResNet50图像分类
【图像分类】基于OpenVINO实现PyTorch ResNet50图像分类
184 0