<基礎学習>9/19-9/20 物体検出(SSD_Keras)をやってみた★9/22追記

今日書くこと

  • SSD_Kerasで、学習→推論ができるまで

SSD_Kerasを触った経緯

(「いきさつ」と打って変換すると「経緯」に変換されてびっくり。どうでもいいですね)

知人のお手伝いで物体検出をやっていて、その中でいいフレームワーク?がないかということで探していたところSSD_Kerasを見つけました。
物体検出のイメージとしてはこんな感じです。
f:id:kurupical:20170920195140p:plain:w500
ハイキューを彷彿とさせる絵面ですね

参考にしたサイト

ai-coordinator.jp

自分が詰まったところメモ

  • Trainingするソースどれやねん…
    SSD_training.ipynb。jupiterNotebookの形式らしいので、これを.pyに変換しました。
    9/22追記:ipynb→pyの変換
    以下のコマンドを叩いてください。
jupyter nbconvert --to python ファイル名.ipynb  
  • 学習終わらん…(Epoch 1/30でずっと止まる)
    →batch_size > テスト画像数になると駄目みたいで、ずっと止まります。具体的には以下。
gen = Generator(gt, bbox_util, 16, 'frames/',
                train_keys, val_keys,
                (input_shape[0], input_shape[1]), do_crop=False)

230行目あたりでGeneratorを生成する時に指定している第3引数がbatch_sizeです。
batch_sizeは、1回の学習に使うデータの数のことです。
デフォルトは16になっていますが、必要に応じて合わせる必要があります。 テストデータは1枚としていたので、ここを1に足す必要があります。

9/22追記:学習データの作り方

  • アノテーションデータの作成
    「物体検出用SSD_Kerasで使える学習モデルの作成方法」で言及されたツール(http://qiita.com/slowsingle/items/9006383145a650c84cb0)を使います。(結果がXML形式で出力されます)
    出力されたXMLファイルを、PASCAL_VOC/get_data_from_XML.pyを使ってpklファイルに書き込みます。
    同プログラムの下の方に書いてあるところを環境に合わせて変更してください。
## example on how to use it
import pickle
data = XML_preprocessor('testxml/').data
pickle.dump(data,open('gt_pascal.pkl','wb'))
  • アノテーションデータの準備①-XMLファイルの作成
    生成されたgt_pascal.pklをルートディレクトリ(SSD_training.py等プログラムがあるところ)に格納してください。
  • アノテーションデータの準備②-テストデータが格納されているパスを指定
    テストデータに使う画像のpathを、232行目あたりのpath_prefix、233行目あたりのGeneratorの4つ目の引数で指定してください。
  • 学習
    SSD_training.py(※ssd_training.pyではありません)を流してください。
    学習結果は、/checkpointsに出力されます。(※学習前にフォルダを作成しておいてください)
  • 推論の準備① - タグの編集
    SSD.py(※ssd.pyではありません)を編集します。
    デフォルトはVOC2007のタグ付けになっています。
voc_classes = ['Aeroplane', 'Bicycle', 'Bird', 'Boat', 'Bottle',
               'Bus', 'Car', 'Cat', 'Chair', 'Cow', 'Diningtable',
               'Dog', 'Horse','Motorbike', 'Person', 'Pottedplant',
               'Sheep', 'Sofa', 'Train', 'Tvmonitor']  ```
  • 推論の準備② - 読み込む画像の編集
    提供されているプログラムは、パスを直書きしています。
    手間なので、フォルダの中のすべてのファイルが読み込まれるように変更しました。
    以下は、/framesに画像を格納する場合の例です。
files = glob("frames/*.jpg")
for file in files:
    img = image.load_img(file, target_size=(300, 300))
    img = image.img_to_array(img)
    images.append(imread(file))
    inputs.append(img.copy())
inputs = preprocess_input(np.array(inputs))
  • 推論
    学習結果をSSD.pyに読み込ませることで、自分が作ったネットワークと画像で推論ができます。

動かしてみた

f:id:kurupical:20170920200622p:plain:w500

できた!
あとは、学習データを増やしてみて、実用的なレベルまで持って行きたいです。

感想

  • インターネットすごい。こんな難しいこともググればすぐ出来るようになるなんて…。

所要時間

5時間程度でした。