【画像分類】AutoGluon の MultiModalPredictor で「dogs vs cats」をやってみる

公開日:2022年3月14日
最終更新日:2022年9月14日

はじめに

犬と猫の画像分類は何度もやってきました。
touch-sp.hatenablog.com
touch-sp.hatenablog.com
今回はMultiModalPredictorを使って挑戦したいと思います。

データの準備

こちらとおなじ方法でデータを準備しました。
このようなPandasデータフレームをpklで保存したものです。

                    image  label
0      train/cat.1799.jpg      0
1      train/cat.4663.jpg      0
2      train/cat.8728.jpg      0
3      train/cat.1804.jpg      0
4      train/cat.8125.jpg      0
...                   ...    ...
19995  train/dog.5826.jpg      1
19996  train/dog.6480.jpg      1
19997  train/dog.1344.jpg      1
19998  train/dog.4249.jpg      1
19999  train/dog.5497.jpg      1



自前のデータに対してこらからデータフレームを作る人はこちらを見て下さい。
簡単な作り方を説明しています。

学習

「AutoGluon」の名前の通りすべてが「Auto」です。
ハイパーパラメーターをまったく指定しないで実行してみます。
ここでいうハイパーパラメーターとは使用するモデル、バッチ数、エポック数、学習率などです。
もちろん指定することも可能ですが。

Pythonスクリプト

import warnings
warnings.filterwarnings('ignore')

import pandas as pd
from autogluon.multimodal import MultiModalPredictor

train_df = pd.read_pickle('train_df.pkl')

predictor = MultiModalPredictor(label="label")
predictor.fit(train_data = train_df)

predictor.save('my_saved_dir')

出力

Global seed set to 123
Auto select gpus: [0]
Using 16bit native Automatic Mixed Precision (AMP)
GPU available: True, used: True
TPU available: False, using: 0 TPU cores
IPU available: False, using: 0 IPUs
HPU available: False, using: 0 HPUs
LOCAL_RANK: 0 - CUDA_VISIBLE_DEVICES: [0]

  | Name              | Type                            | Params
