Coral Edge TPU を使用して、TensorFlow.js と Node で TFlite モデルを実行する

1. はじめに

54e81d02971f53e8.png

最終更新日: 2022 年 4 月 11 日

この Codelab では、Teachable Machine を使用して画像分類モデルをトレーニングし、JavaScript 用の強力かつ柔軟な機械学習ライブラリである TensorFlow.js を使用して Coral ハードウェア アクセラレーションで実行する方法を学びます。ウェブカメラの画像を表示し、Coral Edge TPU を使用して分類する Electron アプリをビルドします。この Codelab の完全な動作バージョンは、sig-tfjs GitHub リポジトリで入手できます。

Coral デバイスは必要ですか?

いいえ。Coral デバイスがなくても、この Codelab を試すことができます。代わりに WebNN アクセラレータを使用することで、デスクトップ マシンで優れたパフォーマンスを得ることができます。

作成するアプリの概要

この Codelab では、画像を分類する Electron アプリを作成します。お客様のアプリでは、次のことが可能になっています。

  • ウェブカメラからの画像を、トレーニングしたモデルで定義されたカテゴリに分類します。
  • Coral アクセラレータを使用して、パフォーマンスを向上させます(使用可能な場合)。
  • プラットフォームでサポートされている場合は、WebNN を使用してパフォーマンスを向上させます。

学習内容

  • Node.js で TFLite モデルを実行するために tfjs-tflite-node NPM パッケージをインストールして設定する方法。
  • Coral デバイスでモデルを実行するために Edge TPU ランタイム ライブラリをインストールする方法。
  • Coral Edge TPU を使用してモデル推論を高速化する方法。
  • WebNN を使用してモデル推論を高速化する方法。

この Codelab では、Node.js の TFLite に焦点を当てます。関連のない概念とコードブロックについては軽く触れるにとどめ、そのままコピーして貼り付けられるようにしています。

必要なもの

この Codelab を完了するには、以下が必要です。

  • ウェブカメラが搭載(または接続)されたパソコン。
  • Coral の場合は、Raspberry Pi OS(64 ビット)とデスクトップが実行されている Raspberry Pi をおすすめします。
  • WebNN の場合は、Ubuntu 20.04 または Windows 10 を実行している Intel x86-64 マシンをおすすめします。
  • Node.js バージョン 12 以降。
  • JavaScript の知識。
  • (推奨)モデルを高速化する Coral USB Accelerator

2. セットアップする

コードを取得する

このプロジェクトで必要となるすべてのコードは Git リポジトリに用意されています。まず、コードを取得して、お好みの開発環境で開きます。この Codelab では、Raspberry Pi OS(64 ビット)とデスクトップが実行されている Raspberry Pi を使用することをおすすめします。これにより、Coral アクセラレータを簡単に接続できます。

強く推奨: Git を使用して Raspberry Pi にリポジトリのクローンを作成する

コードを取得するには、新しいターミナル ウィンドウを開いて、リポジトリのクローンを作成します。

git clone https://github.com/tensorflow/sig-tfjs.git

Codelab で編集する必要があるファイルはすべて tfjs-tflite-node-codelab ディレクトリ(sig-tfjs 内)にあります。このディレクトリには、starter_codecpu_inference_workingcoral_inference_workingwebnn_inference_working という名前のサブディレクトリがあります。これらは、この Codelab の手順のチェックポイントです。

リポジトリ内の他のファイルには、tfjs-tflite-node-codelab が依存する NPM パッケージがあります。これらのファイルを編集する必要はありませんが、環境が正しく設定されていることを確認するために、これらのテストの一部を実行する必要があります。

Edge TPU ランタイム ライブラリをインストールする

Coral デバイスでは、使用する前に Edge TPU ランタイム ライブラリをインストールする必要があります。お使いのプラットフォームの手順に沿ってインストールします。

Linux / Raspberry Pi の場合

Linux では、このライブラリは Google の PPA から Debian パッケージlibedgetpu1-std)として入手できます。x86-64 アーキテクチャと Armv8(64 ビット)アーキテクチャに対応しています。プロセッサで別のアーキテクチャを使用している場合は、ソースからコンパイルする必要があります。

次のコマンドを実行して、Google の Coral PPA を追加し、Edge TPU ランタイム ライブラリをインストールします。

