pytorch加载自己的图像数据集实例

yizhihongxing

下面是 "PyTorch加载自己的图像数据集实例" 的完整攻略:

准备工作

  1. 数据集准备:准备自己的图像数据集,并将其组织为相应的目录结构。例如,我们假设有一份猫狗分类的数据集,其中包含两个类别:狗和猫。则我们可以将其组织为如下目录结构:
dataset
├── train
│   ├── cat
│   │   ├── cat.1.png
│   │   ├── cat.2.png
│   │   ├── ……
│   ├── dog
│   │   ├── dog.1.png
│   │   ├── dog.2.png
│   │   ├── ……
├── val
│   ├── cat
│   │   ├── cat.10.png
│   │   ├── cat.11.png
│   │   ├── ……
│   ├── dog
│   │   ├── dog.10.png
│   │   ├── dog.11.png
│   │   ├── ……

其中,train 目录下是训练集,val 目录下是验证集。每个子目录表示一个类别。每个类别中包含若干张图片,文件名以类别名开头,并编号。

  1. 安装所需依赖包:PyTorch、torchvision

代码实现

import torch
import torchvision
from torchvision.transforms import transforms
from torch.utils.data import Dataset, DataLoader

# 定义数据路径和变换
train_path = '/path/to/train'
val_path = '/path/to/val'
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]
                )
            ])

# 自定义数据集类
class MyDataset(Dataset):
    def __init__(self, path, transform):
        self.path = path
        self.transform = transform
        self.classes = os.listdir(self.path)

    def __len__(self):
        num = 0
        for c in self.classes:
            num += len(os.listdir(os.path.join(self.path, c)))
        return num

    def __getitem__(self, index):
        for i, c in enumerate(self.classes):
            images = os.listdir(os.path.join(self.path, c))
            if index < len(images):
                img_path = os.path.join(self.path, c, images[index])
                img = Image.open(img_path).convert('RGB')
                img = self.transform(img)
                label = i
                return img, label
            else:
                index -= len(images)

# 创建数据集和数据加载器
train_dataset = MyDataset(train_path, transform)
train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True, num_workers=0)

val_dataset = MyDataset(val_path, transform)
val_loader = DataLoader(val_dataset, batch_size=32, shuffle=False, num_workers=0)

# 使用数据集和数据加载器进行训练和验证
for epoch in range(num_epochs):
    # 训练
    for images, labels in train_loader:
        # 训练操作
        pass

    # 验证
    with torch.no_grad():
        for images, labels in val_loader:
            # 计算模型预测结果,并进行验证操作
            pass

以上代码实现了一个简单的PyTorch数据加载器。其中,我们使用了torchvision.transforms模块定义了图像变换,包括将图像缩放到256x256,并中心裁剪为224x224大小,将图像转换为Tensor类型,并进行归一化操作。

然后,我们定义了一个自定义数据集类MyDataset,该类继承torch.utils.data.Dataset类。其中,__init__方法初始化数据路径和变换,__len__方法返回数据集样本数,__getitem__方法根据索引返回图像和标签。

最后,我们创建了两个数据集实例train_datasetval_dataset,并使用torch.utils.data.DataLoader创建了相应的数据加载器train_loaderval_loader。这样,我们就可以使用数据加载器对模型进行训练和验证。

另外,这里提供两条示例:

示例1:使用自定义数据集训练分类模型

import torch
import torchvision
from torchvision.transforms import transforms
from torch.utils.data import Dataset, DataLoader

# 定义数据路径和变换
train_path = '/path/to/train'
val_path = '/path/to/val'
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]
                )
            ])

# 自定义数据集类
class MyDataset(Dataset):
    def __init__(self, path, transform):
        self.path = path
        self.transform = transform
        self.classes = os.listdir(self.path)

    def __len__(self):
        num = 0
        for c in self.classes:
            num += len(os.listdir(os.path.join(self.path, c)))
        return num

    def __getitem__(self, index):
        for i, c in enumerate(self.classes):
            images = os.listdir(os.path.join(self.path, c))
            if index < len(images):
                img_path = os.path.join(self.path, c, images[index])
                img = Image.open(img_path).convert('RGB')
                img = self.transform(img)
                label = i
                return img, label
            else:
                index -= len(images)

