※当サイトではアフィリエイト広告を利用しています。

機械学習

【pytorch】transformを実装する方法

こんにちは、タナカです。

この記事では、pytorchのtansformの実装方法を説明します。

対象となる読者
  • pytorchを使って機械学習をしたい人
  • transformについて理解したい人
  • pytorchを使ってtransformを実装したい人

pytorchは機械学習をするためのフレームワークの一つです。フレームワークとは、機械学習をするための道具が入った四次元ポケットみたいなものです。

または、機械学習をするためのライブラリといってもいいでしょう。

pytorchを使えば、畳み込み演算や重みの更新など非常に複雑な計算式を1から自分でコーディングする必要がなく、機械学習を実装することができます。

とは言え、pytorchの使い方を覚える必要があります。

今回は、pytorchの中でも前処理の役割を担うtransformの実装方法について説明します。

ではいきましょう。

この記事の内容
  • pytorchでtransformを実装する方法がわかる

1. pytorchを準備する

まずはじめにpytorchをインストールする必要があります。

コマンドプロンプトやターミナル、anaconda promptなどで下記のように入力してpytorchをインストールします。

pip install pytorch
pip install torchvision

2. transformとは

transformとは前処理を実行するために作成したモジュールになります。

モジュールというと少し難しく感じるかもしれませんが、簡単に言うと前処理職人が集まってそれぞれが出店を開いているイメージです。余計わかりづらかったらすみません。

transform-image

例えば、imgくんがリサイズという前処理を受けることで、画像のサイズを小さくしたり、大きくしたりすることができます。

前処理には、リサイズや反転など上で示した以上にたくさんのものが存在しています。

前処理の用途ですが、一般的には画像の水増しなどに用いられることが多いです。

3. transformを実装する

ここからは実際にtransformを実装していきたいと思います。

今回はクラスを使って記述していきます。

from torchvision import transforms

class MyTransform():
    def __init__(self):
        pass

    def __call__(self, img, key):
        self.transform = {
            'train': transforms.Compose([
                transforms.RandomVerticalFlip(),

            ]),
            'test': transforms.Compose([
                transforms.ToTensor()
            ])
        }
        return self.transform[key](img)

 

初めにtransformを実装するためのライブラリをインストールします。torchvisionというライブラリの中にあるtransformsになります。

MyTransformはクラス名です。ここはご自身の好きな名前を付けることができますが、一般的にクラス名を作る場合は、先頭文字を大文字にすることが多いです。

私がtransformを作る際は、前処理をコンストラクタに記載せずに__call__()メソッドに記載していきます。

__call__()メソッドはtransformをインスタンスで生成した後に関数のように使用することができるものです。言葉だと分かりづらいので、実際に使って説明していきます。

# ex)
from PIL import Image
import matplotlib.pyplot as plt

img = Image.open('apple-1834639_640.jpg')

# transformのインスタンスを生成
transform = MyTransform()

img_after = transform(img, key = 'train')

plt.imshow(img_after)
plt.show()
apple-comp

transformの引数に元々の画像とkeyを入力します。keyはtrainとtestによって前処理を変更したいので、指定できるようにしています。

__call__()メソッドの話に戻しますが、transformというインスタンスに引数を与えることで処理を実行できるものになります。

今回の場合は、ランダムで画像の上下を反転することができる前処理を実行しています。ランダムなので、反転したり、しなかったりします。

transforms.Composeは、その引数として、前処理を渡してあげると、渡された順番で処理を実行する関数になります。Compose以外にもあるそうですが、タスクに合わせて変更するのがいいのではないでしょうか。

私は、Compose以外使ったことがないです。

それでは、他にも前処理を増やして実行したいと思います。上下反転の他にもリサイズや回転などがあるので、追加したいと思います。self.transformの中を下記のように変更しました。

    def __call__(self, img, key):
        self.transform = {
            'train': transforms.Compose([
                transforms.ColorJitter(brightness = 0.2, contrast = 0.2),
                transforms.RandomHorizontalFlip(),
                transforms.RandomVerticalFlip(),
                transforms.RandomRotation(degrees = 45),

            ]),
            'test': transforms.Compose([
                transforms.ToTensor()
            ])
        }
        return self.transform[key](img)

 

これを実行した結果がこちらになります。

このようにある元々の画像に対して、画像処理を加えて別の画像に変換することができるのがtransformになります。

機械学習では、画像が違えば同じような見た目でも全く違うものとみなすことができるため、水増しになるということです。

 

最後に機械学習に通す場合は、基本的にtensor化させる必要があるため、Composeの中に下記コードを追加します。

transforms.ToTensor()

 

これは、tensor化しつつ、画像を255で割って、チャンネルファーストに変換する優れものです。実際に使う方法については、分類問題など別の記事で書きたいと思います。

まとめ

この記事では、機械学習の前処理の役割を担うtransformについて説明しました。

transformは自作できるとかなり使い勝手よく、様々なタスクに応用できると思います。