こしあん
2018-08-30

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

実際の画像判定では、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()

以上です。

Related Posts

データのお気持ちを考えながらData Augmentationする... Data Augmentationの「なぜ?」に注目しながら、エラー分析をしてCIFAR-10の精度向上を目指します。その結果、オレオレAugmentationながら、Wide ResNetで97.3%という、Auto Augmentとほぼ同じ(-0.1%)精度を出すことができました。 (※すご...
Chainerで画像の前処理やDataAugmentationをしたいときはDatasetMixin... Chainerにはデフォルトでランダムクロップや標準化といった、画像の前処理やDataAugmentation用の関数が用意されていません。別途のChainer CVというライブラリを使う方法もありますが、chainer.dataset.DatasetMixinを継承させて独自のデータ・セットを定...
keras_preprocessingを使ってお手軽に画像を回転させる方法... Data Augmentationで画像を回転させたいことがあります。画像の回転は一般に「アフィン変換」と呼ばれる操作で、OpenCVやPillowのライブラリを使えば簡単にできるのですが、Numpy配列に対して1から書くとかなりめんどいのです。Kerasが裏で使っているkeras_preproc...
OpenCVで画像を歪ませる方法 PythonでOpenCVを使い画像を歪ませる方法を考えます。アフィン変換というちょっと直感的に理解しにくいことをしますが、慣れればそこまで難しくはありません。ディープラーニングのData Augmentationにも使えます。 OpenCVでのアフィン変換のイメージ アフィン変換というと、ま...
PandasのDataFrameでグループ別にサンプルをN個抜き出す方法... 「PandasでGroupbyでグルーピングしたはいんだけど、そこからグループ別にサンプルを1個、2個…と抜き出す、SQLでよくやるやつってどうやるんだっけ?」ということが気になったので、調べました。ちゃんとした方法があります。 例題 今、中国地方と四国地方の県と面積をDataFrameにして...

Add a Comment

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