MXNet チュートリアル : 画像分類 (翻訳/解説)
翻訳 : (株)クラスキャット セールスインフォメーション
日時 : 02/24/2017
* 本ページは、MXNet 本家サイトの Image Classification Tutorial を翻訳した上で適宜、補足説明したものです:
http://mxnet.io/tutorials/computer_vision/image_classification.html
Image Classification – 畳込みニューラルネットワークを使用して現実世界の物体の様々な画像を分類する例です。
* サンプルコードの動作確認はしておりますが、適宜、追加改変しています。
序
このチュートリアルでは、画像に信頼スコア (confidence scores) でラベルを割り当てます。
このチュートリアルのためのソースコードは GitHub から得てください。
トレーニング
特定のデータセット上でモデルをトレーニングするには、$train\_dataset.py$ を使用します。例えば :
- mnist で MLP をトレーニングするためには、このコマンドを使用します :
python train_mnist.py
- 各 epoch でモデルをセーブするためには、このコマンドを使用します :
mkdir model; python train_mnist.py --model-prefix model/mnist
- epoch 8 でセーブされたモデルからトレーニングを再開するためには、このコマンドを使用します :
python train_mnist.py --model-prefix model/mnist --load-epoch 8
- 他の初期学習率を選択して全ての half epoch 毎に 0.9 で減衰させるためには、このコマンドを使用します :
python train_mnist.py --lr .1 --lr-factor .9 --lr-factor-epoch .5
- mnist 上で畳込みニューラルネットワークを GPU 0 を使用してトレーニングするためには、このコマンドを使用します :
python train_mnist.py --network lenet --gpus 0
- 複数の GPU を使用するためには、リストを指定します; 例えば : —gpus 0,1,3.
- 更なるオプションを見るには、–help を使用してください。
* 訳注 : 以下は mnist を mlp モデルで 20 epochs トレーニングした際のログです。checkpoint の保存もしています :
2017-02-25 09:49:14,148 Node[0] start with arguments Namespace(batch_size=64, disp_batches=100, gpus=None, kv_store='device', load_epoch=None, lr=0.05, lr_factor=0.1, lr_step_epochs='10', model_prefix='models/mnist', mom=0.9, monitor=0, network='mlp', num_classes=10, num_epochs=20, num_examples=60000, num_layers=None, optimizer='sgd', test_io=0, top_k=0, wd=0.0001) 2017-02-25 09:49:15,006 Node[0] Epoch[0] Batch [100] Speed: 17758.14 samples/sec Train-accuracy=0.780322 2017-02-25 09:49:15,368 Node[0] Epoch[0] Batch [200] Speed: 17706.37 samples/sec Train-accuracy=0.900156 2017-02-25 09:49:15,700 Node[0] Epoch[0] Batch [300] Speed: 19271.93 samples/sec Train-accuracy=0.924531 2017-02-25 09:49:16,033 Node[0] Epoch[0] Batch [400] Speed: 19212.92 samples/sec Train-accuracy=0.934375 2017-02-25 09:49:16,387 Node[0] Epoch[0] Batch [500] Speed: 18120.87 samples/sec Train-accuracy=0.944531 2017-02-25 09:49:16,729 Node[0] Epoch[0] Batch [600] Speed: 18689.96 samples/sec Train-accuracy=0.948906 2017-02-25 09:49:17,065 Node[0] Epoch[0] Batch [700] Speed: 19040.31 samples/sec Train-accuracy=0.950469 2017-02-25 09:49:17,418 Node[0] Epoch[0] Batch [800] Speed: 18180.69 samples/sec Train-accuracy=0.952812 2017-02-25 09:49:17,770 Node[0] Epoch[0] Batch [900] Speed: 18162.74 samples/sec Train-accuracy=0.950156 2017-02-25 09:49:17,897 Node[0] Epoch[0] Train-accuracy=0.954814 2017-02-25 09:49:17,898 Node[0] Epoch[0] Time cost=3.281 2017-02-25 09:49:17,910 Node[0] Saved checkpoint to "models/mnist-0001.params" 2017-02-25 09:49:18,181 Node[0] Epoch[0] Validation-accuracy=0.960291 ... 2017-02-25 09:50:22,608 Node[0] Epoch[19] Batch [100] Speed: 19424.26 samples/sec Train-accuracy=1.000000 2017-02-25 09:50:22,965 Node[0] Epoch[19] Batch [200] Speed: 17954.07 samples/sec Train-accuracy=0.999844 2017-02-25 09:50:23,365 Node[0] Epoch[19] Batch [300] Speed: 15995.49 samples/sec Train-accuracy=0.999687 2017-02-25 09:50:23,708 Node[0] Epoch[19] Batch [400] Speed: 18690.76 samples/sec Train-accuracy=0.999687 2017-02-25 09:50:24,063 Node[0] Epoch[19] Batch [500] Speed: 18027.42 samples/sec Train-accuracy=0.999844 2017-02-25 09:50:24,400 Node[0] Epoch[19] Batch [600] Speed: 19009.43 samples/sec Train-accuracy=1.000000 2017-02-25 09:50:24,735 Node[0] Epoch[19] Batch [700] Speed: 19087.96 samples/sec Train-accuracy=0.999531 2017-02-25 09:50:25,098 Node[0] Epoch[19] Batch [800] Speed: 17637.86 samples/sec Train-accuracy=0.999687 2017-02-25 09:50:25,456 Node[0] Epoch[19] Batch [900] Speed: 17902.30 samples/sec Train-accuracy=0.999375 2017-02-25 09:50:25,581 Node[0] Epoch[19] Train-accuracy=1.000000 2017-02-25 09:50:25,581 Node[0] Epoch[19] Time cost=3.304 2017-02-25 09:50:25,591 Node[0] Saved checkpoint to "models/mnist-0020.params" 2017-02-25 09:50:25,832 Node[0] Epoch[19] Validation-accuracy=0.983678
以下は GPU 上でのトレーニングのログです :
INFO:root:start with arguments Namespace(batch_size=64, disp_batches=100, gpus='0', kv_store='device', load_epoch=None, lr=0.05, lr_factor=0.1, lr_step_epochs='10', model_prefix=None, mom=0.9, monitor=0, network='mlp', num_classes=10, num_epochs=20, num_examples=60000, num_layers=None, optimizer='sgd', test_io=0, top_k=0, wd=0.0001) INFO:root:Epoch[0] Batch [100] Speed: 49910.28 samples/sec Train-accuracy=0.774288 INFO:root:Epoch[0] Batch [200] Speed: 52118.94 samples/sec Train-accuracy=0.911875 INFO:root:Epoch[0] Batch [300] Speed: 49846.52 samples/sec Train-accuracy=0.931250 INFO:root:Epoch[0] Batch [400] Speed: 52170.39 samples/sec Train-accuracy=0.937500 INFO:root:Epoch[0] Batch [500] Speed: 50266.65 samples/sec Train-accuracy=0.944375 INFO:root:Epoch[0] Batch [600] Speed: 48508.34 samples/sec Train-accuracy=0.946562 INFO:root:Epoch[0] Batch [700] Speed: 48906.84 samples/sec Train-accuracy=0.947969 INFO:root:Epoch[0] Batch [800] Speed: 51169.35 samples/sec Train-accuracy=0.950937 INFO:root:Epoch[0] Batch [900] Speed: 50815.89 samples/sec Train-accuracy=0.956094 INFO:root:Epoch[0] Train-accuracy=0.956503 INFO:root:Epoch[0] Time cost=1.477 INFO:root:Epoch[0] Validation-accuracy=0.956011 ... INFO:root:Epoch[19] Batch [100] Speed: 51768.25 samples/sec Train-accuracy=0.999691 INFO:root:Epoch[19] Batch [200] Speed: 52185.71 samples/sec Train-accuracy=0.999531 INFO:root:Epoch[19] Batch [300] Speed: 48955.09 samples/sec Train-accuracy=0.999531 INFO:root:Epoch[19] Batch [400] Speed: 50415.05 samples/sec Train-accuracy=1.000000 INFO:root:Epoch[19] Batch [500] Speed: 49099.71 samples/sec Train-accuracy=1.000000 INFO:root:Epoch[19] Batch [600] Speed: 49625.81 samples/sec Train-accuracy=0.999375 INFO:root:Epoch[19] Batch [700] Speed: 51004.17 samples/sec Train-accuracy=0.999844 INFO:root:Epoch[19] Batch [800] Speed: 50453.24 samples/sec Train-accuracy=0.999844 INFO:root:Epoch[19] Batch [900] Speed: 50429.83 samples/sec Train-accuracy=1.000000 INFO:root:Epoch[19] Train-accuracy=1.000000 INFO:root:Epoch[19] Time cost=1.190 INFO:root:Epoch[19] Validation-accuracy=0.982484
分散トレーニング
トレーニングを速くするためには、複数のコンピュータを使用してモデルをトレーニングします。
- 2つの workers を使用してローカル・コンピュータ上で分散トレーニングを素早くテストします :
../../tools/launch.py -n 2 python train_mnist.py --kv-store dist_sync
* 訳注: このテストは正常には実行できませんでした。
SGD dist_sync あるいは asynchronous SGD dist_async を利用することができます。
- SSH を使って接続可能な幾つかのコンピュータを持つならば、そしてこの mxnet フォルダが(NFS としてマウントされ、tutorial for Ubuntu 参照)これらのコンピュータ上でアクセス可能であるならば、最初にそれらのホスト名をファイルに保存することでこれらのコンピュータ上でジョブを実行します、例えば :
$ cat hosts 172.30.0.172 172.30.0.171
- それからこのファイルを -H で渡します :
../../tools/launch.py -n 2 -H hosts python train_mnist.py –kv-store dist_sync
- もし mxnet フォルダが他のコンピュータで利用可能でないならば、mxnet ライブラリをこの examples フォルダにコピーします :
cp -r ../../python/mxnet . cp -r ../../lib/libmxnet.so mxnet
それから実行する前に他のコンピュータ /tmp/mxnet にフォルダを同期します :
../../tools/launch.py -n 2 -H hosts --sync-dir /tmp/mxnet python train_mnist.py --kv-store dist_sync
更なる launch オプション、例えば、YARN を使う、そして分散トレーニング・プログラムをどうのように書くかについての情報については、この チュートリアル を参照してください。
予測を生成する
予測を生成するためには幾つかのオプションがあります :
- pre-trained モデル を使用する。更なる pre-trained モデルは モデル・ギャラリ で提供されます。
- 貴方自身のデータセットを使う。
- Android/iOS のような様々なデバイス上で予測を簡単に実行することもできます。
貴方自身のデータセットを使用する
MXNet にデータを供給するためには2つの方法があります :
- 全てのサンプルを一つあるいはそれ以上のコンパクトな $recordio$ ファイルにパックします。更なる情報については、この step-by-step チュートリアル と documentation を参照してください。パッキングの間に画像リストをシャッフルすることを見過ごす一般的なミスを回避します。これはトレーニングを失敗させる原因となります。例えば、軽度は幾つかのラウンドで 0.001 を保持します。
Note: mnist と cifar10 のような小さなデータセットは自動的にダウンロードします。
- メモリに簡単にロードできる小さなデータセットについては、ここに例を示します :
from sklearn.datasets import fetch_mldata from sklearn.utils import shuffle mnist = fetch_mldata('MNIST original', data_home="./mnist") # shuffle data X, y = shuffle(mnist.data, mnist.target) # split dataset train_data = X[:50000, :].astype('float32') train_label = y[:50000] val_data = X[50000: 60000, :].astype('float32') val_label = y[50000:60000] # Normalize data train_data[:] /= 256.0 val_data[:] /= 256.0 # create a numpy iterator batch_size = 100 train_iter = mx.io.NDArrayIter(train_data, train_label, batch_size=batch_size, shuffle=True) val_iter = mx.io.NDArrayIter(val_data, val_label, batch_size=batch_size) # create model as usual: model = mx.model.FeedForward(...) model.fit(X = train_iter, eval_data = val_iter)
パフォーマンスを改善する
次の要因が本質的にパフォーマンスを改善します :
- CPU プロセッサを使用している場合に限っては高速なバックエンド。高速な BLAS ライブラリ, e.g., openblas, atlas, 及び mkl, が必要です。Nvidia GPU のためには、CUDNN を使用することを強く推奨します。
- 入力データ :
- データ・フォーマット。$rec$ フォーマットを使用します。
- デコードに使用されるスレッドの数。デフォルトでは、MXNet は 4 CPU スレッドを画像デコードのために使用し、これは秒毎に 1 Kb 画像以上をしばしばデコードできます。ローエンドな CPU あるいは非常にパワフルな GPU を使用しているのであれば、スレッドの数を増やすことができます。
- データ・ストレージの位置。任意のローカルあるいは分散ファイルシステム (HDFS, Amzon S3) は優れているでしょう。もし複数のコンピュータが network shared file system (NFS) から同時にデータを読む場合には、けれども、問題に遭遇するかもしれません。
- バッチサイズ。GPU メモリが収容できる最大のサイズを使用することを勧めます。大き過ぎる値は収束を遅くするかもしれません。安全なバッチサイズは CIFAR 10 のためにはおよそ 200; ImageNet のためには 1K、バッチサイズは 1 Kb を超えられます。
- もし一つ以上の GPU を使用しているならば、正確な (= right ) kvstore。更なる情報のためには、このガイド を参照。
- 単一のコンピュータのためには、デフォルトの `local` でしばしば十分です。100 MB より大きいモデルのためには、AlexNet と VGG のような、local_allreduce_device を使用することを望むかもしれません。local_allreduce_device は他のオプションよりも GPU メモリをより使用します。
- 複数のコンピュータのためには、最初に `dist_sync` を使用することを試みることを勧めます。モデルが非常に大きいか多くの数のコンピュータを使用するのであれば、dist_async を利用することを望むかもしれません。
結果
結果の表・グラフ等については、原文 を参照してください :
Next Steps
以上