Programming Lab PR

PyTorchのTransformを使い方|自作Transformの作成方法も解説

記事内に商品プロモーションを含む場合があります

PyTorchのTransformを使い方|自作Transformの作成方法も解説

 

 

  • Transformが何をやっているかよくわからない…
  • Transformを一度体系的に学びたい

本記事では、その悩みを徹底的に解決します。

Transformを使用することで、高度な前処理を簡単に実装することができます。

また、PyTorchはカスタマイズ性が高く、複数の前処理を同時に行ったり、自分で定義した関数を容易に使用することができます。

一見、Transformは複雑に感じますが、一度習得してしまうとなくてはならない存在になります。

 

 

PyTorchのTransformの使い方

 

PyTorchでデータを前処理する場合、『transforms』パッケージを使用します。

transformsを利用することで簡単に画像の前処理ができます。

実際に、具体的な使用方法を以下の順番で解説していきます。

  1. torchvision.transformsから使用する前処理のクラスをインスタンス化
  2. 画像に対して前処理を実行

 

transformsパッケージから使用する前処理のクラスをインスタンス化

 

まずは、transformsパッケージから画像に対して使用する前処理のクラスをインスタンス化します。

具体的には以下のように行います。

# インスタンス化
使用するtransforms = transforms.使用するtransforms()

 

よくわからない方は、この後、画像やTensorに対して具体的に前処理を行うため、そのタイミングで理解できます!

そもそもTensorがよくわからないという方は下記を一読してから先に進んでください。

 

【Pytorch】tensor型とは|知らないとまずいものをまとめてみたPyTorchのTensorに関してまとめてみました。この中で紹介しているTensorの関数やメソッドは、どれもPytorchで深層学習を実装する際に必要不可欠なものばかりです。15分程度で読み終わるので一読して頭を整理させましょう。...

 

画像に対して前処理を実行

 

インスタンス化した前処理を画像に対して実行していきます。

具体的には、以下で実行します。

前処理された画像 = 前処理のインスタンス(画像)

 

これで前処理を施すことができます。

TransformsはDatasetパッケージと同時に使用することで威力を発揮します。

Datasetについて学びたい方は下記を参考にしてください。

 

【必読】PyTorchのDatasetの使い方|カスタム(自作)Datasetも作成できる!PyTorchのDataset作成方法を徹底的に解説しました。本記事を読むことで、Numpy, PandasからDatasetを作成したり、自作のDatasetを作成しモジュール化する作業を初心者の方でも理解できるように徹底的に解説しました。...

 

 

Transformsの種類

 

Transformsには以下の2種類があります。

  1. 画像データを変換
  2. Tensorを変換

 

本記事では、画像データを変換する方法を説明してからTensorを変換する方法を説明していきます。

 

 

サンプルデータをロード

 

今回使用するサンプルデータをロードしましょう。

下記のコードを実行してください。

cifar10 = torchvision.datasets.CIFAR10(root='cifar10_root', train=True, download=True)

 

これでCifar10というデータをインポートすることができました。

このDatasetのうち一枚の画像を今回は使用します。

使用する画像を下記のコードで確認してみましょう。

 

<Input>

image, label = cifar10[0]

fig, ax = plt.subplots(figsize=(6, 6))
ax.imshow(image)
ax.set_title('cifar10, label=6', fontsize=15)
ax.axis('off')
plt.show()

 

<Output>

サンプルデータ

この蛙の画像を使用します。

 

画像を変換するためのTransform

 

ここでは、画像を変換する主要なTransformを説明していきます。

  1. RandomAffine : ランダムにアフィン変換を行う
  2. RandomHorizontalFlip : 確率pで水平方向に反転
  3. RandomVerticalFlip : 確率pで垂直方向に反転
  4. RandomRotation : ランダムな角度で回転
  5. Grayscale : グレイスケールに変換
  6. ToTensor ; PIL image, Numpy配列をTensorに変換

 

まずは、具体例を3枚表示するための関数をあらかじめ定義してください。

def plot_figs(image0, image1, image2):
    fig, axes = plt.subplots(1, 3, figsize=(18, 6))
    axes[0].imshow(image0)
    axes[1].imshow(image1)
    axes[2].imshow(image2)
    axes[0].axis('off')
    axes[1].axis('off')
    axes[2].axis('off')
    plt.show()

 

 

