2020年1月4日土曜日

Raspberry Pi + Coral USB Accelerator + TensorFlow Lite で物体検出と姿勢推定を試してみよう

以下は、古くなったのでサポートを停止した情報です。代替ページとして「Raspberry Pi 5 でリアルタイムな姿勢推定と物体検出」をお勧めします。

1. はじめに

注:本ページの演習は Coral USB Accelerator をお持ちでなくても実行できます

Raspberry Pi で YOLO v3-Tiny / YOLO v3 による物体検出を試してみよう」 では、物体検出の手法である YOLO を Raspberry Pi で試しました。
上記ページの演習を実行すると本書で学んだ CNN が物体検出で使われていることを体験頂けますが、計算量が多いため、カメラからの映像に対して物体検出を行うと映像の遅れが大きいことも分かりました。

一方、ディープラーニングの計算を高速化するために、グラフィックを描画するためのハードウェアである GPU が用いられるということを聞いたことがある方もいると思います。 GPU による高速化はRaspberry Pi でも行われており、例えば Idein 社の取り組みなどがあります。

本ページでは、ディープラーニングの推論部(学習後のネットワークによる認識部)の高速化のために Coral USB Accelerator を用いる手法を紹介します。 Coral USB Accelerator は内部に Google が開発した Edge TPU と呼ばれる AI 用ハードウェアを搭載しており、Raspberry Pi に USB ケーブルで接続することで、Raspberry Pi の代わりに高速に推論の計算を実行してくれるデバイスです。


上図は Raspberry Pi 4 に Coral USB Accelerator を接続し、カメラからの映像に対して物体検出を行っている様子です。以下の物体が検出されていることがわかります。
  • chair : 椅子
  • dining table : ダイニングテーブル
  • laptop : 実際にはラップトップPCではなく小型ディスプレイ
  • cup : カップ
  • keyboard : キーボード
  • mouse : マウス
また、少し見にくいですが左上に「19.9ms」と書かれており、これは物体検出の計算に 19.9ミリ秒の時間がかかったことを示しています。これは1秒間に50回物体検出の計算を行えることを意味します。実際には他にも様々な処理が行われるため1秒ごとの計算回数はもう少し少なくなります。
この計算を Coral USB Accelerator なしで行うと約 300ms の時間がかかりますので、約 15 倍程度の高速化になっています。

本ページではこの演習を行う方法を解説します。Coral USB Accelerator を Raspberry Pi 4 に接続した様子が下図になります。

Coral USB Accelerator は例えば下記で購入できます。
1万円以上するため、気軽に購入して試してみるというわけにはいかないかもしれません。
上述したように、本ページでは「Coral USB Accelerator を使った場合」と「使わなかった場合」とで計算時間を比較しますので、Coral USB Accelerator がなくても演習を体験できます。

Raspberry Pi で YOLO v3-Tiny / YOLO v3 による物体検出を試してみよう」で用いた YOLO とは異なる物体検出の方法を用いますので、性能の違いを体験してみるのもよいでしょう。

また、本ページの末尾では Coral USB Accelerator を用いた人物の姿勢推定のプログラムの実行方法も紹介します。こちらも Coral USB Accelerator がなくても動作しますので是非試してみてください。

2. 準備とTensorFlow Liteのインストール

それでは、本ページに演習を行うための準備を解説していきます。 必要なのは下記のものです。
  • Raspbian Busterをインストールした Rasberry Pi ( Pi 3 B+ と Pi 4 B でのみ試しました)
  • Raspberry Pi 公式カメラモジュールまたはウェブカメラ(ウェブカメラは Logicool 社製のみ試しました)
  • Pytrhon3 用の OpenCV 3 がインストールされていること
  • TensorFlow 1 系がインストールされていないこと
さらに、本書を全て終えた状態の Raspberry Pi を仮定します。その状態を簡単に実現するには、まず下記のページに従い Python3 用のツールをインストールします(ただし、kerasの設定は不要です)。
そうすると、TensorFlowがインストールされた状態になります。上記ページで、TensorFlow 1 系をインストールした方は、ターミナルを起動して下記のコマンドで TensorFlow のみを削除します。 TensorFlow 1 系がインストールされている環境では本ページで用いる TensorFlow Lite のプログラムの実行ができなくなるためです。 本ページの演習が終わり、また TensorFlow が必要だと感じた時に改めて再インストールしてください。
sudo pip3 uninstall tensorflow
途中で「Proceed (y/n)?」などと(場合によっては複数回)聞かれますので、キーボードで「y」をタイプしてEnterキーを押し、処理を進めて下さい。

次に、TensorFlow Liteをインストールします。 TensorFlow Lite とは、PCなどとは異なり計算パワーが小さいコンピュータでディープラーニングの計算を行わせるためのライブラリです。例えば、Android や iPhone などのスマートフォンでディープラーニングの計算を行いたい場合にも用いられます。

上で触れたように、Raspberry Pi ではフルセットの TensorFlow が動くのですが、Coral USB Accelerator のプログラムを実行するには TensorFlow Lite が必要になるのです。

