Google Play サービス Java API の TensorFlow Lite

Google Play サービスの TensorFlow Lite には、ネイティブ API に加えて、Java API を使用してアクセスすることもできます。特に、Google Play サービスの TensorFlow Lite は、 TensorFlow Lite Task APIおよびTensorFlow Lite Interpreter APIを通じて利用できます。タスク ライブラリは、ビジュアル、オーディオ、テキスト データを使用した一般的な機械学習タスク用に、最適化されたすぐに使用できるモデル インターフェイスを提供します。 TensorFlow ランタイムによって提供される TensorFlow Lite インタープリター API は、ML モデルを構築および実行するためのより汎用的なインターフェイスを提供します。

次のセクションでは、Google Play サービスの TensorFlow Lite でインタープリタ API とタスク ライブラリ API を使用する方法について説明します。アプリでインタープリター API とタスク ライブラリ API の両方を使用することは可能ですが、ほとんどのアプリでは 1 セットの API のみを使用する必要があります。

タスク ライブラリ API の使用

TensorFlow Lite タスク API はインタープリター API をラップし、ビジュアル、オーディオ、テキスト データを使用する一般的な機械学習タスクに高レベルのプログラミング インターフェイスを提供します。アプリケーションでサポートされているタスクのいずれかが必要な場合は、タスク API を使用する必要があります。

1. プロジェクトの依存関係を追加する

プロジェクトの依存関係は、機械学習のユースケースによって異なります。タスク API には次のライブラリが含まれています。

  • ビジョン ライブラリ: org.tensorflow:tensorflow-lite-task-vision-play-services
  • オーディオ ライブラリ: org.tensorflow:tensorflow-lite-task-audio-play-services
  • テキスト ライブラリ: org.tensorflow:tensorflow-lite-task-text-play-services

TensorFlow Lite の Play サービス API にアクセスするには、依存関係の 1 つをアプリ プロジェクト コードに追加します。たとえば、ビジョン タスクを実装するには次を使用します。

dependencies {
...
    implementation 'org.tensorflow:tensorflow-lite-task-vision-play-services:0.4.2'
...
}

2. TensorFlow Liteの初期化を追加

TensorFlow Lite API を使用する前に、 Google Play サービス API の TensorFlow Lite コンポーネントを初期化します。次の例では、ビジョン ライブラリを初期化します。

コトリン

init {
  TfLiteVision.initialize(context)
}

3. 推論を実行する

TensorFlow Lite コンポーネントを初期化した後、 detect()メソッドを呼び出して推論を生成します。 detect()メソッド内の正確なコードは、ライブラリとユースケースによって異なります。以下は、 TfLiteVisionライブラリを使用した単純なオブジェクト検出の使用例です。

コトリン

fun detect(...) {
  if (!TfLiteVision.isInitialized()) {
    Log.e(TAG, "detect: TfLiteVision is not initialized yet")
    return
  }

  if (objectDetector == null) {
    setupObjectDetector()
  }

  ...

}

データ形式によっては、推論を生成する前にdetect()メソッド内でデータを前処理して変換する必要がある場合もあります。たとえば、物体検出器の画像データには次のものが必要です。

val imageProcessor = ImageProcessor.Builder().add(Rot90Op(-imageRotation / 90)).build()
val tensorImage = imageProcessor.process(TensorImage.fromBitmap(image))
val results = objectDetector?.detect(tensorImage)

インタプリタ API の使用

インタプリタ API は、タスク ライブラリ API よりも優れた制御と柔軟性を提供します。機械学習タスクがタスク ライブラリでサポートされていない場合、または ML モデルを構築および実行するためのより汎用的なインターフェイスが必要な場合は、インタープリター API を使用する必要があります。

1. プロジェクトの依存関係を追加する

TensorFlow Lite の Play サービス API にアクセスするには、次の依存関係をアプリ プロジェクト コードに追加します。

dependencies {
...
    // Tensorflow Lite dependencies for Google Play services
    implementation 'com.google.android.gms:play-services-tflite-java:16.0.1'
    // Optional: include Tensorflow Lite Support Library
    implementation 'com.google.android.gms:play-services-tflite-support:16.0.1'
...
}

2. TensorFlow Liteの初期化を追加

TensorFlow Lite API を使用する前に、 Google Play サービス API の TensorFlow Lite コンポーネントを初期化します。

コトリン

val initializeTask: Task<Void> by lazy { TfLite.initialize(this) }

ジャワ

Task<Void> initializeTask = TfLite.initialize(context);

3. インタプリタを作成し、実行時オプションを設定します。

次のコード例に示すようにInterpreterApi.create()を使用してインタープリターを作成し、 InterpreterApi.Options.setRuntime()を呼び出して Google Play サービス ランタイムを使用するように構成します。

コトリン

import org.tensorflow.lite.InterpreterApi
import org.tensorflow.lite.InterpreterApi.Options.TfLiteRuntime
...
private lateinit var interpreter: InterpreterApi
...
initializeTask.addOnSuccessListener {
  val interpreterOption =
    InterpreterApi.Options().setRuntime(TfLiteRuntime.FROM_SYSTEM_ONLY)
  interpreter = InterpreterApi.create(
    modelBuffer,
    interpreterOption
  )}
  .addOnFailureListener { e ->
    Log.e("Interpreter", "Cannot initialize interpreter", e)
  }