# None of this is needed on Coral boards
# This repo is needed for almost all packages below
echo "deb https://packages.cloud.google.com/apt coral-edgetpu-stable main" | sudo tee /etc/apt/sources.list.d/coral-edgetpu.list
# This repo is needed for only python3-coral-cloudiot and python3-coral-enviro
echo "deb https://packages.cloud.google.com/apt coral-cloud-stable main" | sudo tee /etc/apt/sources.list.d/coral-cloud.list

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

sudo apt-get update
sudo apt-get install libedgetpu1-std

Windows / その他の OS の場合

事前コンパイル済みのバイナリは MacOS と Windows の x86-64 バージョンで利用可能です。ダウンロードしたアーカイブで install.sh または install.bat スクリプトを実行するとインストールできます。

デバイスを再起動する

Edge TPU ランタイムがインストールされたら、デバイスを再起動して、インストーラが追加した新しい Coral Udev ルールを有効にします。

Coral デバイスが検出されていることを確認する

Coral デバイスが検出され、動作していることを確認するには、coral-tflite-delegate パッケージの統合テストを実行します。このパッケージはリポジトリのルート ディレクトリにあります。統合テストを実行するには、Coral アクセラレータを接続し、パッケージのディレクトリで次のコマンドを実行します。

npx yarn
npx yarn build-deps
npx yarn test-integration

次のような出力が表示されます。

yarn run v1.22.17
$ yarn build && yarn test-integration-dev
$ tsc
$ jasmine --config=jasmine-integration.json
Platform node has already been set. Overwriting the platform with node.
Randomized with seed 78904
Started

============================
Hi there 👋. Looks like you are running TensorFlow.js in Node.js. To speed things up dramatically, install our node backend, which binds to TensorFlow C++, by running npm i @tensorflow/tfjs-node, or npm i @tensorflow/tfjs-node-gpu if you have CUDA. Then call require('@tensorflow/tfjs-node'); (-gpu suffix for CUDA) at the start of your program. Visit https://github.com/tensorflow/tfjs-node for more details.
============================
WARNING: converting 'int32' to 'uint8'
.


1 spec, 0 failures
Finished in 2.777 seconds
Randomized with seed 78904 (jasmine --random=true --seed=78904)
Done in 6.36s.

ログに記載されている @tensorflow/tfjs-node, のインストールについては、TFLite でモデルを実行するため、心配する必要はありません。

出力に Encountered unresolved custom op: edgetpu-custom-op が含まれている場合は、Coral デバイスが検出されていません。Edge TPU ランタイム ライブラリがインストールされ、Coral デバイスがパソコンに接続されていることを確認します。Coral のスタートガイドに沿って、Coral バインディングの Python バージョンをテストすることもできます。Python のバージョンが動作するにもかかわらず、これらのテストが失敗する場合は、バグレポートを提出してお知らせください。

スターター コードを実行する

これで、スターター コードを実行する準備が整いました。手順は次のとおりです。

  1. tfjs-tflite-node-codelab ディレクトリの starter_code ディレクトリに移動します。
  2. npm install を実行して依存関係をインストールします。
  3. npm start を実行してプロジェクトを起動します。パソコンのウェブカメラからの動画フィードを表示するアプリが開きます。

出発点

出発点として、この Codelab 用に設計された基本的な Electron カメラアプリを使用します。コードは、この Codelab のコンセプトを示すために簡略化されており、エラー処理はほとんどありません。本番環境のアプリでこのコードを再利用する場合は、エラーを処理し、すべてのコードを十分にテストしてください。

デバイスのカメラのライブフィードを表示する基本的な Electron アプリ。

スターター コードを確認する

このスターター コードには多くのファイルがありますが、編集する必要があるのは renderer.js のみです。動画フィードや HTML 要素など、ページに表示されるものを制御し、アプリに ML モデルを追加する場所です。他のファイルの中に index.html ファイルがありますが、これは renderer.js ファイルを読み込むだけです。main.js ファイルは Electron のエントリ ポイントです。アプリのライフサイクル(アプリを開いたときに表示する内容や、アプリを閉じたときに実行する処理など)を制御しますが、変更する必要はありません。

デバッガを開く

この Codelab に沿ってアプリをデバッグする必要がある場合があります。このアプリは Electron に基づいているため、Chrome デバッガが組み込まれています。ほとんどのプラットフォームでは、Ctrl+Shift+i キーを押して開くことができます。[コンソール] タブをクリックすると、アプリのログとエラー メッセージが表示されます。

ここで調べることはほとんどありません。画像分類子のトレーニングに直接進みましょう。

