Google Play 服務中的 TensorFlow Lite Java API

除了原生 API 之外,Google Play 服務中的 TensorFlow Lite 也可以使用 Java API 存取。尤其是,Google Play 服務中的 TensorFlow Lite 可透過 TensorFlow Lite Task APITensorFlow Lite Interpreter API 取得。「工作程式庫」針對使用視覺、音訊和文字資料的常見機器學習工作,提供最佳化的開箱即用模型介面。TensorFlow 執行階段提供的 TensorFlow Lite Interpreter API,則提供更通用的介面來建構及執行 ML 模型。

以下章節說明如何在 Google Play 服務中使用 Interpreter 和工作程式庫 API 與 TensorFlow Lite。雖然應用程式可以同時使用 Interpreter API 和工作程式庫 API,但大多數應用程式應僅使用一組 API。

使用工作程式庫 API

TensorFlow Lite Task API 包裝了 Interpreter API,並為使用視覺、音訊和文字資料的常見機器學習工作提供高階程式設計介面。如果您的應用程式需要 支援的工作 之一,則應使用 Task 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。例如,使用下列程式碼來實作視覺工作

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

2. 新增 TensorFlow Lite 的初始化

在使用 TensorFlow Lite API 之前,先初始化 Google Play 服務 API 的 TensorFlow Lite 元件。下列範例初始化視覺程式庫

Kotlin

init {
  TfLiteVision.initialize(context)
}

3. 執行推論

初始化 TensorFlow Lite 元件後,呼叫 detect() 方法以產生推論。detect() 方法中的確切程式碼會因程式庫和用途而異。以下是搭配 TfLiteVision 程式庫的簡單物件偵測用途範例

Kotlin

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)

使用 Interpreter API

Interpreter API 比工作程式庫 API 提供更多控制和彈性。如果工作程式庫不支援您的機器學習工作,或者您需要更通用的介面來建構及執行 ML 模型,則應使用 Interpreter 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 元件

Kotlin

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

Java

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

3. 建立 Interpreter 並設定執行階段選項

使用 InterpreterApi.create() 建立 Interpreter,並呼叫 InterpreterApi.Options.setRuntime() 將其設定為使用 Google Play 服務執行階段,如下列範例程式碼所示

Kotlin

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)
  }

Java

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() 呼叫新增至 Interpreter 建立

Kotlin

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

Java

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

4. 執行推論

使用您建立的 interpreter 物件,呼叫 run() 方法以產生推論。

Kotlin

interpreter.run(inputBuffer, outputBuffer)

Java

interpreter.run(inputBuffer, outputBuffer);

硬體加速

TensorFlow Lite 可讓您使用特殊的硬體處理器 (例如圖形處理單元 (GPU)) 來加速模型的效能。您可以使用稱為 委派 的硬體驅動程式來善用這些特殊的處理器。您可以使用下列硬體加速委派搭配 Google Play 服務中的 TensorFlow Lite

  • GPU 委派 (建議) - 此委派透過 Google Play 服務提供,並動態載入,就像工作 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 委派。下列範例說明如何搭配工作程式庫和 Interpreter API 執行此操作。

搭配工作 API

Kotlin

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

Java

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

搭配 Interpreter API

Kotlin

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)
}
    

Java

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 委派

    Kotlin

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

    Java

        TfLiteVision.initialize(context, TfLiteInitializationOptions.builder().setEnableGpuDelegateSupport(true).build());
        
  3. 使用 BaseOptions 啟用 GPU 委派選項

    Kotlin

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

    Java

        BaseOptions baseOptions = BaseOptions.builder().useGpu().build();
        
  4. 使用 .setBaseOptions 設定選項。例如,您可以使用下列程式碼在 ObjectDetector 中設定 GPU

    Kotlin

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

    Java

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

搭配 Interpreter API 使用 GPU

若要搭配 Interpreter API 使用 GPU 委派

  1. 更新專案依附元件以使用 Play 服務中的 GPU 委派

    implementation 'com.google.android.gms:play-services-tflite-gpu:16.1.0'
    
  2. 在 TFlite 初始化中啟用 GPU 委派選項

    Kotlin

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

    Java

        TfLite.initialize(context,
          TfLiteInitializationOptions.builder()
           .setEnableGpuDelegateSupport(true)
           .build());
        
  3. 在 Interpreter 選項中啟用 GPU 委派:透過在 InterpreterApi.Options() 中呼叫 addDelegateFactory(),將委派工廠設定為 GpuDelegateFactory

    Kotlin

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

    Java

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

從獨立 TensorFlow Lite 移轉

如果您計畫將應用程式從獨立 TensorFlow Lite 移轉至 Play 服務 API,請查看下列額外指南以更新您的應用程式專案程式碼

  1. 查看本頁面的「限制」章節,以確保您的用途受到支援。
  2. 在更新程式碼之前,請先針對您的模型執行效能和準確度檢查,特別是如果您使用的是早於 2.1 版的 TensorFlow Lite 版本,以便您擁有可與新實作方式比較的基準。
  3. 如果您已移轉所有程式碼以使用 TensorFlow Lite 的 Play 服務 API,則應從您的 build.gradle 檔案中移除現有的 TensorFlow Lite 執行階段程式庫依附元件 (包含 org.tensorflow:tensorflow-lite:* 的項目),以便減少您的應用程式大小。
  4. 找出程式碼中所有 new Interpreter 物件建立的例項,並修改每個例項,使其使用 InterpreterApi.create() 呼叫。新的 TfLite.initialize 是非同步的,這表示在大多數情況下,它並非直接替換:您必須為呼叫完成時註冊監聽器。請參閱「步驟 3」程式碼中的程式碼片段。
  5. import org.tensorflow.lite.InterpreterApi;import org.tensorflow.lite.InterpreterApi.Options.TfLiteRuntime; 新增至任何使用 org.tensorflow.lite.Interpreterorg.tensorflow.lite.InterpreterApi 類別的原始檔。
  6. 如果任何產生的 InterpreterApi.create() 呼叫只有單一引數,請將 new InterpreterApi.Options() 附加至引數清單。
  7. .setRuntime(TfLiteRuntime.FROM_SYSTEM_ONLY) 附加至任何 InterpreterApi.create() 呼叫的最後一個引數。
  8. 將所有其他 org.tensorflow.lite.Interpreter 類別的例項取代為 org.tensorflow.lite.InterpreterApi

如果您想要並排使用獨立 TensorFlow Lite 和 Play 服務 API,則必須使用 TensorFlow Lite 2.9 (或更高版本)。TensorFlow Lite 2.8 和更早版本與 Play 服務 API 版本不相容。