#daiizメモ

Scrapboxに夢中

TensorFlowで食神の定食画像を分類する実験

昨日に引き続き,機械学習のお話.

TensorFlowのチュートリアルで紹介されていた画像をクラス分けするConvolutional Neural Networksの例題(CIFAR-10)のデータセットだけを差し替えて実験してみた.

今回の実験の目的は

  • 写真を収集するためのツールの開発
  • TensorFlowで書いたプログラムに自前で用意した写真を与える練習
  • 少しのデータでどれくらいの分類精度が出せるのか試す

といった感じ.
分類対象は,電通生なら誰でも知っている有名な中華料理店食神の590円定食メニュー.1番〜8番まであるけれど,今回は訓練データ数の都合上半分の1, 3, 4, 5番をターゲットとした*1

まず,写真を集めるツールについて.
ウェブブラウザで画像の収集と欲しい部分を切り抜くためのツールが欲しかったので作ってみた.
しかし少し解決できない問題があって,ブラウザで触るアプリではなくてChromeアプリになった.明日公開予定です(公開しました.ページ末尾追記1を参照ください)


このツールで,写真のなかから必要な部分を切り抜いてストックしていくことができる.最後に32 x 32 pxに縮小した画像をbase64エンコードしたものと教師ラベルを対応付けたものをJSON形式でエクスポートする.収集作業を再開したりラベルを変更したい場合はインポートすることもできる.これまでにスマホに撮り貯めた写真や,miil上にある写真を手作業で集めた.

なんとか頑張って,以下の枚数だけ写真を用意できた.

定食名 学習用(枚) 評価用(枚)
teishoku-1 31 5
teishoku-3 19 5
teishoku-4 19 5
teishoku-5 21 5

絶対足りてないけれど,とりあえず続けてみる.

TensorFlowからこれらの写真を読み込むときは,「label-0-0.jpg」のようなファイルを読むではなく,予めラベルと画像バイナリを固めたファイルとして読み込む.このファイルを作るためには,tf.python_io.TFRecordWriterというものを用いればよいらしい.

学習モデルは,チュートリアルにあるtensorflow.models.image.cifar10をそのまま用いた.そのうち,自分で各層を定義できるようになりたい.

これで,準備は整ったので学習スタート.10000回くらい繰り返すと良いのかもしれないが,TensorBoardで確認していると,1000回くらいでtotal-lossとlearning-rateに大きな変化がなくなったので途中で打ち切った.

f:id:daiiz:20160218114902p:plainf:id:daiiz:20160218114905p:plain

訓練プログラムに,モデルの学習した変数の値をダンプするよう指定しているので,プログラム終了時にはチェックポイントファイル(.ckpt)が生成されている.学習の成果を評価したり,何かアプリに組み込んだりしたい場合はこのファイルに保持された変数値を解凍(展開; restore) すればよい.

そして,またまたチュートリアルを参考して評価用のプログラムを書き,評価用のデータセットで検証してみると,正答率は

2016-02-18 11:55:09.253059: precision @ 1 = 0.700

70%と出てきた.かなり低い.やはりデータ不足か.

実際に写真を与えて遊ぶためのプログラムも作ったので,試してみると意外と良さそうな手応えだった.定食3番と定食4番の見極めが上手くいっていないようで,ときどき互いに間違えている.評価用の写真数も大した数ないので,全部与えて試してみたところ,3番と4番以外は殆ど間違いがなかったのでこのあたりが正答率を大きく下げているのかもしれない.

遊ぶときに与える写真は正方形であればどんな大きさでもよい.どこか集中的に切り抜いて与えたい場合は最初の手順で紹介した切り抜きツールで切り抜いてから与えてやる.

例えば以下のような,新たに用意した2つの写真(答えはいずれもteishoku-3)を与えてみると,それぞれ

f:id:daiiz:20160218124959j:plain:w280f:id:daiiz:20160218125023j:plain:w280
右の写真は id:kanata_02 さんより提供


{
    "teishoku-3": 0.9777767658233643, 
    "teishoku-1": 0.015356350690126419, 
    "teishoku-5": 0.0014701758045703173, 
    "teishoku-4": 0.005396719556301832
}
teishoku-3
{
    "teishoku-3": 0.72220778465271, 
    "teishoku-1": 0.009275807067751884, 
    "teishoku-5": 0.013801602646708488, 
    "teishoku-4": 0.25471484661102295
}
teishoku-3

のように分類結果が返される.数値は確率を表していて,特に2つめの結果はteishoku-3に次いでteishoku-4が高い値になっていることがわかる.

ここまでで,今回やりたかったことは達成できた.途中でちょくちょく出てきたプログラム類は来週以降に公開できると思います.(公開しました.ページ末尾追記2を参照ください)


今後について.

  • 3, 4の写真をもっと集めて4択問題の正答率を上げたい
  • 全メニュー8種類ぶんの分類器を作りたい
  • 大量の写真データを手軽に集められる他のネタでも実験したい
  • 食神定食写真大募集!!

追記1

追記2

追記3

*1:普通,小辛,中辛,辛口の区別は無し.すべて同ラベルで学習させる