3. 画像分類ツールをトレーニングする

このセクションでは、カスタム画像分類モデルの TFLite バージョンと Coral バージョンをトレーニングします。

分類器をトレーニングする

画像分類器は入力画像を受け取り、ラベルを割り当てます。この Codelab では、Teachable Machine を使用してブラウザでモデルをトレーニングします。このセクションのトレーニングを高速化するには、Raspberry Pi の代わりにデスクトップ パソコンまたはノートパソコンを使用できますが、結果のファイルを Pi にコピーする必要があります。

これでモデルをトレーニングする準備が整いました。トレーニングするモデルの種類がわからない場合は、人物検出器をトレーニングすることをおすすめします。人物検出器は、フレーム内に人物がいるかどうかを検出するだけの簡単なモデルです。

  1. 新しいタブで Teachable Machine のトレーニング ページを開きます。
  2. [イメージ プロジェクト]、[標準イメージモデル] の順に選択します。
  3. 各クラスの画像サンプルを追加します。ウェブカメラの入力を使用するのが最も簡単な方法です。クラスの名前を変更することもできます。
  4. 各クラスのデータが十分に収集されたら(通常は 50 個のサンプルで十分です)、[モデルをトレーニング] を押します。

モデルのトレーニングが完了すると、モデルの出力のプレビューが表示されます。

モデルは 2 つのクラスの画像でトレーニングされます。

モデルにさまざまな入力を試してください。誤って分類された入力が見つかった場合は、トレーニング データに追加してモデルを再トレーニングします。

  1. モデルの精度に満足したら、[モデルをエクスポート] をクリックします。モデルの 2 つの異なるバージョンをダウンロードする必要があります。
  2. モデルを Tensorflow Lite 浮動小数点モデルとしてエクスポートします。これにより、converted_tflite.zip という名前のファイルがダウンロードされます。CPU で実行される。
  3. モデルを Tensorflow Lite EdgeTPU モデルとしてエクスポートします。これにより、Coral Edge TPU で実行される converted_edgetpu.zip という名前のファイルがダウンロードされます。

4. アプリで CPU モデルを実行する

モデルのトレーニングが完了したので、アプリに追加します。このセクションの最後では、アプリがデバイスの CPU を使用してモデルを実行できるようになります。

モデルファイルをアプリに追加する

分類子をトレーニングしたときにダウンロードした converted_tflite.zip モデルファイルを解凍します。アーカイブには 2 つのファイルがあります。model_uquant.tflite は、モデルグラフと重みを含む保存済みの TFLite モデルです。labels.txt には、モデルが予測するクラスの人間が判読可能なラベルが含まれます。両方のファイルを modeldirectory に配置します。

依存関係のインストール

モデルの読み込みと入力の前処理には、TensorFlow.js の依存関係がいくつか必要です。

  • tfjs-tflite-node: Node.js で TFLite モデルを実行するための TensorFlow.js のパッケージ。
  • @tensorflow/tfjs: TensorFlow.js のメイン パッケージ。

@tensorflow/tfjs はすでにインストールされていますが、次のコマンドで tfjs-tflite-node をインストールする必要があります。

npm install --save tfjs-tflite-node

インストールしたら、renderer.js の先頭にあるアプリに追加します。

CODELAB パート 1: tfjs-tflite-node をインポートします。

const {loadTFLiteModel} = require('tfjs-tflite-node');

モデルを読み込む

これで、モデルを読み込む準備が整いました。tfjs-tflite-node には、この処理を行う loadTFLiteModel 関数が用意されています。ファイルパス、ArrayBuffer、TFHub URL からモデルを読み込むことができます。モデルとその重みを読み込むには、main 関数に次のように追加します。

CODELAB パート 1: ここでモデルを読み込みます。

const modelPath = './model/model_unquant.tflite';
const model = await loadTFLiteModel(modelPath);
const labels = fs.readFileSync('./model/labels.txt', 'utf8')
      .split('\n');

モデルを実行する

モデルの実行には 3 つのステップがあります。まず、ウェブカメラから入力フレームを取得して前処理します。次に、そのフレームでモデルを実行して予測を取得します。その後、ページに予測を表示します。

ウェブカメラの入力を前処理する

現時点では、ウェブカメラは単なる HTML 要素であり、表示されるフレームは JavaScript の renderer.js ファイルでは利用できません。ウェブカメラからフレームを取得するために、TensorFlow.js は tf.data.webcam を提供しています。これは、カメラからフレームをキャプチャするための使いやすい capture() メソッドを提供します。