下記の2つのコマンドを一つずつ順に実行すれば TensorFlow Lite のインストールは完了です。このコマンドを含め、本ページのコマンドは長いものが多いので、コピー&貼り付けにより確実に実行してください。
wget https://github.com/google-coral/pycoral/releases/download/release-frogfish/tflite_runtime-2.5.0-cp37-cp37m-linux_armv7l.whl

sudo pip3 install tflite_runtime-2.5.0-cp37-cp37m-linux_armv7l.whl
次に、Coral USB Accelerator を使うためのライブラリのインストールを行います。下記の4つのコマンドを一つずつ順に実行すれば完了です。なお、このコマンドは「Get started with the USB Accelerator」ページで解説されているものです。
echo "deb https://packages.cloud.google.com/apt coral-edgetpu-stable main" | sudo tee /etc/apt/sources.list.d/coral-edgetpu.list

curl https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -

sudo apt update

sudo apt install libedgetpu1-std
ここまでが終わったら Raspberry Pi を再起動してください。

3. カメラから得られた画像に対する物体認識

それでは、Coral USB Accelerator で物体検出を試してみましょう。

まず、Coral USB Accelerator を持っている場合は、それを Raspberry Pi に接続しておきましょう。このとき、Raspberry Pi 4 をお使いの方は USB3 ポートに接続するようにしましょう。コネクタの色が青いのが USB3 ポートです。コネクタの色が黒い USB2 ポートに接続するよりも Coral USB Accelerator が高速に動作します。

また、Raspberry Pi 公式カメラモジュールまたはウェブカメラを Raspberry Pi に接続しましょう。Raspberry Pi 公式カメラモジュールをお使いの方は、設定アプリケーションでカメラを有効にすることを忘れないでください。これは本書でも行ったことですね。

それでは、まずサンプルアプリケーションをダウンロードし、さらに 学習済のデータファイルのダウンロードを行います。ターミナルを起動し、下記のコマンドを一つずつ順に実行して下さい。
git clone https://github.com/neuralassembly/CoralOpenCV.git

cd CoralOpenCV/object_detection

bash install_requirements.sh
一つ目のコマンドでサンプルファイル全体のダウンロードを行っており、二つ目のコマンドでプログラムの存在するディレクトリへ移動し、三つ目のコマンドで学習済のデータファイルをダウンロードしています。なお、このサンプルファイルは Coral USB Accelerator 公式のサンプルファイルに、筆者が OpenCV によるカメラ対応を追加したものです。

さて、上のコマンドを実行したターミナルでそのまま下記を実行すれば物体検出が行われます。
python3 detect_opencv.py --model models/ssd_mobilenet_v2_coco_quant_postprocess_edgetpu.tflite --labels models/coco_labels.txt 
Coral USB Accelerator をお持ちではない場合、下記のコマンドを実行してください。
python3 detect_opencv.py --model models/ssd_mobilenet_v2_coco_quant_postprocess.tflite --labels models/coco_labels.txt 
なお、上記コマンドを実行する前にターミナルを一度閉じている場合、先に「cd CoralOpenCV/object_detection」コマンドによりディレクトリの移動を行ってから上記コマンドを実行してください。

なお、上記どちらかのコマンドでエラーが出る場合、一旦下記のコマンドで古いフォルダを削除し…
rm -rf ~/CoralOpenCV/
そして上の「git clone https://github.com/neuralassembly/CoralOpenCV.git」から始まる3コマンドを実行しなしてください。 それで問題が解消する場合があります。

プログラムが正しく動作すれば冒頭に示した図のように、検出された物体の位置に青い枠と名称が表示されます。


一枚の画像に対して物体検出を実行するのにかかる時間が映像の左上に表示されています。筆者が試したところ、おおよそ下記のような数値が得られました。Coral USB Accelerator を Raspberry Pi 4 の USB3 ポートに接続するのが最速ですが、USB2 ポートに接続した場合でも十分に恩恵を受けられることがわかります。

Pi 4 B + Coral USB Accelerator (USB3)20 ms
Pi 4 B + Coral USB Accelerator (USB2)45 ms
Pi 4 B + Coral なし300 ms
Pi 3 B+ + Coral USB Accelerator (USB2)60 ms
Pi 3 B+ + Coral なし590 ms

Raspberry Pi で YOLO v3-Tiny / YOLO v3 による物体検出を試してみよう」 で用いた YOLO と比較すると、Coral USB Accelerator を用いない場合であっても YOLO よりも高速に動作しているように感じます。

それは、この学習済ネットワークには Google により開発された MobileNetV2 + SSDLite という、高速化を意識したネットワークが用いられているからです。 ただし、学習用のデータセットはYOLOと同じCOCOが用いられているため、検出される物体は共通です。検出される物体のリストはこちらにあります。番号が 89 まで振られていますが、数字に抜けがあるので実際には 80 種類の物体を検出できます。

これくらいの速度で動作すると、周囲の物体検出をしながら動作するロボットの作成も現実的ではないでしょうか。

なお、プログラムを終了したい場合は、本書のプログラムと同様、認識の画面上でキーボードの「q」をタイプしてください。

