試行錯誤ダイアリー

新卒エンジニアが日々の技術的な学び,働き方,日々感じたこと等を書きます

【mxnet】RecordIOフォーマットのデータセットの作り方

f:id:appli-in:20180902220102p:plain:w700


機械学習で画像認識する場合には使うフレームワークによって,画像を指定のフォーマットに変換することで効率的に学習することができます.例えば有名なフレームワークの一つのTensor FlowではTFrecordというフォーマットが用意されています.

ここではDeep Learningのフレームワークの1つのmxnetで利用できるデータフォーマットであるRecordIOフォーマットのデータセットの作り方について説明します.

RecordIOフォーマットに変換せずに,画像データの形式のまま入力して学習することも可能ですが,学習に使うデータが大規模になればなるほど学習時間がかかるので,効率的なフォーマットに変換することで学習時間を短くすることができます.更に,awsのSageMakerなどのクラウド環境で学習するときは,インスタンスの起動時間によって料金が変わることが多いので,コスト削減にも繋がります.

RecordIOとは

RecordIOはmxnetで使用できるデータセットのフォーマットです.RecordIOフォーマットでは用意した.jpg.pngなどの画像データをバイナリファイルに変換します.

RecordIOを使うメリットについて公式ドキュメントには以下の3つが書かれています.

・ディスク上の容量を大きく削減することができる .
・ディスク上での連続読み取りが可能になる.
・分散設定が簡単になる

RecordIOデータセットの作り方

RecordIOデータセットの作成手順は以下の通りです.

1.画像を用意してラベルごとにディレクトリに分ける.
2.画像とラベルが対応づいたリストファイルを生成する.
3.リストファイルを元にRecordIOファイルを生成する.

画像を用意する

学習に使いたいデータを用意します.

ここでは例としてCaltech256のデータセットを使います.

curl -O http://www.vision.caltech.edu/Image_Datasets/Caltech256/256_ObjectCategories.tar
tar -xf 256_ObjectCategories.tar

でダウンロードして解凍します.

使うデータはこのように各クラスごとにディレクトリ別に保存します.

[画像]

リストファイル生成時にはディレクトリの順番にしたがってクラスを割り当てられるので,上の画像の様にクラス名の前に数字を書くことで明示的にクラスの順番を指定しておくと後で何番目のクラスが何に該当するのかがわかりやすくなります.

lstファイルを生成する

ここではクラスと画像が紐付いたメタデータであるリストファイル(.lst)を生成します.

リストファイルを生成するためにmxnetが用意しているim2rec.pyというスクリプトをダウンロードします. URL:im2rec.py

以下のコマンドでダウンロードします.

curl -O https://raw.githubusercontent.com/apache/incubator-mxnet/master/tools/im2rec.py

im2rec.pyを使ってlstファイルを作ります.使い方はこの様になります. python im2rec.py prefix_of_lst directory_path

今回の場合はprefix_of_lst = list_datadirectory_path = ./256_ObjectCategories/としてリストファイルを作成します.

実行コマンドはこの通りです.

python im2rec.py --list --recursive list_data ./256_ObjectCategories/

するとlist_data.lstが生成されます. 中身を確認してみると.

$ head list_data.lst
26764   236.000000  237.vcr/237_0047.jpg
20759   180.000000  181.segway/181_0052.jpg
16936   144.000000  145.motorbikes-101/145_0785.jpg
27849   247.000000  248.yarmulke/248_0007.jpg
4547    39.000000   040.cockroach/040_0001.jpg
2185    16.000000   017.bowling-ball/017_0050.jpg
17906   152.000000  153.palm-pilot/153_0056.jpg
11086   100.000000  101.head-phones/101_0112.jpg
3090    24.000000   025.cactus/025_0082.jpg
13257   120.000000  121.kangaroo-101/121_0032.jpg

このようタブ区切りのファイルになっており,左から「画像のインデックス」,「クラスの番号(今回は256クラス)」,「画像のパス」になっています.

ここでオプションについて説明すると,
--list : lstファイルとして出力する
--recursive : サブディレクトリのフォルダをラベルとする
今回の様に画像のラベルごとにディレクトリに分けた場合は--recursiveオプションをつけないと正しく出力されません.

ちなみに学習用の画像と検証用の画像のために--train-ratio--test-ratioオプションで画像を分割することが可能です. 使い方は次の様になります.

python im2rec.py --list --train-ratio 0.8 --test-ratio 0.2 prefix_of_dir directory_path

これを実行すると,prefix_of_dir_train.lstprefix_of_dir_test.lstという2つのファイルが生成されます.

※以下の様に予めディレクトリを分けてからlstファイルに変換することも可能です.

train_dir/
  ┣class1/
  ┃  ┣img1.jpg
  ┃  ┗img2.jpg
  ┗class2/
     ┣img3.jpg
     ┗img4.jpg

val_dir/
  ┣class1/
  ┃  ┣img5.jpg
  ┃  ┗img6.jpg
  ┗class2/
     ┣img7.jpg
     ┗img8.jpg

RecordIOファイルの生成

先程生成したlstファイルを元にバイナリーのRecordIOファイルを生成します.

こちらもim2rec.pyを使って生成します.

使い方は以下の通りです. python im2rec.py list_file.lst img_dir

今回は次のように実行します.

python im2rec.py --resize 256 --num-thread 16 list_data.lst ./256_ObjectCategories/

それぞれのオプションの説明は次の通りです.
--resize 256 : 画像を256pxにリサイズ(このとき画像の短い方の辺が256に合うようにリサイズされる)
--num-thread : 並列で実行するときの並列数

実行が完了するとlist_data.recというRecordIOのフォーマットのデータが生成されます.

終わりに

今回はmxnetで利用できるRecordIOフォーマットのデータの生成方法についてまとめました.

lstファイルを作らずに生成する方法もあるようなので,今後追記する予定です.

参考資料

mxnetのドキュメント
Create a Dataset Using RecordIO — mxnet documentation

im2rec.pyプログラム github.com