これを使用するには、次のセットアップ コードを main() に追加します。

CODELAB パート 1: tf.data.webcam をこちらで設定します。

const tensorCam = await tf.data.webcam(webcam);

次に、すべてのフレームで画像をキャプチャするには、run() に以下を追加します。

CODELAB パート 1: ウェブカメラのフレームをキャプチャします。

const image = await tensorCam.capture();

また、モデルと互換性を持たせるために、各フレームを前処理する必要があります。この Codelab で使用するモデルの入力シェイプは [1, 224, 224, 3] なので、224 × 224 ピクセルの RGB 画像が想定されています。tensorCam.capture() のシェイプは [224, 224, 3] なので、tf.expandDims を使用して、テンソルの先頭に次元を追加する必要があります。また、CPU モデルは -1 ~ 1 の Float32 入力を想定していますが、ウェブカメラは 0 ~ 255 の値をキャプチャします。入力テンソルを 127 で割って範囲を [0, 255] から [0, ~2] に変更し、1 を減算して目的の範囲 [-1, ~1] を取得できます。これを行うには、run() 関数の tf.tidy() に次の行を追加します。

CODELAB パート 1: ウェブカメラのフレームをここで前処理します。

const expanded = tf.expandDims(image, 0);
const divided = tf.div(expanded, tf.scalar(127));
const normalized = tf.sub(divided, tf.scalar(1));

テンソルは使用後に破棄することが重要です。tf.tidy() はコールバックに含まれるコードに対してこれを自動的に行いますが、非同期関数はサポートしていません。前に作成した画像テンソルは、その dispose() メソッドを呼び出して手動で破棄する必要があります。

CODELAB パート 1: ここでウェブカメラのフレームを破棄します。

image.dispose();

モデルを実行して結果を表示する

前処理された入力でモデルを実行するには、正規化されたテンソルで model.predict() を呼び出します。これにより、各ラベルの予測確率を含む 1 次元テンソルが返されます。この確率に 100 を掛けて各ラベルの確率を求め、スターター コードに含まれている showPrediction 関数を使用して、モデルの予測を画面に表示します。

このコードでは、stats.js も使用して、model.predict の前後に stats.beginstats.end の呼び出しを配置することで、予測にかかる時間を計測しています。

CODELAB パート 1: モデルを実行し、結果をここに表示します。

stats.begin();
const prediction = model.predict(normalized);
stats.end();
const percentage = tf.mul(prediction, tf.scalar(100));
showPrediction(percentage.dataSync(), labels);

yarn start を使用してアプリを再度実行すると、モデルの分類が表示されます。

TFLite CPU モデルは Electron アプリで実行されます。ウェブカメラからの画像を分類し、各クラスの信頼度値を下に表示します。

パフォーマンス

現在の設定では、モデルは CPU で実行されます。デスクトップ パソコンやほとんどのノートパソコンでは問題ありませんが、Raspberry Pi などの低電力デバイスで実行する場合は望ましくない可能性があります。Raspberry Pi 4 では、おそらく 10 FPS 程度になるでしょう。これは、一部のアプリケーションでは十分な速度ではない可能性があります。高速なマシンを使用せずにパフォーマンスを向上させるには、Coral Edge TPU の形式でアプリケーション固有のシリコンを使用します。

5. アプリで Coral モデルを実行する

Coral デバイスをお持ちでない場合は、このセクションをスキップしてください。

この Codelab のステップは、前のセクションで作成したコードを基にしていますが、一から始める場合は cpu_inference_working チェックポイントを使用できます。

Coral モデルを実行する手順は、CPU モデルを実行する手順とほぼ同じです。主な違いはモデル形式です。Coral は uint8 テンソルのみをサポートするため、モデルは量子化されます。これは、モデルに渡される入力テンソルと、モデルが返す出力テンソルに影響します。もう 1 つの違いは、Coral TPU で実行するには、Edge TPU コンパイラを使用してモデルをコンパイルする必要があることです。TeachableMachine ではこの手順はすでに完了していますが、他のモデルでこの手順を行う方法については、Coral のドキュメントをご覧ください。

Coral モデルファイルをアプリに追加する

