Обработка и загрузка данных в PyTorch

В PyTorch обработка и загрузка данных — важнейший этап процесса обучения глубоких нейронных сетей.

Для эффективной работы с данными PyTorch предоставляет мощные инструменты, включаяtorch.utils.data.Datasetиtorch.utils.data.DataLoader, которые помогают управлять такими задачами, как наборы данных, пакетная загрузка и аугментация данных.

Введение в обработку и загрузку данных в PyTorch:

  • Пользовательский набор данных: путём наследованияtorch.utils.data.Datasetчтобы загрузить собственный набор данных.
  • DataLoader:DataLoaderЗагрузка данных пакетами, поддержка многопоточной загрузки и перемешивания данных.
  • Предобработка и аугментация данных: Используйтеtorchvision.transformsдля выполнения распространённых операций предобработки и аугментации изображений, повышая обобщающую способность модели.
  • Загрузка стандартных наборов данных:torchvision.datasetsпредоставляет множество распространённых наборов данных, упрощая процесс загрузки данных.
  • Несколько источников данных: путём объединения несколькихDatasetэкземпляров для обработки данных из разных источников.

Пользовательский набор данных

torch.utils.data.Dataset— это абстрактный класс, который позволяет создавать наборы данных из собственных источников данных.

Нам нужно унаследовать этот класс и реализовать следующие два метода:

  • __len__(self): Возвращает количество примеров в наборе данных.
  • __getitem__(self, idx): Возвращает пример по индексу.

Предположим, у нас есть простой файл CSV или какие-то данные в виде списка; мы можем создать собственный набор данных, унаследовав класс Dataset.

Пример

import torch
from torch.utils.data import Dataset

# Пользовательский класс набора данных
class MyDataset(Dataset):
    def __init__(self, X_data, Y_data):
        """
Инициализация набора данных; X_data и Y_data — два списка или массива
X_data: входные признаки
Y_data: целевые метки
        """

        self.X_data = X_data
        self.Y_data = Y_data

    def __len__(self):
        """Возвращает размер набора данных"""
        return len(self.X_data)

    def __getitem__(self, idx):
        """Возвращает данные по указанному индексу"""
        x = torch.tensor(self.X_data[idx], dtype=torch.float32)  # Преобразовать в тензор
        y = torch.tensor(self.Y_data[idx], dtype=torch.float32)
        return x, y

# Пример данных
X_data = [[1, 2], [3, 4], [5, 6], [7, 8]]  # Входные признаки
Y_data = [1, 0, 1, 0]  # Целевые метки

# Создать экземпляр набора данных
dataset = MyDataset(X_data, Y_data)

Загрузка данных с помощью DataLoader

DataLoader — важный инструмент, предоставляемый PyTorch, используемый для пакетной загрузки данных из Dataset.

DataLoader позволяет читать данные пакетами и выполнять многопоточную загрузку, тем самым повышая эффективность обучения.

Пример

from torch.utils.data import DataLoader

# Создание экземпляра DataLoader; batch_size задаёт количество образцов, загружаемых каждый раз
dataloader = DataLoader(dataset, batch_size=2, shuffle=True)

# Вывод загруженных данных
for epoch in range(1):
    for batch_idx, (inputs, labels) in enumerate(dataloader):
        print(f'Пакет {batch_idx + 1}:')
        print(f'Входы: {inputs}')
        print(f'Метки: {labels}')
  • batch_size: Количество образцов, загружаемых каждый раз.
  • shuffle: Перемешивать ли данные; обычно во время обучения данные нужно перемешивать.
  • drop_last: Если количество образцов в наборе данных не делится без остатка наbatch_size, когда установлено вTrue, отбрасывать последний неполный батч.

Вывод:

Batch 1:
Inputs: tensor([[3., 4.], [1., 2.]])
Labels: tensor([0., 1.])
Batch 2:
Inputs: tensor([[7., 8.], [5., 6.]])
Labels: tensor([0., 1.])

На каждой итерации цикла DataLoader возвращает батч данных, включая входные признаки (inputs) и целевые метки (labels).


