はじめに
Google Colaboratoryの環境でAutoMLのライブラリであるAutoGluon( https://autogluon.mxnet.io/index.html )の画像分類を試してみました。
基本的には公式のQuickStartの内容にプラスアルファした内容になります。
環境
Google Colaboratoryで実施しています。
実行
Google Colabの設定
画像分類の場合はDeepLearningのモデルを使用するため、GPUを使用するように設定します(下図参照)。
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
学習時における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日現在の登録されているモデルは下図のようになっていました。
上述の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
そのほかに、metric
やoptimiser
も設定できるので、DeepLearningするにもやりやすいなーと思いました。
さいごに
画像系の分析だとTensorflowやkerasなどを用いて、計算ロジックを組むようなイメージがありましたが、ここまで簡単にモデル構築ができるとなると、画像データの処理(ノイズ除去や、Augmentationなど)にかけられる時間が相対的に増えそうで大変良さそうだなと思いました。
AutoGluonのベースがDeepLearningのライブラリ(あるいはプラットフォーム)のmxnetになっているので、自然言語処理(NLP)もAutoGluonでサポートしていることも納得がいきました。むしろAutoGluon-Tabularがプラスアルファな要素という感じなのでしょうか。
AutoGluonもmxnetもAWSがサポートしているので、AWSのMLサービスにはこの辺のライブラリが使われているのかな...と思いつつここまでとしたいと思います。