分類子をトレーニングしたときにダウンロードした converted_edgetpu.zip モデルファイルを解凍します。アーカイブには 2 つのファイルが含まれています。model_edgetpu.tflite は、モデルグラフと重みを含む保存済みの TFLite モデルです。labels.txt には、モデルが予測するクラスの人間が判読可能なラベルが含まれます。モデルファイルを coral_model ディレクトリに配置します。

依存関係のインストール

Coral モデルを実行するには、Edge TPU ランタイム ライブラリが必要です。続行する前に、セットアップ手順に沿ってインストールされていることを確認してください。

Coral デバイスは TFLite デリゲートとしてアクセスされます。JavaScript からアクセスするには、coral-tflite-delegate パッケージをインストールします。

npm install --save coral-tflite-delegate

次に、renderer.js ファイルの先頭に次の行を追加して、デリゲートをインポートします。

Codelab パート 2: ここでデリゲートをインポートします。

const {CoralDelegate} = require('coral-tflite-delegate');

モデルを読み込む

これで、Coral モデルを読み込む準備が整いました。これは CPU モデルの場合と同じ方法で行いますが、今回は loadTFLiteModel 関数にオプションを渡して Coral デリゲートを読み込みます。

CODELAB パート 2: ここでデリゲート モデルを読み込みます。

const coralModelPath = './coral_model/model_edgetpu.tflite';
const options = {delegates: [new CoralDelegate()]};
const coralModel = await loadTFLiteModel(coralModelPath, options);

ラベルは CPU モデルと同じであるため、読み込む必要はありません。

CPU と Coral を切り替えるボタンを追加

前のセクションで追加した CPU モデルに加えて、Coral モデルを追加します。両方を同時に実行するとパフォーマンスの違いがわかりにくいため、切り替えボタンで Coral と CPU の実行を切り替えます。

次のコードを使用してボタンを追加します。

CODELAB パート 2: ここに委任ボタンを作成します。

let useCoralDelegate = false;
const toggleCoralButton = document.createElement('button');
function toggleCoral() {
  useCoralDelegate = !useCoralDelegate;
  toggleCoralButton.innerText = useCoralDelegate
      ? 'Using Coral. Press to switch to CPU.'
      : 'Using CPU. Press to switch to Coral.';
}
toggleCoralButton.addEventListener('click', toggleCoral);
toggleCoral();
document.body.appendChild(toggleCoralButton);

この条件を run() 関数にフックしましょう。useCoralDelegate が false の場合は、CPU バージョンを実行する必要があります。それ以外の場合は、Coral バージョンを実行します(ただし、今のところ何も行いません)。CPU モデルを実行するコードを if ステートメントでラップします。Coral モデルが expanded テンソルを使用するため、if ステートメントから除外されています。

CODELAB パート 2: ここでデリゲートを使用するかどうかを確認します。

// NOTE: Don't just copy-paste this code into the app.
// You'll need to edit the code from the CPU section.
const expanded = tf.expandDims(image, 0);
if (useCoralDelegate) {
  // CODELAB part 2: Run Coral prediction here.
} else {
  const divided = tf.div(expanded, tf.scalar(127));
  const normalized = tf.sub(divided, tf.scalar(1));
  stats.begin();
  const prediction = model.predict(normalized);
  stats.end();
  const percentage = tf.mul(prediction, tf.scalar(100));
  showPrediction(percentage.dataSync(), labels);
}

モデルを実行する

モデルの Coral バージョンは 0 ~ 255 の uint8 テンソルを想定しているため、入力の正規化は不要です。ただし、出力も 0 ~ 255 の範囲の uint8 テンソルです。表示する前に、0 ~ 100 の浮動小数点数に変換する必要があります。

CODELAB パート 2: ここで Coral の予測を実行します。(これは上記のコード スニペットの一部です)

stats.begin();
const prediction = coralModel.predict(expanded);
stats.end();
const percentage = tf.div(tf.mul(prediction, tf.scalar(100)), tf.scalar(255));
showPrediction(percentage.dataSync(), labels);

yarn start を使用してアプリを再度実行すると、Coral アクセラレータの分類が表示されます。

CPU モデルと Coral モデルはアプリ内で一度に 1 つずつ実行され、ボタンで切り替えます。CPU モデルでは約 20 FPS、Coral モデルでは約 45 FPS が得られます。

ボタンを押すと、Coral 推論と CPU 推論を切り替えることができます。Coral モデルの信頼度ランキングは CPU モデルよりも精度が低く、通常は偶数の小数点で終わります。この精度の低下は、Coral で量子化モデルを実行することのトレードオフです。実際には問題になることはほとんどありませんが、覚えておくとよいでしょう。

