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

1. はじめに

54e81d02971f53e8.png

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

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

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

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

作成するアプリの概要

この Codelab では、画像を分類する Electron アプリを作成します。アプリ:

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

学習内容

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

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

必要なもの

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

  • ウェブカメラが接続されたパソコン。
  • Coral の場合は、Raspberry Pi OS (64-bit) withdesktop を実行する Raspberry Pi をおすすめします。
  • WebNN には、Ubuntu 20.04 または Windows 10 を搭載した Intel x86-64 マシンを推奨します。
  • Node.js バージョン 12 以上。
  • JavaScript に関する知識
  • (推奨)モデルを高速化するための Coral USB アクセラレータ

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

次のコマンドを実行して、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.

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

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

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

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

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

出発点

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

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

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

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

デバッガを開く

この Codelab の手順に沿って、アプリのデバッグが必要になることがあります。このアプリは Electron をベースとしているため、Chrome デバッガが組み込まれています。ほとんどのプラットフォームでは、Ctrl+Shift+I キーで開けます。[Console] タブをクリックして、アプリからのログとエラー メッセージを表示します。

他に取り上げることは特にないので、さっそく画像分類器をトレーニングしましょう。

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 x 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 テンソルのみをサポートしているため、モデルは量子化されます。これは、モデルに渡される入力テンソルと、モデルから返される出力テンソルに影響します。もう一つの違いは、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 ステートメントでラップしますexpanded テンソルは Coral モデルで使用されるため、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 バージョンのモデルの uint8 テンソルは 0 ~ 255 であるため、その入力を正規化する必要はありません。ただし、出力も 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 アクセラレータからの分類が表示されます。

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

Coral 推論と CPU 推論を切り替えるには、ボタンを押します。Coral モデルの信頼度ランキングは、CPU モデルよりも精度が低く、通常は小数点以下 1 桁で終わります。この精度の低下は、Coral で量子化モデルを実行することと引き換えに行われます。通常は実際には重要ではありませんが、覚えておく必要があります。

パフォーマンスに関する注意事項

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

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

Coral の前処理の高速化

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

tf.setBackend(cpu');

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

6. WebNN を使用して CPU モデルを高速化する

Coral アクセラレータがない場合や、モデルを高速化する別の方法を試すだけの場合は、WebNN TFLite デリゲートを使用できます。このデリゲートは、Intel プロセッサに組み込まれた ML ハードウェアを使用して、OpenVINO ツールキットによるモデルの推論を高速化します。そのため、この Codelab のセットアップ セクションでは取り上げられなかった追加の要件があり、OpenVINO ツールキットをインストールする必要があります。先に進む前に、必ずサポートされている Target System Platforms に照らして設定を確認してください。ただし、WebNN デリゲートはまだ macOS をサポートしていないことに注意してください。

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

OpenVINO Toolkit は、Intel プロセッサに組み込まれた機械学習ハードウェアを使用してモデルを高速化します。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);
}

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

プルダウンでデバイスを変更します

プルダウンを接続して、使用する 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 の呼び出しのみが測定されます。これにより、パフォーマンスを詳しく把握できます。ただし、これにはテンソルを TFLite のネイティブ C バインディングに移行するのにかかる時間も含まれているため、完璧な測定ではありません。

7. 完了

これで、Electron で tfjs-tflite-node を使用して、初めての Coral / WebNN プロジェクトが完了しました。

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

内容のまとめ

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

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

次のステップ

作業の土台が整ったところで、この機械学習モデル ランナーを現在取り組んでいる実際のユースケースに拡張するために、どのようなクリエイティブなアイデアを思いつくことができるでしょうか。手ごろな価格で素早く推論を行い、業界に革命を起こしたり、パンがちょうど良い仕上がりになったらトースターを止めるように工夫したりできるかもしれません。可能性は無限大です

TeachableMachine によるモデルのトレーニング方法について詳しくは、転移学習に関する Codelab をご覧ください。音声認識や姿勢推定など、Coral と連携する他のモデルをお探しの場合は、coral.ai/models をご覧ください。これらのモデルの CPU バージョンやその他の多くのモデルの CPU については、TensorFlow Hub で探すこともできます。

成功事例を共有する

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

ソーシャル メディアで #MadeWithTFJS ハッシュタグを付けて、Google のプロジェクトが TensorFlow ブログ今後のイベントで紹介されるチャンスがありますので、お忘れなく。皆さんが作るものを楽しみにしています。

おすすめのウェブサイト