# 创建数据集和数据加载器
train_dataset = MyDataset(train_path, transform)
train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True, num_workers=0)

val_dataset = MyDataset(val_path, transform)
val_loader = DataLoader(val_dataset, batch_size=32, shuffle=False, num_workers=0)

# 定义模型和优化器
model = torchvision.models.resnet18(pretrained=True)
num_ftrs = model.fc.in_features
model.fc = torch.nn.Linear(num_ftrs, 2)  # 二分类问题
criterion = torch.nn.CrossEntropyLoss()
optimizer = torch.optim.SGD(model.parameters(), lr=0.001, momentum=0.9)

# 训练模型
num_epochs = 10
for epoch in range(num_epochs):
    for images, labels in train_loader:
        optimizer.zero_grad()
        outputs = model(images)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()

    # 计算验证集上的准确率
    with torch.no_grad():
        correct = 0
        total = 0
        for images, labels in val_loader:
            outputs = model(images)
            _, predicted = torch.max(outputs.data, 1)
            total += labels.size(0)
            correct += (predicted == labels).sum().item()

        acc = 100.0 * correct / total
        print(f'Epoch [{epoch+1}/{num_epochs}], Accuracy: {acc:.2f}%')

上述示例使用了自定义数据集train_datasetval_dataset,分别表示训练集和验证集。其中,我们使用了一个预训练的ResNet18模型,并替换了其最后一层全连接层以适应二分类问题。然后,我们定义了交叉熵损失和随机梯度下降优化器,使用数据加载器进行训练,并在每个epoch结束后在验证集上计算了模型的准确率。

示例2:使用自定义数据集微调分类模型

import torch
import torchvision
from torchvision.transforms import transforms
from torch.utils.data import Dataset, DataLoader

# 定义数据路径和变换
train_path = '/path/to/train'
val_path = '/path/to/val'
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]
                )
            ])

# 自定义数据集类
class MyDataset(Dataset):
    def __init__(self, path, transform):
        self.path = path
        self.transform = transform
        self.classes = os.listdir(self.path)

    def __len__(self):
        num = 0
        for c in self.classes:
            num += len(os.listdir(os.path.join(self.path, c)))
        return num

    def __getitem__(self, index):
        for i, c in enumerate(self.classes):
            images = os.listdir(os.path.join(self.path, c))
            if index < len(images):
                img_path = os.path.join(self.path, c, images[index])
                img = Image.open(img_path).convert('RGB')
                img = self.transform(img)
                label = i
                return img, label
            else:
                index -= len(images)

# 加载预训练模型,并替换其最后一层
model = torchvision.models.resnet18(pretrained=True)
num_ftrs = model.fc.in_features
model.fc = torch.nn.Linear(num_ftrs, 2)  # 二分类问题

# 冻结前面若干层参数
for i, param in enumerate(model.parameters()):
    if i < 40:
        param.requires_grad = False

# 创建数据集和数据加载器
train_dataset = MyDataset(train_path, transform)
train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True, num_workers=0)

val_dataset = MyDataset(val_path, transform)
val_loader = DataLoader(val_dataset, batch_size=32, shuffle=False, num_workers=0)

# 定义优化器
optimizer = torch.optim.SGD(model.parameters(), lr=0.001, momentum=0.9)

# 微调模型
num_epochs = 10
for epoch in range(num_epochs):
    for images, labels in train_loader:
        optimizer.zero_grad()
        outputs = model(images)
        loss = criterion(outputs, labels)
        loss.backward()
        optimizer.step()

    # 计算验证集上的准确率
    with torch.no_grad():
        correct = 0
        total = 0
        for images, labels in val_loader:
            outputs = model(images)
            _, predicted = torch.max(outputs.data, 1)
            total += labels.size(0)
            correct += (predicted == labels).sum().item()

        acc = 100.0 * correct / total
        print(f'Epoch [{epoch+1}/{num_epochs}], Accuracy: {acc:.2f}%')

上述示例同样使用了自定义数据集train_datasetval_dataset,分别表示训练集和验证集。不同的是,我们使用了一个预训练的ResNet18模型,并将其最后一层替换为适用于二分类问题的全连接层。然后,我们冻结前面若干层的参数,只训练后面的几层,以加速模型收敛。最后,我们使用数据加载器进行微调,并在每个epoch结束后在验证集上计算了模型的准确率。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:pytorch加载自己的图像数据集实例 - Python技术站