パフォーマンスに関する注記

表示されるフレームレートには前処理と後処理が含まれているため、Coral ハードウェアの性能を表すものではありません。FPS メーターをクリックしてレイテンシ(ミリ秒単位)が表示されるまでクリックすると、パフォーマンスをより正確に把握できます。このレイテンシは model.predict への呼び出しのみを測定します。ただし、この測定には、テンソルを TFLite ネイティブ C バインディングに移動してから Coral デバイスに移動するまでの時間も含まれるため、完全な測定ではありません。C++ で記述されたより正確なパフォーマンス ベンチマークについては、EdgeTPU ベンチマーク ページをご覧ください。

また、この動画は Raspberry Pi ではなくノートパソコンで録画されているため、FPS が異なる場合があります。

Coral の前処理の高速化

場合によっては、TFJS バックエンドを切り替えることで、前処理を高速化できます。デフォルトのバックエンドは WebGL です。これは、大規模な並列処理可能なオペレーションに適していますが、このアプリでは前処理フェーズでそのような処理はほとんど行いません(使用する op は expandDims のみで、並列処理は行いません)。CPU バックエンドに切り替えて、ファイルの上部のインポートの後に次の行を追加することで、GPU との間でテンソルを移動する際の追加のレイテンシを回避できます。

tf.setBackend(cpu');

これは、TFLite CPU モデルの前処理にも影響します。このモデルは並列化されているため、この変更によりモデルの実行速度が大幅に低下します。

6. WebNN で CPU モデルを高速化する

Coral アクセラレータがない場合や、モデルを高速化する別の方法を試したい場合は、WebNN TFLite デリゲートを使用できます。このデリゲートは、Intel プロセッサに組み込まれた機械学習ハードウェアを使用して、OpenVINO ツールキットでモデル推論を高速化します。そのため、この Codelab の設定セクションで説明されていない追加の要件があり、OpenVINO ツールキットをインストールする必要があります。続行する前に、サポートされているターゲット システム プラットフォームに対して設定を確認してください。ただし、WebNN デリゲートはまだ macOS をサポートしていません。

OpenVINO ツールキットをインストールする

OpenVINO ツールキットは、Intel プロセッサに組み込まれた ML ハードウェアを使用してモデルを高速化します。Intel から事前コンパイルされたバージョンをダウンロードするか、ソースからビルドできます。OpenVINO をインストールする方法はいくつかありますが、この Codelab では、Windows または Linux のインストーラ スクリプトを使用することをおすすめします。他のバージョンには互換性がない可能性があるため、必ず 2021.4.2 LTS ランタイム バージョンをインストールしてください。インストーラを実行したら、Linux または Windows のインストール手順(永続的な解決策)の説明に従って、シェル環境変数を構成するか、webnn-tflite-delegate ディレクトリにある setupvars.sh(Linux)または setupvars.bat(Windows)コマンドを実行します。

WebNN Delegate が動作していることを確認する

WebNN デリゲートが正しく動作していることを確認するには、リポジトリのルート ディレクトリにある webnn-tflite-delegate パッケージの統合テストを実行します。統合テストを実行するには、パッケージのディレクトリで次のコマンドを実行します。

# In webnn-tflite-delegate/
npx yarn
npx yarn test-integration

次のような出力が表示されます。

WebNN delegate: WebNN device set to 0.
INFO: Created TensorFlow Lite WebNN delegate for device Default and power Default.

============================
Hi there 👋. Looks like you are running TensorFlow.js in Node.js. To speed things up dramatically, install our node backend, which binds to TensorFlow C++, by running npm i @tensorflow/tfjs-node, or npm i @tensorflow/tfjs-node-gpu if you have CUDA. Then call require('@tensorflow/tfjs-node'); (-gpu suffix for CUDA) at the start of your program. Visit https://github.com/tensorflow/tfjs-node for more details.
============================
label: wine bottle
score:  0.934505045413971
.


1 spec, 0 failures
Finished in 0.446 seconds
Randomized with seed 58441 (jasmine --random=true --seed=58441)
Done in 8.07s.

次のような出力が表示された場合は、構成エラーを示しています。

Platform node has already been set. Overwriting the platform with node.
Randomized with seed 05938
Started
error Command failed with exit code 3221225477.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

この出力は、OpenVINO の環境変数が設定されていないことを意味している可能性があります。現時点では、setupvars.sh(Linux)または setupvars.bat(Windows)コマンドを実行して設定できますが、Linux または Windows永続的なソリューション)の手順に沿って永続的に設定することもできます。Windows を使用している場合は、