RandomAffine : ランダムにアフィン変換を行う

 

RandomAffineクラスを使って画像をランダムにアフィン変換を施すことができます。

RandomAffine  
degree (-degree, degree)で回転角度を指定
translate (x方向の移動, y方向の移動)を指定
scale (scaleの最小値, scaleの最大値)を指定
shear (-x軸に対するせん断の角度, x軸に対するせん断の角度)を指定 

 

下記に具体的なコードを示します。

<Input>

affine1 = transforms.RandomAffine(degrees=(-30, 30), scale=(0.5, 2.5))
affine2 = transforms.RandomAffine(degrees=(-30, 30), translate=(0.1, 0.1), scale=(0.5, 1.5), shear=(-0.1, 0.1))

image_affine1 = affine1(image)
image_affine2 = affine2(image)

plot_figs(image, image_affine1, image_affine2)

 

<Output>

RandomAffine変換

 

RandomHorizontalFlip : 確率pで水平方向に反転

 

RandomHorizontalFlipクラスを使用することで、確率pで水平方向に反転を行うことができます。

 

RandomHorizontalFlip  
p 水平方向に反転する確率

 

具体的なコードを下記に示します。

<Input>

hflip1 = transforms.RandomHorizontalFlip(p=0.8)

image_hflip1 = hflip1(image)
image_hflip2 = hflip1(image)

plot_figs(image, image_hflip1, image_hflip2)

 

<Output>

HorizontalFlip変換

 

RandomVerticalFlip : 確率pで垂直方向に反転

 

RandomVerticalFlipクラスを使用することで、確率pで垂直方向に反転を行うことができます。

 

RandomVerticalFlip  
p 垂直方向に反転する確率

 

具体的なコードを下記に示します。

<Input>

vflip1 = transforms.RandomVerticalFlip(p=0.8)

image_vflip1 = vflip1(image)
image_vflip2 = vflip1(image)

plot_figs(image, image_vflip1, image_vflip2)

 

<Output>

VerticalFlip変換

 

RandomRotation : ランダムな角度で回転

 

RandomRotationクラスで、画像をランダムな角度で回転させることができます。

 

RandomRotation  
degree (-degree, degree)で回転させる角度を指定
center 回転させる中心位置を指定
expand Trueにすると回転した画像が収まるように出力する

 

具体的なコードを下記に示します。

<Input>

rotation1 = transforms.RandomRotation(90)
rotation2 = transforms.RandomRotation(degrees=(-90, 90), center=(0,0), expand=True)

image_rotated1 = rotation1(image)
image_rotated2 = rotation2(image)

plot_figs(image, image_rotated1, image_rotated2)

 

<Output>

RandomRotation変換

 

Grayscale : グレイスケールに変換

 

Grayscaleクラスを使用することで画像をグレイスケールに変換することができます。

 

Grayscale  
num_output_channels 出力チャネル数

 

<Input>

gray1 = transforms.Grayscale(num_output_channels=1)
gray2 = transforms.Grayscale(num_output_channels=3) 

image_gray1 = gray1(image)
image_gray2 = gray2(image)

plot_figs(image, image_gray1, image_gray2)

 

<output>

Grayscale変換

 

ToTensor : PIL image, Numpy配列をTensorに変換

 

ToTensorクラスは、PIL Image, Numpy配列をTensorに変換するとができます。

画像の場合、PIL Imageだと(高さ, 幅, チャネル)で画素値が[0, 255]を(チャネル, 幅, 高さ)で画素値が[0, 1.0]のTensorに変換します。

具体的なコードを下記に示します。

totensor = transforms.ToTensor()
tensor = totensor(image)

 

実際にTensorの形状を確認してみます。

 

<Input>

print(tensor.size())

 

<Output>

torch.Size([3, 32, 32])

 

(チャネル, 高さ, 幅)の配列に変換されました。

 

Tensorを変換するためのTransform

 

ここからは、Tensorを変換するためのTransformを説明していきます。

基本的な使い方は、画像を変換するときと変わりません。

 

Normalize : 指定した平均, 標準偏差でTensorを正規化

 

Normalizeクラスを使用することで、指定した平均, 標準偏差でTensorを正規化することができます。

 