(0)
上一篇 2023年5月14日
下一篇 2023年5月14日

相关文章

  • 详解如何使用numpy提高Python数据分析效率

    如何使用Numpy提高Python数据分析效率 Numpy是Python中用于科学计算的一个重要库,它提供了效的多维数组对象和各种派生,以及用于数组的函数。本文将详细讲解何使用N提高Python数据分析效率,括Numpy的基本操作、数组的创建、索引和切片、数组的运算、的拼接和重、数组的转置等。 Numpy的基本操作 在使用Numpy进行数据分析时,需要掌握一…

    python 2023年5月13日
    00
  • python 读取文件并把矩阵转成numpy的两种方法

    在Python中,我们可以使用多种方法读取文件并将其转换为NumPy数组。以下是两种常见的方法: 使用numpy.loadtxt()函数 numpy.loadtxt()函数可以从文本文件中读取数据,并将其转换为NumPy数组。以下是一个使用numpy.loadtxt()函数读取文件并将其转换为NumPy数组的示例: import numpy as np # …

    python 2023年5月14日
    00
  • numpy实现合并多维矩阵、list的扩展方法

    在NumPy中,可以使用concatenate函数来实现多维矩阵和列表的合并。concatenate函数可以沿着指定的轴将多个数组合并成一个数组。下面是关于NumPy中concatenate的用法及说明的详细攻略。 concatenate函数的语法 concatenate函数的语法如下: numpy.concatenate((a1, a2, …), ax…

    python 2023年5月14日
    00
  • python 的numpy库中的mean()函数用法介绍

    NumPy是Python中用于科学计算的一个重要的库,它提供了高效的多维数组和与之相关的量。在NumPy中,mean()函数是一个重要的函数,本文将详细讲解mean()函数的用法,包括mean()函数的基本用法、mean()函数的参数、mean()函数的返回值、mean()函数的应用等方面。 mean()函数的基本用法 mean()函数是NumPy中的一个函…

    python 2023年5月14日
    00
  • macOS M1(AppleSilicon) 安装TensorFlow环境

    下面我将为您详细讲解在 macOS M1(Apple Silicon) 上安装 TensorFlow 环境的完整攻略,主要分为以下几个步骤: 步骤一:安装 Homebrew 要在 macOS M1 上安装 TensorFlow,我们首先需要安装一个包管理器——Homebrew。打开 Terminal 应用,在命令行中输入以下命令进行安装: /bin/bash…

    python 2023年5月14日
    00
  • 在NumPy中创建空数组/矩阵的方法

    在NumPy中,我们可以使用numpy.zeros()函数和numpy.ones()函数创建一个指定形状的全零数组/矩阵或全一数组/矩阵。下面是详细的步骤和示例。 步骤 NumPy创建空数组/矩阵步骤如下: 导入NumPy库。 使用numpy.zeros()函数或numpy.ones()函数创建一个指定形状的全零数组/矩阵或全一数组/矩阵。 下面我们将详细讲…

    python 2023年5月14日
    00
  • Python OpenCV 针对图像细节的不同操作技巧

    Python OpenCV针对图像细节的不同操作技巧 在本攻略中,我们将介绍如何使用Python OpenCV针对图像细节的不同操作技巧。以下是整个攻略的步骤: 导入必要库。可以使用以下命令导入必要的库: import cv2 import numpy as np 读取图像。可以使用以下代码读取图像: img = cv2.imread(‘image.jpg’…

    python 2023年5月14日
    00
  • Python实现分段线性插值

    Python实现分段线性插值 分段线性插值是一种常见的插值方法,可以用于在给定的数据点之间估计未知的函数值。在本攻略中,我们将介绍如何使用Python实现分段线性插值,并提供两个示例说明。 问题描述 在某些情况下,我们需要在给定的数据点之间估计未知的函数值。分段线性插值是一种常见的插值方法,可以用于实现这个目标。如何使用Python实现分段线性插值呢?在本攻…

    python 2023年5月14日
    00
合作推广
合作推广
分享本页
返回顶部