setupvars.bat

コマンドは Git bash をサポートしていないため、この Codelab のコマンドは Windows コマンド プロンプトから実行してください。

WebNN Delegate をインストールする

OpenVINO がインストールされたので、WebNN を使用して CPU モデルを高速化する準備が整いました。この Codelab のこのセクションは、「アプリで CPU モデルを実行する」セクションで記述したコードを基にしています。このステップで作成したコードを使用できますが、Coral セクションをすでに完了している場合は、cpu_inference_working チェックポイントを使用して、クリーンな状態から開始してください。

WebNN デリゲートの Node.js 部分は npmjs で配布されます。インストールするには、次のコマンドを実行します。

npm install --save webnn-tflite-delegate

次に、renderer.js ファイルの先頭に次の行を追加して、デリゲートをインポートします。

Codelab パート 2: ここでデリゲートをインポートします。

const {WebNNDelegate, WebNNDevice} = require('webnn-tflite-delegate');

WebNN デリゲートは CPU または GPU での実行をサポートしています。WebNNDevice を使用すると、どちらを使用するかを選択できます。

モデルを読み込む

これで、WebNN デリゲートを有効にしてモデルを読み込む準備が整いました。Coral では別のモデルファイルを読み込む必要がありましたが、WebNN は TFLite と同じモデル形式をサポートしています。WebNNDelegate をモデルに渡されるデリゲートのリストに追加して、有効にします。

CODELAB パート 2: ここでデリゲート モデルを読み込みます。

let webnnModel = await loadTFLiteModel(modelPath, {
  delegates: [new WebNNDelegate({webnnDevice: WebNNDevice.DEFAULT})],
});

これは同じモデルであるため、ラベルを再度読み込む必要はありません。

TfLite CPU と WebNN を切り替えるボタンを追加

モデルの WebNN バージョンが準備できたので、WebNN と TfLite CPU 推論を切り替えるボタンを追加します。両方を同時に実行すると、パフォーマンスの違いを把握しにくくなります。

次のコードを使用してボタンを追加します(この時点ではモデルは切り替わりません)。

CODELAB パート 2: ここに委任ボタンを作成します。

let useWebNNDelegate = false;
const divElem = document.createElement('div');
const toggleWebNNButton = document.createElement('button');
function toggleWebNN() {
  useWebNNDelegate = !useWebNNDelegate;
  toggleWebNNButton.innerHTML = useWebNNDelegate
      ? 'Using WebNN. Press to switch to TFLite CPU.'
      : 'Using TFLite CPU. Press to switch to WebNN.';
  divElem.hidden = useWebNNDelegate ? false : true;
}

toggleWebNNButton.addEventListener('click', toggleWebNN);
toggleWebNN();
document.body.appendChild(toggleWebNNButton);
document.body.appendChild(divElem);

このコードでは、次のセクションで WebNN 設定を構成するために使用する div 要素も追加しています。

WebNN デバイスを切り替えるためのプルダウンを追加

WebNN は CPU と GPU での実行をサポートしているため、それらを切り替えるためのプルダウンを追加します。ボタンを作成するコードの後に次のコードを追加します。

// Create elements for WebNN device selection
divElem.innerHTML = '<br/>WebNN Device: ';
const selectElem = document.createElement('select');
divElem.appendChild(selectElem);

const webnnDevices = ['Default', 'GPU', 'CPU'];
// append the options
for (let i = 0; i < webnnDevices.length; i++) {
  var optionElem = document.createElement('option');
  optionElem.value = i;
  optionElem.text = webnnDevices[i];
  selectElem.appendChild(optionElem);
}

アプリを実行すると、[Default]、[GPU]、[CPU] のリストがドロップダウンに表示されます。プルダウンはまだフックアップされていないため、いずれかを選択しても現時点では何も起こりません。アプリにプルダウンが表示され、WebNN デバイスを [Default]、[GPU]、[CPU] から選択できます。

ドロップダウンでデバイスを変更する

ドロップダウンをフックして使用する WebNN デバイスを変更するには、ドロップダウン セレクタ要素の change イベントにリスナーを追加します。選択した値が変更されたら、デリゲート オプションで対応する WebNN デバイスを選択して WebNN モデルを再作成します。

