7.16. まとめ¶
本章では、推論ステップがパイプラインの一部となる場合に OpenMV アプリケーションが利用する ml の各部分を順を追って説明しました。
概念 -- ニューラルネットワークとは算術的に何であるか(テンソルをテンソルへ写像する、学習可能な演算子の積み重ね)、機械学習が古典的な画像処理に対して何を変えたのか(人間が書いた要約アルゴリズムは消え去り、ラベル付きデータから学習された重みに置き換わった)、そして数行の Python で顔検出器を動かした hello デモについて。
ml モジュール --
ml.Modelオブジェクトと、入出力テンソルを調べるためのそのプロパティ、受け付けるモデルファイルのパス、そしてそれらのファイルが置かれる場所(フラッシュから直接実行するための読み取り専用の ROMFS パーティション、または読み込み時にモデルを RAM へコピーできる任意の MicroPython ファイルシステム)について。推論パイプライン --
predict()が順番に実行する 3 つの段階(前処理、エンジンへのディスパッチ、後処理)、段階 1 を扱うNormalizationハンドル、段階 3 を扱う後処理ハンドル、そしてカメラが扱う整数テンソルを、ネットワークの学習対象であった実数値へと結びつける量子化の算術について。推論エンジン -- TFLM(ほとんどのカメラが動かす演算子インタープリタ)、CMSIS-NN(Cortex-M 上でその下層にある SIMD カーネルライブラリ)、そして NPU(AE3 上の Arm の Ethos-U55 はオフラインコンパイラ Vela と組み合わされ、N6 上の ST の Neural-ART は STAI および STEdgeAI と組み合わされる)について。エンジンはカメラによって固定されており、スクリプトが選ぶものではありません。
出力のデコード -- 生の出力テンソルをボックス、キーポイント、またはクラスごとのリストへと変換する後処理、重なり合う候補をまとめる
NMSクラス、量子化解除の前にしきい値処理を行うことでデコードを高速に保つ方法を示す YOLOv8 のウォークスルー、そしてカタログがあるモデルをカバーしていない場合にカスタムデコーダを書くためのプロトコルについて。
7.16.1. 今や手の届くもの¶
本章が準備した 3 つのこと。
学習済みモデルの読み込みと実行。
/rom/にあるものはそれ以上の準備なしに動作します。互換性のある.tfliteとして外部から供給されるものは、対象カメラ向けのオフラインツール(AE3 なら Vela、N6 なら STEdgeAI)が適切なレイアウトを生成した後に動作します。任意の出力テンソルのデコード。 アーキテクチャがカタログにある場合、適切な後処理は機械的に決まります。YOLOv8 モデルには
YoloV8、BlazeFace にはBlazeFace、といった具合です。カタログにない場合は、独自に記述する プロトコルが取り決めをカバーし、YOLOv8 ウォークスルー が最も分かりやすい複製元のリファレンスとなります。パフォーマンスについての考察。 NPU 上で 30 FPS で動くモデルが、Cortex-M7 上では 3 FPS で動くこともあります。その比率は、ネットワークのどれだけをカメラが CPU から肩代わりできるかに依存します。量子化、ROMFS への配置、NPU コンパイル、そして対象エンジンの演算子カバレッジの 4 つがレバーであり、本章ではそれぞれを取り上げました。
7.16.2. ML はカメラの他の機能と組み合わさる¶
推論が単独で実行されることはまれです。image モジュールがフレームをキャプチャして前処理し、ml モジュールがネットワークを実行し、ulab.numpy がどちらにも組み込みのない数値処理を引き受けます。典型的な検出スクリプトはこの 3 つすべてを組み合わせます。csi でキャプチャし、必要に応じて image でフレームを調整し、predict() を実行し、ml.postprocessing の中の適切なモジュールで結果を後処理し、後処理が返したボックスの上でアプリケーションが望む独自の演算には ulab.numpy を利用します。この 3 つのモジュールは同じメモリモデルを共有しており、それらの間の境界は可能な限りゼロコピーです。