ジャワ

import org.tensorflow.lite.InterpreterApi
import org.tensorflow.lite.InterpreterApi.Options.TfLiteRuntime
...
private InterpreterApi interpreter;
...
initializeTask.addOnSuccessListener(a -> {
    interpreter = InterpreterApi.create(modelBuffer,
      new InterpreterApi.Options().setRuntime(TfLiteRuntime.FROM_SYSTEM_ONLY));
  })
  .addOnFailureListener(e -> {
    Log.e("Interpreter", String.format("Cannot initialize interpreter: %s",
          e.getMessage()));
  });

Android ユーザー インターフェイス スレッドのブロックを回避できるため、上記の実装を使用する必要があります。スレッドの実行をより厳密に管理する必要がある場合は、インタープリターの作成にTasks.await()呼び出しを追加できます。

コトリン

import androidx.lifecycle.lifecycleScope
...
lifecycleScope.launchWhenStarted { // uses coroutine
  initializeTask.await()
}

ジャワ

@BackgroundThread
InterpreterApi initializeInterpreter() {
    Tasks.await(initializeTask);
    return InterpreterApi.create(...);
}

4. 推論を実行する

作成したinterpreterオブジェクトを使用して、 run()メソッドを呼び出して推論を生成します。

コトリン

interpreter.run(inputBuffer, outputBuffer)

ジャワ

interpreter.run(inputBuffer, outputBuffer);

ハードウェアアクセラレーション

TensorFlow Lite を使用すると、グラフィックス プロセッシング ユニット (GPU) などの特殊なハードウェア プロセッサを使用してモデルのパフォーマンスを高速化できます。デリゲートと呼ばれるハードウェア ドライバーを使用して、これらの特殊なプロセッサを利用できます。 Google Play サービスの TensorFlow Lite では次のハードウェア アクセラレーション デリゲートを使用できます。

  • GPU デリゲート(推奨) - このデリゲートは Google Play サービスを通じて提供され、Task API および Interpreter API の Play サービス バージョンと同様に動的に読み込まれます。

  • NNAPI デリゲート- このデリゲートは、Android 開発プロジェクトに含まれるライブラリの依存関係として利用でき、アプリにバンドルされています。

TensorFlow Lite によるハードウェア アクセラレーションの詳細については、 TensorFlow Lite デリゲートのページを参照してください。

デバイスの互換性を確認する

すべてのデバイスが TFLite による GPU ハードウェア アクセラレーションをサポートしているわけではありません。エラーやクラッシュの可能性を軽減するには、 TfLiteGpu.isGpuDelegateAvailableメソッドを使用して、デバイスが GPU デリゲートと互換性があるかどうかを確認します。

この方法を使用して、デバイスが GPU と互換性があるかどうかを確認し、GPU がサポートされていない場合のフォールバックとして CPU または NNAPI デリゲートを使用します。

useGpuTask = TfLiteGpu.isGpuDelegateAvailable(context)

useGpuTaskのような変数を取得したら、それを使用してデバイスが GPU デリゲートを使用するかどうかを判断できます。次の例は、タスク ライブラリとインタープリター API の両方を使用してこれを行う方法を示しています。

タスク API を使用する

コトリン

lateinit val optionsTask = useGpuTask.continueWith { task ->
  val baseOptionsBuilder = BaseOptions.builder()
  if (task.result) {
    baseOptionsBuilder.useGpu()
  }
 ObjectDetectorOptions.builder()
          .setBaseOptions(baseOptionsBuilder.build())
          .setMaxResults(1)
          .build()
}
    

ジャワ

Task<ObjectDetectorOptions> optionsTask = useGpuTask.continueWith({ task ->
  BaseOptions baseOptionsBuilder = BaseOptions.builder();
  if (task.getResult()) {
    baseOptionsBuilder.useGpu();
  }
  return ObjectDetectorOptions.builder()
          .setBaseOptions(baseOptionsBuilder.build())
          .setMaxResults(1)
          .build()
});
    

インタプリタ API を使用する

コトリン

val interpreterTask = useGpuTask.continueWith { task ->
  val interpreterOptions = InterpreterApi.Options()
      .setRuntime(TfLiteRuntime.FROM_SYSTEM_ONLY)
  if (task.result) {
      interpreterOptions.addDelegateFactory(GpuDelegateFactory())
  }
  InterpreterApi.create(FileUtil.loadMappedFile(context, MODEL_PATH), interpreterOptions)
}
    

ジャワ

Task<InterpreterApi.Options> interpreterOptionsTask = useGpuTask.continueWith({ task ->
  InterpreterApi.Options options =
      new InterpreterApi.Options().setRuntime(TfLiteRuntime.FROM_SYSTEM_ONLY);
  if (task.getResult()) {
     options.addDelegateFactory(new GpuDelegateFactory());
  }
  return options;
});
    

タスク ライブラリ API を備えた GPU

