TensorFlow Lite w usługach Google Play Java API

Dostęp do TensorFlow Lite w usługach Google Play można również uzyskać za pomocą interfejsów API Java, oprócz natywnego interfejsu API. W szczególności TensorFlow Lite w usługach Google Play jest dostępny za pośrednictwem interfejsu API zadań TensorFlow Lite i interfejsu API interpretera TensorFlow Lite . Biblioteka zadań zapewnia zoptymalizowane, gotowe do użycia interfejsy modeli do typowych zadań uczenia maszynowego wykorzystujących dane wizualne, dźwiękowe i tekstowe. Interfejs API interpretera TensorFlow Lite, udostępniany przez środowisko wykonawcze TensorFlow, zapewnia interfejs bardziej ogólnego przeznaczenia do tworzenia i uruchamiania modeli uczenia maszynowego.

Poniższe sekcje zawierają instrukcje dotyczące korzystania z interfejsów API interpretera i biblioteki zadań z TensorFlow Lite w usługach Google Play. Chociaż aplikacja może używać zarówno interfejsów API interpretera, jak i interfejsów API biblioteki zadań, większość aplikacji powinna używać tylko jednego zestawu interfejsów API.

Korzystanie z interfejsów API biblioteki zadań

Interfejs API zadań TensorFlow Lite otacza interfejs API interpretera i zapewnia interfejs programowania wysokiego poziomu dla typowych zadań uczenia maszynowego, które wykorzystują dane wizualne, dźwiękowe i tekstowe. Powinieneś użyć interfejsu API zadań, jeśli Twoja aplikacja wymaga jednego z obsługiwanych zadań .

1. Dodaj zależności projektu

Zależność projektu zależy od przypadku użycia uczenia maszynowego. Interfejsy API zadań zawierają następujące biblioteki:

  • Biblioteka wizji: org.tensorflow:tensorflow-lite-task-vision-play-services
  • Biblioteka audio: org.tensorflow:tensorflow-lite-task-audio-play-services
  • Biblioteka tekstowa: org.tensorflow:tensorflow-lite-task-text-play-services

Dodaj jedną z zależności do kodu projektu aplikacji, aby uzyskać dostęp do interfejsu API usług Play dla TensorFlow Lite. Na przykład użyj poniższych poleceń, aby wdrożyć zadanie związane z wizją:

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

2. Dodaj inicjalizację TensorFlow Lite

Zainicjuj komponent TensorFlow Lite interfejsu API usług Google Play przed użyciem interfejsów API TensorFlow Lite. Poniższy przykład inicjuje bibliotekę wizji:

Kotlina

init {
  TfLiteVision.initialize(context)
}

3. Wyciągnij wnioski

Po zainicjowaniu komponentu TensorFlow Lite wywołaj metodę detect() w celu wygenerowania wniosków. Dokładny kod metody detect() różni się w zależności od biblioteki i przypadku użycia. Poniżej przedstawiono prosty przypadek użycia wykrywania obiektów z biblioteką TfLiteVision :

Kotlina

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

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

  ...

}

W zależności od formatu danych przed wygenerowaniem wniosków może być konieczne wstępne przetworzenie i konwersja danych w ramach metody detect() . Na przykład dane obrazu dla detektora obiektów wymagają:

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

Korzystanie z interfejsów API interpretera

Interfejsy API interpretera oferują większą kontrolę i elastyczność niż interfejsy API biblioteki zadań. Należy używać interfejsów API interpretera, jeśli zadanie uczenia maszynowego nie jest obsługiwane przez bibliotekę zadań lub jeśli potrzebujesz interfejsu o bardziej ogólnym przeznaczeniu do tworzenia i uruchamiania modeli uczenia maszynowego.

1. Dodaj zależności projektu

Dodaj następujące zależności do kodu projektu aplikacji, aby uzyskać dostęp do interfejsu API usług Play dla TensorFlow Lite:

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. Dodaj inicjalizację TensorFlow Lite