4. (おまけ1)カメラから得られた画像に対する分類

以上で本ページの本題は終わりですが、ダウンロードしたサンプルプログラムには、「映像中に映っている物体の名称を表示する」という分類のプログラムもあるのでその解説もしておきます。 先ほどの物体検出との違いは、こちらのプログラムでは「映像に映っている物体は一つ」であることが前提されていることです。

下記のコマンドにより、分類用の学習データのダウンロードを行います。
cd ~/CoralOpenCV/classification

bash install_requirements.sh
そして、そのまま下記を実行します。
python3 classify_opencv.py --model models/mobilenet_v1_1.0_224_quant_edgetpu.tflite --labels models/labels_mobilenet_quant_v1_224.txt
Coral USB Accelerator をお持ちではない場合、下記のコマンドを実行してください。
python3 classify_opencv.py --model models/mobilenet_v1_1.0_224_quant.tflite --labels models/labels_mobilenet_quant_v1_224.txt
プログラムが動作すると、以下のように映像中に映っている物体(一つ)の名称が画面上部に表示されます。


こちらでは Google により開発された MobileNet V1 というネットワークが用いられています。 認識できる物体はホームディレクトリの「 CoralOpenCV/classification/models/labels_mobilenet_quant_v1_224.txt 」というテキストファイルに 1001 の英語の名称のリストが列挙されていますので、興味のある方は開いて確認してみてください。

4. (おまけ2)カメラに映っている人物の姿勢を推定する

もう一つ、カメラに映っている人物の姿勢を推定するプログラムの実行方法を紹介します。 人物の姿勢推定は、Microsoft の Kinect というデバイスを用いる方法が有名ですが、この例ではそれをディープラーニングにより通常のカメラで実現します。

こちらはサンプルプログラムをダウンロードして実行することにより、PoseNetというモデルを実行します。

まず、ターミナルを起動して下記の2つのコマンドを一つずつ順に実行し、必要なライブラリをインストールします。
sudo apt update

sudo apt install python3-edgetpu
なお、python3-edgetpu をインストールすると、互換性の問題で上でインストールした libedgetpu1-std が削除され、上の物体検出と分類の演習が行えなくなります。もう一度上の物体検出と分類の演習を実行したい場合、下記コマンドで libedgetpu1-std を再インストールしてください。ただしそうすると、たった今インストールした python3-edgetpu が削除され、今度は姿勢推定の演習が行えなくなります。面倒ですね。
sudo apt install libedgetpu1-std
さて、python3-edgetpu がインストールされた状態で、下記の4つのコマンドを一つずつ順に実行し、サンプルプログラムをダウンロードして実行環境を準備します。なお、このサンプルファイルは Coral USB Accelerator 公式のサンプルファイルに、Coral USB Accelerator がない場合のサポートを筆者が加えたものです。
cd ~/

git clone https://github.com/neuralassembly/project-posenet.git

cd project-posenet

bash install_requirements.sh
以上が終わったら、2つのコマンドを一つずつ順に実行してプログラムを実行します。
cd ~/project-posenet

python3 pose_camera.py 
Coral USB Accelerator をお持ちでない方は、以下のコマンドを実行してください。
cd ~/project-posenet

python3 pose_camera_cpu.py 
すると、下記のようにカメラの前の人物の姿勢(および目、鼻、耳)が線で表示されます。


なお、このプログラムはカメラの前に人が立つことを想定したものですが、プライバシーに配慮してフィギュアを用いた例になっておりますことをご了承ください。

また、このプログラムは、キーボードの「Ctrl-c」によりプログラムを終了します。
初回の実行時はプログラムの動作が遅いですが、コンソール上でキーボードで「Ctrl-c」を押して一旦プログラムを終了し、再びプログラムを起動するとそれ以降は快適に動作する印象があります。

また、カメラの前に人が立って動く際、映像の左右を反転させると鏡のようになって直感的に理解しやすい映像となります。コマンドライン引数「--mirror」を付けた以下のコマンドにより実行すると、この動作を実現できます。
python3 pose_camera.py --mirror 
Coral USB Accelerator をお持ちでない方は、以下のコマンドです。
python3 pose_camera_cpu.py --mirror 
なお、PoseNet では人間までの距離を知ることはできません。RealSense というセンサを用いて、人間までの距離も求める方法を 「Raspberry Pi + RealSense + Coral USB Accelerator + PoseNet で深度情報と姿勢情報を表示する」に記しました。RealSense をお持ちでない方も読み物としてお楽しみください。

また、PoseNet の動作原理を知りたいという方は、別サイト内の 「姿勢推定を行うPoseNetをWindowsなどのPCで実行する」というページの末尾にに解説を記しましたので興味のある方はご覧ください。

6. おわりに

Raspberry Pi + Coral USB Accelerator + TensorFlow Lite で物体検出を試してみました。Google により提案された MobileNet という高速なネットワークが、Coral USB Accelerator によりさらに高速に実行できることを体験できました。

ディープラーニングがより普及するには、このように計算能力が高くないデバイスにも計算が高速に実行ができる仕組みが重要になると思われます。