タスク API で GPU デリゲートを使用するには:

  1. Play サービスからの GPU デリゲートを使用するようにプロジェクトの依存関係を更新します。

    implementation 'com.google.android.gms:play-services-tflite-gpu:16.1.0'
    
  2. setEnableGpuDelegateSupportを使用して GPU デリゲートを初期化します。たとえば、次のようにしてTfLiteVisionの GPU デリゲートを初期化できます。

    コトリン

        TfLiteVision.initialize(context, TfLiteInitializationOptions.builder().setEnableGpuDelegateSupport(true).build())
        

    ジャワ

        TfLiteVision.initialize(context, TfLiteInitializationOptions.builder().setEnableGpuDelegateSupport(true).build());
        
  3. BaseOptionsで GPU デリゲート オプションを有効にします。

    コトリン

        val baseOptions = BaseOptions.builder().useGpu().build()
        

    ジャワ

        BaseOptions baseOptions = BaseOptions.builder().useGpu().build();
        
  4. .setBaseOptionsを使用してオプションを構成します。たとえば、次のようにObjectDetectorで GPU を設定できます。

    コトリン

        val options =
            ObjectDetectorOptions.builder()
                .setBaseOptions(baseOptions)
                .setMaxResults(1)
                .build()
        

    ジャワ

        ObjectDetectorOptions options =
            ObjectDetectorOptions.builder()
                .setBaseOptions(baseOptions)
                .setMaxResults(1)
                .build();
        

インタプリタ API を備えた GPU

インタープリター API で GPU デリゲートを使用するには:

  1. Play サービスからの GPU デリゲートを使用するようにプロジェクトの依存関係を更新します。

    implementation 'com.google.android.gms:play-services-tflite-gpu:16.1.0'
    
  2. TFlite の初期化で GPU デリゲート オプションを有効にします。

    コトリン

        TfLite.initialize(context,
          TfLiteInitializationOptions.builder()
           .setEnableGpuDelegateSupport(true)
           .build())
        

    ジャワ

        TfLite.initialize(context,
          TfLiteInitializationOptions.builder()
           .setEnableGpuDelegateSupport(true)
           .build());
        
  3. インタープリター オプションで GPU デリゲートを有効にします。InterpreterApi.Options()` addDelegateFactory() withinを呼び出して、デリゲート ファクトリを GpuDelegateFactory に設定します。

    コトリン

        val interpreterOption = InterpreterApi.Options()
         .setRuntime(TfLiteRuntime.FROM_SYSTEM_ONLY)
         .addDelegateFactory(GpuDelegateFactory())
        

    ジャワ

        Options interpreterOption = InterpreterApi.Options()
          .setRuntime(TfLiteRuntime.FROM_SYSTEM_ONLY)
          .addDelegateFactory(new GpuDelegateFactory());
        

スタンドアロン TensorFlow Lite からの移行

アプリをスタンドアロン TensorFlow Lite から Play サービス API に移行することを計画している場合は、アプリ プロジェクト コードを更新するための次の追加ガイダンスを確認してください。

  1. このページの「制限事項」セクションを参照して、使用事例がサポートされていることを確認してください。
  2. コードを更新する前に、特に TensorFlow Lite のバージョン 2.1 より前のバージョンを使用している場合は、モデルのパフォーマンスと精度のチェックを実行して、新しい実装と比較するためのベースラインを確保します。
  3. TensorFlow Lite の Play サービス API を使用するようにすべてのコードを移行した場合は、既存の TensorFlow Liteランタイム ライブラリの依存関係 ( org.tensorflow: tensorflow-lite :*を含むエントリ) を build.gradle ファイルから削除する必要があります。アプリのサイズを減らすことができます。
  4. コード内で発生するnew Interpreterオブジェクトの作成をすべて特定し、InterpreterApi.create() 呼び出しを使用するようにそれぞれを変更します。新しい TfLite.initialize は非同期です。つまり、ほとんどの場合、ドロップイン置換ではありません。呼び出しが完了したときのためにリスナーを登録する必要があります。ステップ 3のコードのコード スニペットを参照してください。
  5. import org.tensorflow.lite.InterpreterApi; import org.tensorflow.lite.InterpreterApi.Options.TfLiteRuntime; org.tensorflow.lite.Interpreterクラスまたはorg.tensorflow.lite.InterpreterApiクラスを使用して、任意のソース ファイルにコピーします。
  6. 結果として得られるInterpreterApi.create()の呼び出しのいずれかに引数が 1 つしかない場合は、 new InterpreterApi.Options()引数リストに追加します。
  7. InterpreterApi.create()への呼び出しの最後の引数に.setRuntime(TfLiteRuntime.FROM_SYSTEM_ONLY)を追加します。
  8. org.tensorflow.lite.Interpreterクラスの他のすべての出現をorg.tensorflow.lite.InterpreterApiに置き換えます。

スタンドアロンの TensorFlow Lite と Play サービス API を並行して使用する場合は、TensorFlow Lite 2.9 (またはそれ以降) を使用する必要があります。 TensorFlow Lite 2.8 以前のバージョンは、Play サービス API バージョンと互換性がありません。