Предобработка и аугментация данных

Предобработка и аугментация данных имеют решающее значение для улучшения производительности модели.

PyTorch предоставляет модуль torchvision.transforms для выполнения распространённых операций предобработки и аугментации изображений, таких как поворот, обрезка, нормализация и т. д.

Распространённые операции предобработки изображений:

Пример

import torchvision.transforms as transforms
from PIL import Image

# Определить конвейер предобработки данных
transform = transforms.Compose([
    transforms.Resize((128, 128)),  # Изменить размер изображения до 128x128
    transforms.ToTensor(),  # Преобразовать изображение в тензор
    transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])  # Нормализация
])

# Загрузить изображение
image = Image.open('image.jpg')

# Применить предобработку
image_tensor = transform(image)
print(image_tensor.shape)  # Вывести форму тензора
  • transforms.Compose(): Объединяет несколько операций преобразования вместе.
  • transforms.Resize(): Изменяет размер изображения.
  • transforms.ToTensor(): Преобразует изображение в тензор PyTorch, со значениями, нормализованными к[0, 1]диапазону.
  • transforms.Normalize(): Нормализует данные изображения; нормализация обычно требуется при использовании предобученных моделей.

Аугментация данных изображений

Методы аугментации данных увеличивают разнообразие данных, применяя случайные преобразования к обучающим данным, что помогает модели лучше обобщать. Например, случайные отражения, повороты, кадрирование и т. д.

Пример

transform = transforms.Compose([
    transforms.RandomHorizontalFlip(),  # Случайное горизонтальное отражение
    transforms.RandomRotation(30),  # Случайный поворот на 30 градусов
    transforms.RandomResizedCrop(128),  # Случайная обрезка и изменение размера до 128x128
    transforms.ToTensor(),
    transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
])

Эти методы аугментации данных можно комбинировать с помощью transforms.Compose(), чтобы гарантировать, что каждое изображение подвергается различным преобразованиям во время обучения.


Загрузка наборов данных изображений

Для наборов данных изображений torchvision.datasets предоставляет множество распространённых наборов данных (таких как CIFAR-10, ImageNet, MNIST и т. д.), а также инструменты для загрузки данных изображений.

Загрузка набора данных MNIST:

Пример

import torchvision.datasets as datasets
import torchvision.transforms as transforms

# Определение операций предварительной обработки
transform = transforms.Compose([
    transforms.ToTensor(),
    transforms.Normalize((0.5,), (0.5,))  # Нормализовать изображение в оттенках серого
])

# Скачать и загрузить набор данных MNIST
train_dataset = datasets.MNIST(root='./data', train=True, download=True, transform=transform)
test_dataset = datasets.MNIST(root='./data', train=False, download=True, transform=transform)

# Создание DataLoader
train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=64, shuffle=False)

# Итерация по обучающим данным
for inputs, labels in train_loader:
    print(inputs.shape)  # Форма входных данных для каждого пакета
    print(labels.shape)  # Форма меток для каждого пакета
  • datasets.MNIST()автоматически скачает и загрузит набор данных MNIST.
  • transformПараметр позволяет нам предварительно обработать данные.
  • train=Trueиtrain=Falseпредставляют обучающий и тестовый наборы соответственно.

Использование нескольких источников данных (многоисточниковый набор данных)

Если ваш набор данных состоит из нескольких файлов или нескольких источников (например, нескольких папок с изображениями), вы можете настроить загрузку нескольких источников данных, унаследовав класс Dataset.

PyTorch предоставляет такие классы, как ConcatDataset и ChainDataset, для объединения нескольких наборов данных.

Например, предположим, у нас есть данные из нескольких папок с изображениями; мы можем объединить их в один набор данных:

Пример

from torch.utils.data import ConcatDataset

# Предположим, dataset1 и dataset2 — это два объекта Dataset
combined_dataset = ConcatDataset([dataset1, dataset2])
combined_loader = DataLoader(combined_dataset, batch_size=64, shuffle=True)
Другие расширения