Normalize  
mean 各チャネルの平均
std 各チャネルの標準偏差

 

norm = transforms.Normalize(mean=[0, 0, 0], std=[1.0, 1.0, 1.0])
normed_tensor = norm(tensor)

 

 

ToPILImage : Tensorを画像に変換

 

ToPILImageを使用することでTensorを画像に変換することができます。

 

<Input>

PIL = transforms.ToPILImage()
image = PIL(tensor)

fig, ax = plt.subplots(figsize=(6, 6))
ax.imshow(image)
ax.axis('off')
plt.show()

 

<Output>

PILに変換

 

複数のTransformerを実行する

 

複数のTransformerを実行する方法を説明していきます。

 

Compose : 複数のTransformを前から実行

 

Composeクラスを使用することで、複数のTransformを前からまとめて実行することができます。

具体的なコードを下に示します。

 

<Input>

affine = transforms.RandomAffine(degrees=(-10, 10), scale=(0.9, 1.1))
totensor = transforms.ToTensor()
normalize = transforms.Normalize((0.0, 0.0, 0.0), (1.0, 1.0, 1.0))  

trans = transforms.Compose([affine, totensor, normalize])
data = trans(image)

print(data.size())

 

<Output>

torch.Size([3, 32, 32])

 

これで複数のTransformを実行することができます。

他にもランダムにTransformを実行するRandomApplyやRandomChoice等もありますが、ほとんど使用しません。

 

自作Transformを作成する

 

自分で関数を定義し、Lambdaに渡すことで自作のTransformを作成することができます。

具体的なコードを下記に示します。

<Input>

# 自作関数
def square(x):
    x = x**2
    return x

# sample
data = torch.tensor([1, 2, 3, 4])

# Lambdaクラスを使用
square = transforms.Lambda(square)
squared_data = square(data)

print(squared_data)

 

<Output>

tensor([ 1,  4,  9, 16])

 

まとめ

 

PyTorchのTransformsパッケージを徹底解説しました。

transformをdatasetの引数に設定するだけで高度な前処理を簡単に行うことができます。

また、ComposeクラスやLambdaクラスを使用することでカスタマイズ性は格段に上がります。

本記事が皆様にって有益であると幸いです。

『深層学習を実装したい!』という方は下記を参考にしてください

 

【入門】PyTorchの使い方をMNIST画像分類で学ぶ|初心者でも理解可能!本記事では、MNISTデータセットを利用して、PyTorchの実装の流れを紹介しました。本記事を通して読めば、PyTorchを実務で使用するイメージが確実に身につくと思います。...

 

ABOUT ME
努力のガリレオ
【運営者】 : 東大で理論物理を研究中(経歴)東京大学, TOEIC950点, NASA留学, カナダ滞在経験有り, 最優秀塾講師賞, オンライン英会話講師試験合格, ブログと独自コンテンツで収益6桁達成 【編集者】: イングリッシュアドバイザーとして勤務中(経歴)中学校教諭一種免許取得[英語],カナダ留学経験あり, TOEIC650点
Python学習を効率化させるサービス

 

Pythonを学習するのに効率的なサービスを紹介していきます。

まず最初におすすめするのは、Udemyです。

Udemyは、Pythonに特化した授業がたくさんあり、どの授業も良質です。

また、セール中は1500円定義で利用することができ、コスパも最強です。

下記の記事では、実際に私が15個以上の講義を受講して特におすすめだった講義を紹介しています。

 

【最新】UdemyでおすすめのPythonコース|東大生が厳選!10万を超える講座があるUdemyの中で、Pythonに関係する講座を厳選しました。また、本記事では、Udemyを使用しながらPythonをどのような順番で勉強するべきかを紹介しました。ぜひ参考にしてください。...

 

他のPythonに特化したオンライン・オフラインスクールも下記の記事でまとめています。

 

【最新】Pythonに強いプログラミングスクール7選|東大生が厳選Pythonの流行と共に、Pythonに強いプログラミングスクールが増えてきました。本記事では、特にPythonを効率的に学ぶことができるプログラミングスクールを経験をもとに厳選して、内容を詳しく解説しています。...

 

自分の学習スタイルに合わせて最適なものを選びましょう。

また、私がPythonを学ぶ際に使用した本を全て暴露しているので参考にしてください。