Преобразование данных PyTorch
В PyTorch преобразование данных — это механизм обработки данных при загрузке данных, преобразующий необработанные данные в формат, подходящий для обучения модели, в основном с помощью инструментов, предоставляемых torchvision.transforms.
Преобразования данных могут не только выполнять базовую предварительную обработку данных (например, нормализацию, изменение размера и т. д.), но и помогать в аугментации данных (например, случайная обрезка, отражение и т. д.), улучшая способность модели к обобщению.
Зачем нужны преобразования данных?
Предобработка данных:
- Настройте формат, размер и диапазон данных, чтобы они подходили для ввода модели.
- Например, изображения необходимо изменить до фиксированного размера, преобразовать в формат тензора и нормализовать до [0,1].
Аугментация данных:
- Преобразуйте данные во время обучения, чтобы увеличить разнообразие.
- Например, увеличьте разнообразие выборок данных с помощью случайного поворота, отражения и обрезки, чтобы избежать переобучения.
Гибкость:
- Определяя последовательность операций преобразования, можно динамически обрабатывать данные, что упрощает сложность загрузки данных.
В PyTorch модуль torchvision.transforms предоставляет множество операций преобразования для обработки изображений.
Базовые операции преобразования
| Название функции преобразования | Описание | Пример |
|---|---|---|
| transforms.ToTensor() | Преобразует изображение PIL или массив NumPy в тензор PyTorch и автоматически нормализует значения пикселей к [0, 1]. | transform = transforms.ToTensor() |
| transforms.Normalize(mean, std) | Нормализует изображение так, чтобы данные имели нулевое среднее и единичную дисперсию. | transform = transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) |
| transforms.Resize(size) | Изменяет размер изображения, чтобы обеспечить одинаковый размер изображения для входа сети. | transform = transforms.Resize((256, 256)) |
| transforms.CenterCrop(size) | Обрезает область заданного размера из центра изображения. | transform = transforms.CenterCrop(224) |
1、ToTensor
Преобразует изображение PIL или массив NumPy в тензор PyTorch.
Также нормализует значения пикселей из [0, 255] в [0, 1].
from torchvision import transforms transform = transforms.ToTensor()
2、Normalize
Нормализует данные так, чтобы они имели заданное среднее и стандартное отклонение.
Обычно используется для данных изображений, нормализуя значения пикселей так, чтобы они имели нулевое среднее и единичную дисперсию.
transform = transforms.Normalize(mean=[0.5], std=[0.5]) # 归一化到 [-1, 1]
3、Resize
Изменяет размер изображения.
transform = transforms.Resize((128, 128)) # 将图像调整为 128x128
4、CenterCrop
Обрезает область заданного размера из центра изображения.
transform = transforms.CenterCrop(128) # 裁剪 128x128 的区域
Операции аугментации данных
| Название функции преобразования | Описание | Пример |
|---|---|---|
| transforms.RandomHorizontalFlip(p) | Случайным образом отражает изображение по горизонтали. | transform = transforms.RandomHorizontalFlip(p=0.5) |
| transforms.RandomRotation(degrees) | Случайным образом поворачивает изображение. | transform = transforms.RandomRotation(degrees=45) |
| transforms.ColorJitter(brightness, contrast, saturation, hue) | Настраивает яркость, контрастность, насыщенность и оттенок изображения. | transform = transforms.ColorJitter(brightness=0.2, contrast=0.2, saturation=0.2, hue=0.1) |
| transforms.RandomCrop(size) | Случайным образом вырезает область заданного размера. | transform = transforms.RandomCrop(224) |
| transforms.RandomResizedCrop(size) | Случайным образом обрезает изображение и изменяет его размер до указанного размера. | transform = transforms.RandomResizedCrop(224) |
1、RandomCrop
Случайным образом вырезает из изображения область заданного размера.
transform = transforms.RandomCrop(128)
2、RandomHorizontalFlip
Отражает изображение по горизонтали с некоторой вероятностью.
transform = transforms.RandomHorizontalFlip(p=0.5) # 50% 概率翻转
3、RandomRotation
Поворачивает на случайный угол.
transform = transforms.RandomRotation(degrees=30) # 随机旋转 -30 到 +30 度
4、ColorJitter
Случайным образом изменяет яркость, контрастность, насыщенность или оттенок изображения.
transform = transforms.ColorJitter(brightness=0.5, contrast=0.5)
Композиция преобразований
| Название функции преобразования | Описание | Пример |
|---|---|---|
| transforms.Compose() | Объединяет несколько преобразований вместе и применяет их последовательно по порядку. | transform = transforms.Compose([transforms.ToTensor(), transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]), transforms.Resize((256, 256))]) |
Объедините несколько преобразований с помощью transforms.Compose.
transform = transforms.Compose([
transforms.Resize((128, 128)),
transforms.RandomHorizontalFlip(p=0.5),
transforms.ToTensor(),
transforms.Normalize(mean=[0.5], std=[0.5])
])
Пользовательские преобразования
Если функциональность, предоставляемая transforms, не может удовлетворить требования, её можно реализовать с помощью пользовательских классов или функций.
Пример
def __call__(self, x):
# Здесь можно настроить любую логику преобразования
return x * 2
transform = CustomTransform()
Пример
Применение преобразований к наборам данных изображений
Загрузите набор данных MNIST и примените преобразования.
Пример
from torch.utils.data import DataLoader
# Определите преобразования
transform = transforms.Compose([
transforms.Resize((128, 128)),
transforms.ToTensor(),
transforms.Normalize(mean=[0.5], std=[0.5])
])
# Загрузка набора данных
train_dataset = datasets.MNIST(root='./data', train=True, transform=transform, download=True)
# Использовать DataLoader
train = DataLoader(dataset=train_dataset, batch_size=32, shuffle=True)
# Просмотр преобразованных данных
for images, labels in train_loader:
print("Размер тензора изображения:", images.size()) # [batch_size, 1, 128, 128]
break
Результат вывода:
图像张量大小: torch.Size([32, 1, 128, 128])
Визуализация эффектов преобразования
Следующий код показывает сравнение между исходными данными и преобразованными данными.
Пример
from torchvision import datasets
from torchvision import datasets, transforms
# Визуализация исходных и аугментированных изображений
transform_augment = transforms.Compose([
transforms.RandomHorizontalFlip(),
transforms.RandomRotation(30),
transforms.ToTensor()
])
# Загрузка набора данных
dataset = datasets.MNIST(root='./data', train=True, download=True, transform=transform_augment)
# Показать изображения
def show_images(dataset):
fig, axs = plt.subplots(1, 5, figsize=(15, 5))
for i in range(5):
image, label = dataset[i]
axs[i].imshow(image.squeeze(0), cmap='gray') # Преобразовать (1, H, W) в (H, W)
axs[i].set_title(f"Label: {label}")
axs[i].axis('off')
plt.show()
show(dataset)
Отображение выглядит следующим образом:
