PyTorch データ変換

PyTorch では、データ変換(Data Transformation)は、データを読み込む際にデータを処理するメカニズムであり、元のデータをモデルのトレーニングに適した形式に変換します。主に 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 が提供する機能で要件を満たせない場合は、カスタムクラスまたは関数で実装できます。

例

class CustomTransform:
    def __call__(self, x):
        # ここで任意の変換ロジックをカスタマイズできます
        return x * 2

transform = CustomTransform()

例

画像データセットへの変換の適用

MNIST データセットを読み込み、変換を適用します。

例

from torchvision import datasets, transforms
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_loader = 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])

変換効果の可視化

次のコードは、元のデータと変換後のデータの比較を示しています。

例

import matplotlib.pyplot as plt
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_images(dataset)

表示は次のようになります:

その他の拡張