----------------------------------------------------------------------
0 | model             | TimmAutoModelForImagePrediction | 86.7 M
1 | validation_metric | AUROC                           | 0
2 | loss_func         | CrossEntropyLoss                | 0
----------------------------------------------------------------------
86.7 M    Trainable params
0         Non-trainable params
86.7 M    Total params
173.491   Total estimated model params size (MB)
Epoch 0:  50%|██████████████████████████████████████▌                                      | 1375/2750 [01:44<01:44, 13.15it/s, loss=0.00438, v_num=Epoch 0, global step 70: 'val_roc_auc' reached 0.99872 (best 0.99872), saving model to '/mnt/wsl/PHYSICALDRIVE0p1/autogluon_works/AutogluonModels/ag-20220910_032736/epoch=0-step=70.ckpt' as top 3
Epoch 0: 100%|██████████████████████████████████████████████████████████████████████████████| 2750/2750 [03:31<00:00, 13.03it/s, loss=0.0403, v_num=Epoch 0, global step 141: 'val_roc_auc' reached 0.99965 (best 0.99965), saving model to '/mnt/wsl/PHYSICALDRIVE0p1/autogluon_works/AutogluonModels/ag-20220910_032736/epoch=0-step=141.ckpt' as top 3
Epoch 1:  50%|███████████████████████████████████████                                       | 1375/2750 [01:27<01:27, 15.80it/s, loss=0.0105, v_num=Epoch 1, global step 211: 'val_roc_auc' reached 0.99939 (best 0.99965), saving model to '/mnt/wsl/PHYSICALDRIVE0p1/autogluon_works/AutogluonModels/ag-20220910_032736/epoch=1-step=211.ckpt' as top 3
Epoch 1: 100%|█████████████████████████████████████████████████████████████████████████████| 2750/2750 [02:57<00:00, 15.46it/s, loss=0.00957, v_num=Epoch 1, global step 282: 'val_roc_auc' reached 0.99930 (best 0.99965), saving model to '/mnt/wsl/PHYSICALDRIVE0p1/autogluon_works/AutogluonModels/ag-20220910_032736/epoch=1-step=282.ckpt' as top 3
Epoch 2:  50%|██████████████████████████████████████▌                                      | 1375/2750 [01:29<01:29, 15.31it/s, loss=0.00037, v_num=Epoch 2, global step 352: 'val_roc_auc' was not in top 3
Epoch 2: 100%|█████████████████████████████████████████████████████████████████████████████| 2750/2750 [03:05<00:00, 14.81it/s, loss=0.00137, v_num=Epoch 2, global step 423: 'val_roc_auc' reached 0.99943 (best 0.99965), saving model to '/mnt/wsl/PHYSICALDRIVE0p1/autogluon_works/AutogluonModels/ag-20220910_032736/epoch=2-step=423.ckpt' as top 3
・
・
・
Epoch 8:  50%|███████████████████████████████████████                                       | 1375/2750 [01:39<01:39, 13.76it/s, loss=0.0146, v_num=Epoch 8, global step 1198: 'val_roc_auc' was not in top 3
Epoch 8: 100%|████████████████████████████████████████████████████████████████████████████| 2750/2750 [03:17<00:00, 13.94it/s, loss=8.77e-06, v_num=Epoch 8, global step 1269: 'val_roc_auc' was not in top 3
Epoch 9:  50%|██████████████████████████████████████                                      | 1375/2750 [01:47<01:47, 12.73it/s, loss=1.27e-05, v_num=Epoch 9, global step 1339: 'val_roc_auc' was not in top 3
Epoch 9: 100%|████████████████████████████████████████████████████████████████████████████| 2750/2750 [03:34<00:00, 12.84it/s, loss=8.18e-06, v_num=Epoch 9, global step 1410: 'val_roc_auc' was not in top 3
Epoch 9: 100%|████████████████████████████████████████████████████████████████████████████| 2750/2750 [03:35<00:00, 12.76it/s, loss=8.18e-06, v_num=]
Start to fuse 3 checkpoints via the greedy soup algorithm.
Predicting DataLoader 0: 100%|███████████████████████████████████████████████████████████████████████████████████████| 63/63 [00:03<00:00, 15.82it/s]
Predicting DataLoader 0: 100%|███████████████████████████████████████████████████████████████████████████████████████| 63/63 [00:04<00:00, 15.64it/s]
Predicting DataLoader 0: 100%|███████████████████████████████████████████████████████████████████████████████████████| 63/63 [00:04<00:00, 15.39it/s]

テストデータを用いた検証

Pythonスクリプト

import warnings
warnings.filterwarnings('ignore')

import pandas as pd
from autogluon.multimodal import MultiModalPredictor

test_df = pd.read_pickle('test_df.pkl')

predictor = MultiModalPredictor.load('my_saved_dir')

score = predictor.evaluate(test_df, metrics=["accuracy"])
print(score)

出力

Load pretrained checkpoint: my_saved_dir/model.ckpt
Predicting DataLoader 0: 100%|██████████████████████████████████████| 157/157 [00:11<00:00, 14.18it/s]
{'accuracy': 0.997}

推論

画像


Pythonスクリプト

import warnings
warnings.filterwarnings('ignore')

import pandas as pd
from autogluon.multimodal import MultiModalPredictor

predictor = MultiModalPredictor.load('my_saved_dir')

test_pic = "test1.jpg"
proba = predictor.predict_proba(pd.DataFrame({'image':[test_pic]}))
print(proba)

出力

Load pretrained checkpoint: my_saved_dir/model.ckpt
Predicting DataLoader 0: 100%|██████████████████████████████████████████| 1/1 [00:01<00:00,  1.75s/it]
              0    1
0  3.974164e-07  1.0

画像のパスをPandasデータフレームで渡すと結果はPandasデータフレームになります。


単にパスで渡すと結果はNumpy ndarrayになります。

proba = predictor.predict_proba({'image':[test_pic]})
array([[3.9741636e-07, 9.9999952e-01]], dtype=float32)

結果

ほぼ100%犬だと言っています。

さいごに

スクリプトはGitHubに公開しています。
GitHub - dai-ichiro/ImageClassification at automm

環境

Ubuntu 20.04 on WSL2 (Windows 11)
CUDA 11.3.1
python 3.8.10
pip install torch==1.12.1+cu113 torchvision==0.13.1+cu113 torchtext --extra-index-url https://download.pytorch.org/whl/cu113
pip install autogluon
autogluon==0.5.2
autogluon-contrib-nlp==0.0.1b20220208
autogluon.common==0.5.2
autogluon.core==0.5.2
autogluon.features==0.5.2
autogluon.multimodal==0.5.2
autogluon.tabular==0.5.2
autogluon.text==0.5.2
autogluon.timeseries==0.5.2
autogluon.vision==0.5.2
torch==1.12.1+cu113
torchmetrics==0.7.3
torchtext==0.13.1
torchvision==0.13.1+cu113

MultiModalPredictor関連記事

touch-sp.hatenablog.com