2019年11月30日土曜日

MediaPipeのObject detectionのサンプルでSSDLite MobileNet V3を試す

目的


MediaPipeのAndroidのObject detectionのサンプルを動かしたときの備忘録を残す。
今回の手順は公式にもあるので、あまり参考にはならない。


動機


MediaPipeについてはTLに流れてから、ずーっと気になっていた。
今回、モバイルに最適化されたSSDLite MobileNet V3が登場したので試してみた。





Xperia Z5でSSDLite MobileNet V3 Small をGPU実行したときのスクリーンキャプチャである。



手順


手順としては、以下となる。
  1. Android用の環境を準備(Bazel、Android関連のインストール)
  2. MediaPipe用にモデルをエクスポート
  3. モデルをMediaPipeのプロジェクトへの組み込み、ビルド
  4. Andoridへのインストール


Android用の環境を準備


Linux環境(筆者はFedora 31)にBazel、Andorid Studio(Android SDK)、Android NDKをインストールする。インストールの方法は、「TensorFlow Lite GPU delegateのAndroid用ライブラリをビルドする」と同じである。


MediaPipe用にモデルをエクスポート


TF-Liteモデルをエクスポートするのだが、通常のTF-Liteモデルのエクスポート手順とは異なる。これは、PostProssessing(NonMaxSuppression)の処理をMediaPipeが行うためである。
手順は公式でも記載されているが、ここではSSDLite MobileNet V3 Smallのpre-trainedモデルで行う。

まず、tensorflow / models をcloneし、object detection apiのインストールを行う(TF1.15でmodelsはmasterで試している)。

Tensorflow detection model zooからssd_mobilenet_v3_small_cocoをダウンロードして展開する。

$ wget http://download.tensorflow.org/models/object_detection/ssd_mobilenet_v3_small_coco_2019_08_14.tar.gz
$ tar xf ssd_mobilenet_v3_small_coco_2019_08_14.tar.gz

MediaPipeの手順に沿ってモデルをfreeze graphする。ここで注意することは、通常の手順と異なる(パラメータが異なる)ことである。具体的には、export_tflite_ssd_graph.pyの引数に--add_postprocessing_op=falseを指定する。

$ CONFIG_FILE=xxxx/ssd_mobilenet_v3_small_coco_2019_08_14/pipeline.config
$ CHECKPOINT_PATH=xxx/ssd_mobilenet_v3_small_coco_2019_08_14/model.ckpt
$ OUTPUT_DIR=path_to_output_dir
$ python object_detection/export_tflite_ssd_graph.py --pipeline_config_path=$CONFIG_FILE --trained_checkpoint_prefix=$CHECKPOINT_PATH --output_directory=$OUTPUT_DIR --add_postprocessing_op=false

出力ディレクトリには2つのファイルが作成される。
  • tflite_graph.pb
  • tflite_graph.pbtxt

これをtoco(tflite_convert)で変換する。
input_arrays, output_arraysの名前に注意。また、input_shapesはSSDLite MobileNetV3は320, 320である。
$ tflite_convert --graph_def_file=$OUTPUT_DIR/tflite_graph.pb \
  --output_file=$OUTPUT_DIR/ssdlite_object_detection.tflite \
  --input_format=TENSORFLOW_GRAPHDEF \
  --output_format=TFLITE \
  --inference_type=FLOAT \
  --input_shapes=1,320,320,3 \
  --input_arrays=normalized_input_image_tensor \
  --output_arrays=raw_outputs/box_encodings,raw_outputs/class_predictions


モデルをMediaPipeのプロジェクトへの組み込み、ビルド


mediapipeのリポジトリをcloneして、作成したTF-Liteモデルをmediapipe/mediapipe/model配下にコピーする

$ git clone https://github.com/google/mediapipe.git
$ cp $OUTPUT_DIR/ssdlite_object_detection.tflite mediapipe/mediapipe/model/ssdlite_object_detection.tflite

ANDROID_NDK_HOME, ANDROID_HOMEを設定し、ビルド。
(ANDROID_NDK_HOME, ANDROID_HOMEはインストールした環境にあわせて変更)
$ export ANDROID_HOME=$HOME/Android/Sdk
$ export ANDROID_NDK_HOME=$HOME/Android/Sdk/ndk-bundle

CPU版
$ bazel build -c opt --config=android_arm64 mediapipe/examples/android/src/java/com/google/mediapipe/apps/objectdetectioncpu

GPU版
$ bazel build -c opt --config=android_arm64 mediapipe/examples/android/src/java/com/google/mediapipe/apps/objectdetectiongpu


Andoridへのインストール


あとはadbコマンドを使ってインストールする。
$ adb install bazel-bin/mediapipe/examples/android/src/java/com/google/mediapipe/apps/objectdetectiongpu/objectdetectiongpu.apk

メニューに Object Detection CPU / Object Detection GPUのアイコンがあるので、タップすればOK。
(再度、インストールする場合は、一度アンインストールしてから)。

0 件のコメント:

コメントを投稿