Tensorflowで作った学習モデルをandroidで利用する
物体検出を勉強中です。Tensorflowにはネットワークのグラフ情報やパラメータなどを保存するcheckpoint
というものがありますよね。
checkpoint
ファイルをロードすれば一旦学習をストップして、再度学習を続行することもできて非常に便利。
それとは別でcheckpoint
ファイルからProtocolBuffer
と呼ばれるグラフ情報とパラメータが格納されたファイルを作成できるらしく、それを使ってAndroid上で動かしてみた。
まずはProtocolBuffer
ファイルの作成から。コードはいつも通りここにあげた。
出力結果でネットワークに使用したConv2d
などのパラメータが出てきているのがわかります。
利用としてはtf.Session
での初期化をProtocolBuffer
ファイルに入っているグラフ情報で初期化して使うという感じかな?
モルガンさんのこの記事を参照した。
ProtocolBuffer
ファイルの作成もできたので、Android上で読み込んで使ってみる。
アプリの設計としては
- OpenCVのライブラリを導入して、カメラのフレームを入力にする。
- カメラのフレームを取得して、その画像でOpenCVライブラリにあるテンプレートマッチングを行う。
- マッチングしたところを切り抜きリサイズして
ProtocolBuffer
ファイルを読み込み、学習にかける
こんな感じ こちらのコードはここ
Androidアプリの開発はそんな経験はなくThreadやListenerなどはあまりわかってないので、頭悪いコードになってしまった。
ProtocolBuffer
ファイルが400MBとデカすぎるのでSDカードから読み込むことに。それでもかなり重いが。。
結果としては以下のようになった
欠点として、端末の電池の減りが早くなるのと、端末自体が激アツになってしまう。
作るにおいて躓いたのは、OpenCVの導入だった。
android用のTensorflowの導入は簡単だったけど、OpenCVを手順通りにやるとLinkerErrorが出てしまい困った。
原因としては、OpenCVの導入の手順では「sdk > native > libs」の libs を 自プロジェクトの jniLibs に置くと書いてある。
libsの中身としては、armeabi
やx86
とかAndroid端末のCPU?の名前のディレクトリが何個かある。
自分のプロジェクトにはTensorflowを利用するために、「jniLibs -> armeabi-v7a -> libtensorflow_inference.so」ファイルが置いてある。
jniLibsに armeabi-v7a
以外のx86
などのディレクトリを置いてしまうと、Tensorflowのライブラリを読み込むときに、libtensorflow_inference.soをx86
とかから参照してしまいエラーが出るということだった。OpenCVを利用するためには libsのarmeabi-v7a
だけをコピーして置けば解決した。
RCNNも作ってみたかったけどjavaでのSelectiveSearchのライブラリが見つからなかったので諦めた。
ProtocolBuffer
ファイルの利用例が作れたのでよしとする。