5
4

More than 3 years have passed since last update.

AutoGluonの画像分類(Image Classification)を試してみた

Last updated at Posted at 2020-09-03

はじめに

Google Colaboratoryの環境でAutoMLのライブラリであるAutoGluon( https://autogluon.mxnet.io/index.html )の画像分類を試してみました。
基本的には公式のQuickStartの内容にプラスアルファした内容になります。

環境

Google Colaboratoryで実施しています。

実行

Google Colabの設定

画像分類の場合はDeepLearningのモデルを使用するため、GPUを使用するように設定します(下図参照)。

GoogleColab_01.png

GoogleColab_02.png

Google Colabでのライブラリインストール

上の設定だけだと、AutoGluonを動かしたときに、GPUがないとエラーがでます。
そのため、こちらの記事( https://qiita.com/tasmas/items/22cf80a4be80f7ad458e )を参考にインストールしました。特にエラーも出ず、うまくできました。


!pip uninstall -y mkl
!pip install --upgrade mxnet-cu100
!pip install autogluon
!pip install -U ipykernel

実行後にランタイムを再起動します。

AutoGluonの実行

公式のQuickStartに沿って実行していきます。
https://autogluon.mxnet.io/tutorials/image_classification/beginner.html

まずはライブラリのインポートとデータのダウンロードです。
データはKaggleにあったShopee-IETの画像データで、洋服などの画像を「BabyPants」「BabyShirt」「womencasualshoes」「womenchiffontop」の4つのカテゴリに分類するものになります。
ただし、AutoGluonのページにあるKaggleへのリンクは切れていました。
(Kaggleにもページはあるものの、ぱっとデータが見つからず。昔のコンペのデータなので、削除されてしまったのかもしれません。)

import autogluon as ag
from autogluon import ImageClassification as task

filename = ag.download('https://autogluon.s3.amazonaws.com/datasets/shopee-iet.zip')
ag.unzip(filename)

学習用のデータと評価用のデータをそれぞれ読み込みます。

train_dataset = task.Dataset('data/train')
test_dataset = task.Dataset('data/test', train=False)

学習用データを「fit」させるだけで、画像識別のモデルが構築されます。
めちゃくちゃ簡単...

classifier = task.fit(train_dataset,
                      epochs=5,
                      ngpus_per_trial=1,
                      verbose=False)

以下、fit時の標準出力結果です。
どうやらResNet50を持ってきているようです。
最終的に学習曲線も出してくれます。今回は5 epochしか学習していないので、数分で終了しました。


scheduler_options: Key 'training_history_callback_delta_secs': Imputing default value 60
scheduler_options: Key 'delay_get_config': Imputing default value True

Starting Experiments
Num of Finished Tasks is 0
Num of Pending Tasks is 2
scheduler: FIFOScheduler(
DistributedResourceManager{
(Remote: Remote REMOTE_ID: 0, 
    <Remote: 'inproc://172.28.0.2/371/1' processes=1 threads=2, memory=13.65 GB>, Resource: NodeResourceManager(2 CPUs, 1 GPUs))
})

100%
2/2 [03:58<00:00, 119.19s/it]
Model file not found. Downloading.
Downloading /root/.mxnet/models/resnet50_v1b-0ecdba34.zip from https://apache-mxnet.s3-accelerate.dualstack.amazonaws.com/gluon/models/resnet50_v1b-0ecdba34.zip...
100%|██████████| 55344/55344 [00:01<00:00, 45529.30KB/s]
[Epoch 5] Validation: 0.456: 100%
5/5 [01:06<00:00, 13.29s/it]




Saving Training Curve in checkpoint/plot_training_curves.png

autogluon_result.png

学習時におけるAccuracyは50%程度でした。今の設定じゃ仕方ないかなと思います。


print('Top-1 val acc: %.3f' % classifier.results['best_reward'])
# Top-1 val acc: 0.469

とある画像データに対して予測させてみます。「BabyShirt」のデータに対して予測させると確かに「BabyShirt」と分類されています。


image = 'data/test/BabyShirt/BabyShirt_323.jpg'
ind, prob, _ = classifier.predict(image, plot=True)

print('The input picture is classified as [%s], with probability %.2f.' %
  (train_dataset.init().classes[ind.asscalar()], prob.asscalar()))

# The input picture is classified as [BabyShirt], with probability 0.61.

評価用のデータを使ってAccuracyを計算すると70%程度でした。

test_acc = classifier.evaluate(test_dataset)
print('Top-1 test acc: %.3f' % test_acc)
# Top-1 test acc: 0.703

このような感じであっという間にモデル構築できてしまうので、本当に便利である一方、
fitの関数がやはり肝という感じがしたので、少し調べてみました。

fitについて少し調べたこと

fit関数の引数

今回は画像識別におけるfit関数を使いました。そのソースコード( https://github.com/awslabs/autogluon/blob/15c105b0f1d8bdbebc86bd7e7a3a1b71e83e82b9/autogluon/task/image_classification/image_classification.py#L63 )を下に抜粋しています。


    @staticmethod
    def fit(dataset,
            net=Categorical('ResNet50_v1b', 'ResNet18_v1b'),
            optimizer=NAG(
                learning_rate=Real(1e-3, 1e-2, log=True),
                wd=Real(1e-4, 1e-3, log=True),
                multi_precision=False
            ),
            loss=SoftmaxCrossEntropyLoss(),
            split_ratio=0.8,
            batch_size=64,
            input_size=224,
            epochs=20,
            final_fit_epochs=None,
            ensemble=1,
            metric='accuracy',
            nthreads_per_trial=60,
            ngpus_per_trial=1,
            hybridize=True,
            scheduler_options=None,
            search_strategy='random',
            search_options=None,
            plot_results=False,
            verbose=False,
            num_trials=None,
            time_limits=None,
            resume=False,
            output_directory='checkpoint/',
            visualizer='none',
            dist_ip_addrs=None,
            auto_search=True,
            lr_config=Dict(
                lr_mode='cosine',
                lr_decay=0.1,
                lr_decay_period=0,
                lr_decay_epoch='40,80',
                warmup_lr=0.0,
                warmup_epochs=0
            ),
            tricks=Dict(
                last_gamma=False,
                use_pretrained=True,
                use_se=False,
                mixup=False,
                mixup_alpha=0.2,
                mixup_off_epoch=0,
                label_smoothing=False,
                no_wd=False,
                teacher_name=None,
                temperature=20.0,
                hard_weight=0.5,
                batch_norm=False,
                use_gn=False),
            **kwargs):

引数の一つであるnetにResNet50をデフォルトで呼ぶようにしていたため、
先ほど呼ばれていたことが分かります。
では、他のモデルを試したいときに、どんなモデルを選べるのかということが疑問になります。

呼び出すモデルについて

公式ページ( https://autogluon.mxnet.io/tutorials/image_classification/hpo.html )に記載されているように、gluoncvのmodel_zoo( https://gluon-cv.mxnet.io/model_zoo/classification.html
)にあるモデルを取って来れるようです。
2020年9月4日現在の登録されているモデルは下図のようになっていました。

gluon.png

上述のResNetだけではなく、MobileNetやVGGなど、学習済みモデルがいくつかあることがわかりました。
すでにモデルがaccuracy順に並べられて表示されているので、選ぶのも楽だと思います。

自作のモデルについて

一方で、自分でNeuralNetworkを組みたい場合、AutoGluonのベースで使われているmxnetを使って作れそうです。

def mnist_net():
    mnist_net = gluon.nn.Sequential()
    mnist_net.add(ResUnit(1, 8, hidden_channels=8, kernel=3, stride=2))
    mnist_net.add(ResUnit(8, 8, hidden_channels=8, kernel=5, stride=2))
    mnist_net.add(ResUnit(8, 16, hidden_channels=8, kernel=3, stride=2))
    mnist_net.add(nn.GlobalAvgPool2D())
    mnist_net.add(nn.Flatten())
    mnist_net.add(nn.Activation('relu'))
    mnist_net.add(nn.Dense(10, in_units=16))
    return mnist_net

そのほかに、metricoptimiserも設定できるので、DeepLearningするにもやりやすいなーと思いました。

さいごに

画像系の分析だとTensorflowやkerasなどを用いて、計算ロジックを組むようなイメージがありましたが、ここまで簡単にモデル構築ができるとなると、画像データの処理(ノイズ除去や、Augmentationなど)にかけられる時間が相対的に増えそうで大変良さそうだなと思いました。

AutoGluonのベースがDeepLearningのライブラリ(あるいはプラットフォーム)のmxnetになっているので、自然言語処理(NLP)もAutoGluonでサポートしていることも納得がいきました。むしろAutoGluon-Tabularがプラスアルファな要素という感じなのでしょうか。

AutoGluonもmxnetもAWSがサポートしているので、AWSのMLサービスにはこの辺のライブラリが使われているのかな...と思いつつここまでとしたいと思います。

5
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
4