Zainicjuj komponent TensorFlow Lite interfejsu API usług Google Play przed użyciem interfejsów API TensorFlow Lite:

Kotlina

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

Jawa

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

3. Utwórz interpreter i ustaw opcję środowiska wykonawczego

Utwórz interpreter za pomocą InterpreterApi.create() i skonfiguruj go tak, aby korzystał ze środowiska wykonawczego usług Google Play, wywołując InterpreterApi.Options.setRuntime() , jak pokazano w poniższym przykładowym kodzie:

Kotlina

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

Jawa

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

Powinieneś skorzystać z powyższej implementacji, ponieważ pozwala ona uniknąć blokowania wątku interfejsu użytkownika Androida. Jeśli chcesz dokładniej zarządzać wykonywaniem wątków, możesz dodać wywołanie Tasks.await() do tworzenia interpretera:

Kotlina

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

Jawa

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

4. Wyciągnij wnioski

Korzystając z utworzonego obiektu interpreter , wywołaj metodę run() w celu wygenerowania wnioskowania.

Kotlina

interpreter.run(inputBuffer, outputBuffer)

Jawa

interpreter.run(inputBuffer, outputBuffer);

Przyspieszenie sprzętowe

TensorFlow Lite umożliwia przyspieszenie wydajności modelu przy użyciu wyspecjalizowanych procesorów sprzętowych, takich jak jednostki przetwarzania grafiki (GPU). Możesz skorzystać z tych wyspecjalizowanych procesorów, korzystając ze sterowników sprzętowych zwanych delegatami . Możesz używać następujących delegatów akceleracji sprzętowej z TensorFlow Lite w usługach Google Play:

  • Delegat GPU (zalecany) — ten delegat jest udostępniany przez usługi Google Play i ładowany dynamicznie, podobnie jak wersje Task API i Interpreter API w usługach Play.

  • Delegat NNAPI — ten delegat jest dostępny jako dołączona zależność biblioteki w projekcie deweloperskim systemu Android i jest dołączona do aplikacji.

Aby uzyskać więcej informacji na temat akceleracji sprzętowej za pomocą TensorFlow Lite, zobacz stronę Delegaci TensorFlow Lite .

Sprawdzanie kompatybilności urządzenia

Nie wszystkie urządzenia obsługują akcelerację sprzętową GPU za pomocą TFLite. Aby ograniczyć błędy i potencjalne awarie, użyj metody TfLiteGpu.isGpuDelegateAvailable , aby sprawdzić, czy urządzenie jest kompatybilne z delegatem GPU.

Użyj tej metody, aby sprawdzić, czy urządzenie jest kompatybilne z procesorem graficznym, i użyj procesora CPU lub delegata NNAPI jako rozwiązania awaryjnego, gdy procesor graficzny nie jest obsługiwany.

useGpuTask = TfLiteGpu.isGpuDelegateAvailable(context)

Gdy masz zmienną taką jak useGpuTask , możesz jej użyć do określenia, czy urządzenia korzystają z delegata GPU. Poniższe przykłady pokazują, jak można to zrobić zarówno przy użyciu bibliotek zadań, jak i interfejsów API interpretera.

Z interfejsem API zadań

Kotlina

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

Jawa

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

Z interfejsem API tłumacza

Kotlina

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

Jawa

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

Procesor graficzny z interfejsami API biblioteki zadań

Aby użyć delegata GPU z interfejsami API zadań:

  1. Zaktualizuj zależności projektu, aby używać delegata GPU z usług Play:

    implementation 'com.google.android.gms:play-services-tflite-gpu:16.1.0'
    
  2. Zainicjuj delegata GPU za pomocą setEnableGpuDelegateSupport . Na przykład możesz zainicjować delegata GPU dla TfLiteVision w następujący sposób:

    Kotlina

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

    Jawa

        TfLiteVision.initialize(context, TfLiteInitializationOptions.builder().setEnableGpuDelegateSupport(true).build());
        
  3. Włącz opcję delegowania GPU za pomocą BaseOptions :

    Kotlina

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

    Jawa

        BaseOptions baseOptions = BaseOptions.builder().useGpu().build();
        
  4. Skonfiguruj opcje za pomocą .setBaseOptions . Na przykład możesz skonfigurować procesor graficzny w ObjectDetector w następujący sposób:

    Kotlina

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

    Jawa

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

