技術研究所の(あ)です。
他の記事もいくつか書きましたが、最近、機械学習をちょこちょこ試してます。その一環で、オープンソースのフレームワークの Caffe での画像分類も試してみました。ウェブ等でいろいろ調べて試行錯誤しつつインストールしたり実行してみたりしたのですが、いくつか凄まじくハマったところがありましたので、それらの点について、同じようなトラブルに出くわした方々のためにここにメモっておきます。

1. インストールでハマったところ

Caffe (version は 1.0.0-rc3 てことでいいのかな?) をインストールしたのは、Ubuntu の載った AWS の GPUインスタンス上に CUDA 7.5 (GPGPU のライブラリ) を入れて、という環境です。

事前に「必要なライブラリ等が多くて、インストールがたいへん」と聞いていましたが、確かにたいへんでした。具体的な手順等は検索するといろいろ出てくるのでここでは端折ります。調べて出てくることに加え、make の途中で既に入れたはずのライブラリが「ない」と言われるので、パスを修正したりシンボリックリンクを張ったり、などの作業はいくつかやりましたが、このへんはまあ、ちょっと Unix に慣れた人ならば普通に対応できる範囲だと思います。

そして無事 make が通ったら、きちんとインストールできているかどうかの確認のために make runtest を実行します。これが無事 [success] で終了すれば無問題なのですが…。

ということでここからが本題その1。

make runtest の途中で、ハングする、というトラブルが起こりました。Failする、何らかのエラーを出して止まる、ではなく、帰ってこなくなる、というハングのしかたです。Ctrl-C も効かず、運が良ければ (対処が早ければ?) 他のターミナルから kill できるくらいで、基本的にインスタンスの再起動しかありません。

make runtest は多数あるテスト項目の幾つかをランダムに試しているようですが、何度試しても、いくつかの特定の項目でハングするようです。同じようなトラブルの例&解決策はないか、探してみましたがなかなか情報が出てきません。唯一、GitHub の Caffe本家の掲示板でだいたい同じと思われるトラブルの報告がありましたが (こことかこことか)、その後に「解決した!」という発言はありません(;_;)。

そんな手も足も出なさそうな状況の下、最終的にはなんとかこれを解決しました。
その方法とはッ…!

「CUDA のインストールを、
cuda_7.5.18_linux.run からではなく
cuda-repo-ubuntu1404-7-7-local_7.5-18_amd64.deb から行う」

というものでした。
この二つ、どちらも NVIDIA の CUDA のダウンロードページから「どちらでもよいよ」という感じでダウンロードできるのですが、まさかそんな差が出るとは…。(てゆーか、よくそこを試したよなぁ>自分)

結局、”~.run” のほうでハングする理由は判らないのですっきりしませんが、まあ、無事 make runtest が通ったということで…。

2. 学習させるときにハマったところ

Caffe に画像を学習させる際には、LMDB か LevelDB のデータベース形式に変換してやる必要があります。画像のあるディレクトリを指定して、それをデータベース形式に変換するユーティリティが convert_imageset です。検索するといろいろ出てくる使い方が、こんな感じです。

が、この、赤線の部分の指定のしかたがどうも今のバージョンだと違うようです(;_;)。
で、何がハマりどころかというと、まず、この通り実行してもエラーは出ません (しかし効いてもいません)。
リサイズの幅と高さは他の設定と食い違うと学習実行時にすぐエラーが出るので気が付けます。しかし「シャッフル」(データの順番をランダムに入れ替える) のほうは効いてなくてもエラーが出るようなものではないので、シャッフルしたつもりができていないことになかなか気が付かないのです。

同じカテゴリーのものが連続しているなど、似たような学習データが順番にたくさんあるとき、シャッフルされていないと似たようなデータばかりで続けて学習してしまい、学習曲線が変になってしまうことがあります。ていうか、変な挙動をする原因を追っていて「シャッフルされていない」と気が付きました (これもよく気が付いたなと思う>自分)。まあ、リサイズのオプションが違った時点でこっちも疑っとけ、という話かもしれませんが…^^;。

ちなみに上のオプション指定、今のバージョンだと

convert_imageset train_dataset train.txt train_lmdb -backend lmdb --shuffle --resize_height 36 --resize_width 48

となります。またそのうち変わっているかもしれないのでご注意…?

3. 学習結果を使うときにハマったところ

学習結果のモデルは Python などから使います。classify.py というスクリプトがあるので、まずはこれで試します。結果を人間が読める形にするのにまた別途スクリプトがいるなどしょーもない難儀なポイントがあるのですが、それはさておき。

学習時のテストデータとして使った画像を試しに分類してみても、どうも学習時にログで出ていた正答率がでないっぽい感じでした。「ああ、データベースを作るときにリサイズしたな、それに合わせないといけないな」ということでリサイズしようとしましたが「あれ、どこでそれを指定すればいいの? 設定ファイル?? どこかの引数???」。

結局は classify.py の引数 –images_dim の後に 高さ,幅 の順で指定すればよい、ということが分かりましたが、これも調べてもはっきりとは書いてなく、また、意図通りの指定になっていなくてもエラーが出るわけではない (返ってくる答えがいまいちな感じなだけ) ので確かめづらいところです。何って、これで本当に正解なのかどうかも 100%の確信は持てません (Caffe のソースを詳しく見るしかないかもしれない…^^;)。もし、間違っていたらどなたか教えて下さいませ…。

classify.py --model_def cifar10_quick.prototxt --pretrained_model cifar10_quick_iter.caffemodel.h5 --images_dim 36,48 test001.jpg result.npy

おわりに

こうして数々の苦難を乗り越えてようやく使えた Caffe ですが、使えてみれば、なかなかよい感じの分類をしてくれました。この記事が、同じようなところで苦労をしているみなさんの助けになって、良い結果に辿りつければ、と思います。