漢なら, TensorFlow for C API で推論を極めたいですね!
やりましょう!
C API は主に言語バインディング用に提供されていますが, 特に CPU で推論だけさせたい場合は, C++ API よりも C API を利用するといろいろ楽になります.
利点
API がわかりやすい
C++ だと多数のヘッダファイルを読み込んだり, 各種使える class やメソッド名を調べるのが大変です. 特に TensorFlow の使い始めだと理解するのに時間がかかります.
C API はヘッダファイルが一つであり, API もわかりやすくなっています.
メモリ管理が明示的
メモリ確保, 解放のタイミングが明示的なのでメモリ管理がわかりやすい. メモリリークが気になる場合は ASAN(Aaddress Sanitizer) などを使えばだいたいトラッキングできます.
リンクしやすい
C++ だと, アプリに libtensorflow をリンクする場合に ABI やランタイムライブラリ(stdlib)周りでリンクの問題が発生しやすいですが, C だとその問題がなく簡単に組み込みがしやすくなります.
特に Windows(Visual Studio)でリンクの問題が解決します.
欠点
コード量が増える
C++ に比べれば明示的なメモリ解放など, コーディングする量が冗長になりやすい.
拡張しづらいかも.
C API で wrap してあるクラスやメソッドしか利用できないので, C++ で提供されている全ての機能が使えるわけでない.
PRNet-infer を C API 対応にする
PRNet を C++11 で動くようにして単一画像からの 3D 顔復元を行う.
https://qiita.com/syoyo/items/34be69a4b3bfe9174eeb
を TensorFlow C API バージョンのブランチ c-api
を作りました.
アプリ部分は C++ ですが, TensorFlow を C で呼び出すようにしています.
TensorFlow 公式から落とせる prebuilt パッケージは .so(dll) のみなので, Windows(Visual Studio)でビルドする場合にはインポートライブラリを作る必要があります.
すでに C API のサンプルと, インポートライブラリ入りの prebuilt package を公開している repo がありますので, こちらを利用しました. ありがとうございます.
最近(2019/10)では TensorFlow オフィシャルでも prebuilt package がホスティングされています.
ただ, tf のバージョンはちょっと古いです(URL を少しいじれば最新 tf version を取得できるときもある)
C API の利用サンプルは
も参考にしました.
結果,
Got success to run C++ based 3D face reconstruction PRNet-infer on Windows using TensorFlow for C API! 🎉🎉🎉🎉💯💯💯😍😍😍✨✨✨ 💪💪💪 TF C API greatly simplified linking TensorFlow library with C++ app! > https://t.co/FN8mARqil4 pic.twitter.com/uievsM3HHq
— Syoyo Fujita ⚡️ No ray tracing No life (@syoyo) September 14, 2018
Voila! Visual Studio 2017 で無事ビルドと動作できました.
Happy TensorFlow for C API programming!
ひっかかったところと注意点
TensorFlow v1.10
を使って気になったところです.
TF_NewTensor
には, 適当に deallocator を作って渡す必要があります. TF_DeleteTensor
のときに必ず deallocator を呼ぶようなので, deallocator に nullptr を指定してしまうと, とアクセス例外がでます.
Visual Studio ビルドだと, なぜかたまにアクセス違反がでます(0x5). アプリに問題があるのか, TensorFow の Windows ビルドに問題があるのか. 不明です.
TF 内部でリークするケースがあると, libtensorflow.so が release build になっているため, ASAN などで追いづらいです. tensorflow for c のソースコードをみるなり, デバッグビルドするなりして解決する必要があります.
TODO
- 優秀な TensorFlow C++ 若人が, 人類史上最速で TensorFlow for C 若人へと昇華なされるスキームを確立する旅に出たい.
- ラズパイや Android などで動かしたい
- Emscripten 化すればブラウザでも動くかも?(tensorflow.js のほうが楽かな?)