Procesor graficzny z interfejsami API interpretera

Aby użyć delegata GPU z interfejsami API interpretera:

  1. Zaktualizuj zależności projektu, aby używać delegata GPU z usług Play:

    implementation 'com.google.android.gms:play-services-tflite-gpu:16.1.0'
    
  2. Włącz opcję delegowania GPU podczas inicjalizacji TFlite:

    Kotlina

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

    Jawa

        TfLite.initialize(context,
          TfLiteInitializationOptions.builder()
           .setEnableGpuDelegateSupport(true)
           .build());
        
  3. Włącz delegowanie GPU w opcjach interpretera: ustaw fabrykę delegatów na GpuDelegateFactory, wywołując addDelegateFactory() within InterpreterApi.Options()`:

    Kotlina

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

    Jawa

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

Migracja z samodzielnego TensorFlow Lite

Jeśli planujesz migrację aplikacji z samodzielnego TensorFlow Lite do interfejsu API usług Play, zapoznaj się z poniższymi dodatkowymi wskazówkami dotyczącymi aktualizowania kodu projektu aplikacji:

  1. Przejrzyj sekcję Ograniczenia na tej stronie, aby upewnić się, że Twój przypadek użycia jest obsługiwany.
  2. Przed aktualizacją kodu przeprowadź kontrolę wydajności i dokładności swoich modeli, szczególnie jeśli używasz wersji TensorFlow Lite wcześniejszych niż wersja 2.1, aby mieć punkt odniesienia do porównania z nową implementacją.
  3. Jeśli przeprowadziłeś migrację całego kodu, aby korzystać z interfejsu API usług Play dla TensorFlow Lite, powinieneś usunąć istniejące zależności biblioteki wykonawczej TensorFlow Lite (wpisy z org.tensorflow: tensorflow-lite :* ) z pliku build.gradle, aby może zmniejszyć rozmiar aplikacji.
  4. Zidentyfikuj wszystkie wystąpienia tworzenia new Interpreter w kodzie i zmodyfikuj każde z nich tak, aby korzystało z wywołania InterpreterApi.create(). Nowy plik TfLite.initialize jest asynchroniczny, co oznacza, że ​​w większości przypadków nie jest to zamiennik typu drop-in: musisz zarejestrować słuchacza po zakończeniu połączenia. Zapoznaj się z fragmentem kodu w kodzie kroku 3 .
  5. Dodaj import org.tensorflow.lite.InterpreterApi; i import org.tensorflow.lite.InterpreterApi.Options.TfLiteRuntime; do dowolnych plików źródłowych przy użyciu klas org.tensorflow.lite.Interpreter lub org.tensorflow.lite.InterpreterApi .
  6. Jeśli którekolwiek z powstałych wywołań funkcji InterpreterApi.create() ma tylko jeden argument, dodaj new InterpreterApi.Options() do listy argumentów.
  7. Dołącz .setRuntime(TfLiteRuntime.FROM_SYSTEM_ONLY) do ostatniego argumentu wszystkich wywołań InterpreterApi.create() .
  8. Zastąp wszystkie pozostałe wystąpienia klasy org.tensorflow.lite.Interpreter klasą org.tensorflow.lite.InterpreterApi .

Jeśli chcesz używać autonomicznego TensorFlow Lite i interfejsu API usług Play obok siebie, musisz użyć TensorFlow Lite 2.9 (lub nowszego). TensorFlow Lite 2.8 i wcześniejsze wersje nie są kompatybilne z wersją API usług Play.