Chrome 拡張機能に TensorFlow.js をデプロイする

このチュートリアルでは、Web ページ内の画像を右クリックして画像上でマルチクラス オブジェクト検出を実行できる Chrome 拡張機能を構築してインストールします。この拡張機能は、 MobileNetV2分類子を画像に適用し、予測されたクラスで画像にラベルを付けます。

サンプルコードはGitHubで入手できます。

前提条件

このチュートリアルを完了するには、開発環境に以下がインストールされている必要があります。

拡張機能をビルドする

ソース コードを取得して拡張機能をビルドします。

  1. tfjs-examplesリポジトリのクローンを作成するか、ダウンロードします。
  2. chrome-extensionディレクトリに移動します: cd tfjs-examples/chrome-extension
  3. 依存関係をインストールします: yarn
  4. ビルド スクリプト「 yarn buildを実行します。

ビルド スクリプトを実行すると、次の新しいファイルが表示されるはずです。

  • dist/src/content.js
  • dist/src/service_worker.js
  • dist/src/service_worker.js.map

拡張機能をインストールする

Chrome に拡張機能をインストールします。

  1. Chrome ブラウザで、 chrome://extensionsに移動します。
  2. ブラウザの右側にあるトグルを使用して開発者モードをオンにします。
  3. 「解凍してロード」を選択し、 tfjs-examples/chrome-extension/distディレクトリを選択します。このディレクトリには、 manifest.jsonファイルと、ビルドによってパッケージ化されたsrc/*.jsファイルが含まれています。

Chrome 拡張機能に TF.js mobilenetの新しいカードが表示されるはずです。

拡張機能を使用する

拡張機能をインストールすると、ブラウザーで画像を分類できます。

  1. 画像のあるサイトに移動します。たとえば、 google.comに移動し、「tigers」を検索し、結果ページで[画像]を選択します。トラの画像のページが表示されるはずです。
  2. 画像を右クリックし、 「TensorFlow.js で画像を分類」を選択します。ウォームアップ期間があるため、初めてアプリを実行するときは推論が遅くなります。 (独自のアプリケーションでは、ダミー データをフィードすることでモデルを準備できます。)

拡張機能は画像上でモデルを実行し、予測を示すテキストを重ね合わせます。

拡張機能を削除する

拡張機能の実験が終了したら、それを削除できます。

  1. Chrome で、 chrome://extensionsに移動します。
  2. Chrome 拡張機能カードの TF.js モバイルネットで、 [削除]を選択し、拡張機能を削除することを確認します。

拡張機能の仕組み

このセクションでは、拡張機能がどのように機能するかについて概要を説明します。

マニフェストファイル、 manifest.json 、Chrome がバックグラウンドで実行する Service Worker を指定します。

"background": {
   "service_worker": "src/service_worker.js"
},

Service Worker スクリプトservice_worker.jsは、TensorFlow.js パッケージとmobilenet モデルをインポートします。

import * as mobilenet from '@tensorflow-models/mobilenet';
import * as tf from '@tensorflow/tfjs';

package.jsonのビルド スクリプトは、バンドラーParcelを使用してすべてをバンドルし、実行時に外部スクリプトが読み込まれないようにします。

"build": "parcel build src/service_worker.js --dist-dir dist/src/ && npm run copy",

これは、リモートでホストされるコードを禁止するChrome マニフェスト V3 に準拠するためです。 Service Worker は引き続き TensorFlow.js モデルなどの外部リソースをロードできることに注意してください。

Service Worker スクリプトは、イメージを操作するコンテキスト メニュー項目を作成します。次に、スクリプトはクリックをリッスンします。

/**
 * Adds a right-click menu option to trigger classifying the image.
 * The menu option should only appear when right-clicking an image.
 */
chrome.runtime.onInstalled.addListener(() => {
  chrome.contextMenus.create({
    id: 'contextMenu0',
    title: 'Classify image with TensorFlow.js ',
    contexts: ['image'],
  });
});

chrome.contextMenus.onClicked.addListener(clickMenuCallback);

ユーザーがメニュー項目を選択すると、コールバックによって、現在のタブ ID と右クリックした画像の URL を含むメッセージが送信されます。 (Service Worker では DOM オブジェクトは使用できないことに注意してください。)

function clickMenuCallback(info, tab) {
  const message = { action: 'IMAGE_CLICKED', url: info.srcUrl };
  chrome.tabs.sendMessage(tab.id, message, (resp) => {
    if (!resp.rawImageData) {
      console.error(
        'Failed to get image data. ' +
        'The image might be too small or failed to load. ' +
        'See console logs for errors.');
      return;
    }
    const imageData = new ImageData(
      Uint8ClampedArray.from(resp.rawImageData), resp.width, resp.height);
    imageClassifier.analyzeImage(imageData, info.srcUrl, tab.id);
  });
}

コンテンツ スクリプトcontent.jsはメッセージをリッスンし、 IMAGE_CLICKEDアクションを処理します。スクリプトは画像 URL を受信し、画像をロードし、 OffscreenCanvas上で画像をレンダリングし、キャンバスから画像データを取得して、そのデータを Service Worker に送り返します。

Service Worker は画像データを受信した後、そのデータを使用して mobilenet モデルを実行し、予測結果を取得します。上記のclickMenuCallback関数では、 imageClassifier 、モデルをロードして予測を取得するImageClassifierクラスのインスタンスです。次に、Service Worker スクリプトは、表示のために結果をコンテンツ スクリプトに送り返します。コンテンツ スクリプトは結果を受け取ると、その結果を元の画像の上にオーバーレイします。

約 30 秒間アクティビティが発生しないと、Service Worker スレッドはアイドル状態になります。 Service Worker イベントの管理の詳細については、 Chrome のドキュメントを参照してください。

次は何ですか

このチュートリアルでは、TensorFlow.js と事前トレーニングされた MobileNet モデルを使用して画像を分類する Chrome 拡張機能をデプロイする方法を説明しました。 TensorFlow.js の事前トレーニングされたモデルの詳細については、事前トレーニングされたモデル リポジトリを参照してください。