こしあん
2018-08-30

PyTorchでサイズの異なる画像を読み込む方法

Pocket
LINEで送る
Delicious にシェア

6.1k{icon} {views}

新刊情報

技術書典8の新刊『モザイク除去から学ぶ 最先端のディープラーニング』(A4・195ページ)好評通販中です! 機械学習の入門からGANの最先端までを書いたおすすめの本となっています! Boothで試し読みできます。情報まとめ・質問用GitHub


実際の画像判定では、MNISTやCIFARのようにサイズが完全に整形されたデータはなかなか少ないです。例えばサイズが横幅は一定でも縦幅が異なっていたりするケースがあります。訓練画像間でサイズが異なる場合、そのまま読み込みするとエラーになります。その解決法を示します。

transforms.RandomResizedCropを使おう

他にもあるかもしれませんが、ToTensor()の前にRandomResizedCropを挟むのがかなり確実ではないかと思います。自分がやった限りでは特にエラーが起きませんでした。

class torchvision.transforms.RandomResizedCrop(size, scale=(0.08, 1.0), ratio=(0.75, 1.3333333333333333), interpolation=2)
https://pytorch.org/docs/stable/torchvision/transforms.html#torchvision.transforms.RandomResizedCrop

もともとこれData Augmentation用の関数で、指定した比率のサイズ(scale)とアスペクト比(ratio)でトリミングします。例えば、縦100×横100の画像があり、scale=0.5、ratio=0.75なら縦81×横61でランダムにトリミングするようです。最終的にsizeで合わせたサイズに拡大・縮小されて出力されます。

クロップ部分の細かいことはさておいて、scale=1、ratio=1で固定すれば、入力画像をそのままリサイズするだけの関数になります。本来こっちを使いそうなtransforms.Resizeを、異なるサイズのある環境で使うとなぜかエラーになります(バグかもしれないのでそのうち改善されるかもしれません)。TorchVisionのバージョン0.2.1では、RandomResizedCropを使うとエラーは起きませんでした。

次のように使います。

import torch
from torchvision import datasets, transforms

data_transform = transforms.Compose([
     transforms.RandomResizedCrop(160, scale=(1.0, 1.0), ratio=(1.0, 1.0)), 
     transforms.ToTensor()
    ])

your_datasets = datasets.ImageFolder(root="path-to-your-dataset/train", transform=data_transform) 
loader = torch.utils.data.DataLoader(your_datasets, batch_size=100)

for batch_index, (X, y) in enumerate(loader):
    # ここに処理を書く

DataLoaderの画像を表示する

ちなみにPyTorchの画像はChannels_firstなので、Pyplotで表示するときに少し工夫がいります。np.rollaxisでChannels_lastに変換しましょう。

import numpy as np
import matplotlib.pyplot as plt

plt.plot(figsize=(10, 10))
plt.subplots_adjust(left=0.05, right=0.95, top=0.95, bottom=0.05, hspace=0.05, wspace=0.05)
for i in range(100):
    x = np.rollaxis(X[i].numpy(), 0, 3)
    plt.subplot(10, 10, i+1, xticks=[], yticks=[])
    plt.imshow(x)
plt.show()

以上です。


新刊情報

技術書典8の新刊『モザイク除去から学ぶ 最先端のディープラーニング』好評通販中(A4・195ページ)です! Boothで試し読みもできるのでよろしくね!


Pocket
LINEで送る
Delicious にシェア

Add a Comment

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です