ドロップダウンを追加したコードの後に、次のコードを追加します。

selectElem.addEventListener('change', async () => {
  let webnnDevice;
  switch(selectElem.value) {
    case '1':
      webnnDevice = WebNNDevice.GPU;
      break;
    case '2':
      webnnDevice = WebNNDevice.CPU;
      break;
    default:
      webnnDevice = WebNNDevice.DEFAULT;
      break;
  }
  webnnModel = await loadTFLiteModel(modelPath, {
    delegates: [new WebNNDelegate({webnnDevice})],
  });
});

この変更により、ドロップダウンが変更されるたびに、正しい設定で新しいモデルが作成されます。次に、WebNN モデルをフックして推論に使用します。

WebNN モデルを実行する

WebNN モデルは使用できるようになりましたが、WebNN と TfLite CPU を切り替えるボタンはまだモデルを切り替えません。モデルを切り替えるには、まず Codelab の最初のセクションで TfLite CPU モデルを読み込んだときに使用した model 変数の名前を変更する必要があります。

次の行を変更します。

const model = await loadTFLiteModel(modelPath);

...この行と一致するようにします。

const cpuModel = await loadTFLiteModel(modelPath);

model 変数の名前を cpuModel に変更し、これを run 関数に追加して、ボタンの状態に基づいて正しいモデルを選択します。

CODELAB パート 2: ここでデリゲートを使用するかどうかを確認します。

let model;
if (useWebNNDelegate) {
  model = webnnModel;
} else {
  model = cpuModel;
}

アプリを実行すると、ボタンで TfLite CPU と WebNN を切り替えられるようになります。TFLite CPU モデルと WebNN CPU モデルおよび GPU モデルはアプリ内で実行されます。WebNN モデルのいずれかがアクティブな場合、プルダウン メニューでモデルを切り替えることができます。CPU モデルは約 15 FPS、WebNN CPU モデルは約 40 FPS を取得します。

統合 Intel GPU がある場合は、WebNN CPU 推論と GPU 推論を切り替えることもできます。

パフォーマンスに関する注記

表示されるフレームレートにはプリプロセスとポストプロセスが含まれているため、WebNN の能力を表すものではありません。FPS メーターをクリックしてレイテンシ(ミリ秒単位)が表示されるまでクリックすると、パフォーマンスをより正確に把握できます。このレイテンシは model.predict への呼び出しのみを測定します。ただし、この測定には Tensor を TFLite ネイティブ C バインディングに移動する時間も含まれるため、完璧な測定ではありません。

7. 完了

おめでとうございます!これで、Electron で tfjs-tflite-node を使用した最初の Coral / WebNN プロジェクトが完成しました。

ぜひお試しいただき、さまざまな画像でテストしてみてください。TeachableMachine で新しいモデルをトレーニングして、まったく異なるものを分類することもできます。

内容のまとめ

この Codelab では、以下のことを学びました。

  • Node.js で TFLite モデルを実行するために tfjs-tflite-node npm パッケージをインストールして設定する方法。
  • Coral デバイスでモデルを実行するために Edge TPU ランタイム ライブラリをインストールする方法。
  • Coral Edge TPU を使用してモデル推論を高速化する方法。
  • WebNN を使用してモデル推論を高速化する方法。

次のステップ

これで、実際に使える基礎的な知識を得ることができました。クリエイティブなアイデアを思いついたときは、この ML モデル ランナーを拡張して、取り組んでいる実際のユースケースに役立ててください。高速で手頃な推論で業界に革命を起こしたり、パンがちょうどいい焼き加減になったらトーストを止めるようにトースターを改造したりできるかもしれません。可能性は無限大です

さらに、Teachable Machine が使用したモデルをどのようにトレーニングしたかについて詳しく知りたい場合は、転移学習に関する Codelab をご覧ください。音声認識やポーズ推定など、Coral で動作する他のモデルをお探しの場合は、coral.ai/models をご覧ください。これらのモデルの CPU バージョンやその他の多くのモデルは、TensorFlow Hub で確認できます。

作成したものを共有する

今日作成したものを他のクリエイティブなユースケースにも簡単に拡張できます。既成概念にとらわれず、ハッキングを続けてください。

ソーシャル メディアで #MadeWithTFJS ハッシュタグを使用すると、作成したプロジェクトが TensorFlow ブログ今後のイベントで取り上げられる可能性があります。皆様の作品をぜひお見せください。

参考になるウェブサイト