Generowanie interfejsów modelu za pomocą metadanych

Za pomocą metadanych LiteRT programiści mogą generować kod opakowujący, aby umożliwić integrację na Androidzie. Większość programistów uzna za najłatwiejszy w użyciu interfejs graficzny narzędzia Android Studio ML Model Binding. Jeśli potrzebujesz większej możliwości dostosowania lub używasz narzędzi wiersza poleceń, możesz też skorzystać z LiteRT Codegen.

Używanie powiązań modeli ML w Android Studio

W przypadku modeli LiteRT ulepszonych za pomocą metadanych deweloperzy mogą używać funkcji Android Studio ML Model Binding do automatycznego konfigurowania ustawień projektu i generowania klas opakowujących na podstawie metadanych modelu. Kod opakowujący eliminuje potrzebę bezpośredniego korzystania z ByteBuffer. Zamiast tego deweloperzy mogą wchodzić w interakcje z modelem LiteRT za pomocą obiektów z określonym typem, takich jak BitmapRect.

Importowanie modelu LiteRT w Android Studio

  1. Kliknij prawym przyciskiem myszy moduł, w którym chcesz użyć modelu TFLite, lub kliknij File, a następnie NewOtherLiteRT Model.

  2. Wybierz lokalizację pliku TFLite. Pamiętaj, że narzędzia skonfigurują zależność modułu w Twoim imieniu za pomocą powiązania modelu ML, a wszystkie zależności zostaną automatycznie wstawione do pliku build.gradle modułu Androida.

    Opcjonalnie: jeśli chcesz używać akceleracji GPU, zaznacz drugie pole wyboru, aby zaimportować TensorFlow GPU.

  3. Kliknij Finish.

  4. Po zakończeniu importu pojawi się poniższy ekran. Aby zacząć korzystać z modelu, wybierz Kotlin lub Java, a następnie skopiuj i wklej kod w sekcji Sample Code. Możesz wrócić do tego ekranu, dwukrotnie klikając model TFLite w katalogu ml w Android Studio.

Przyspieszanie wnioskowania z użyciem modelu

Powiązanie modelu ML umożliwia programistom przyspieszenie działania kodu dzięki wykorzystaniu delegatów i liczby wątków.

Krok 1. Sprawdź, czy plik modułu build.gradle zawiera tę zależność:

    dependencies {
        ...
        // For the LiteRT GPU delegate, we need
        // 'com.google.ai.edge.litert:litert-gpu' version 1.*.
        implementation 'com.google.ai.edge.litert:litert-gpu:1.4.1'
    }

Krok 2. Sprawdź, czy procesor graficzny na urządzeniu jest zgodny z delegatem TensorFlow GPU. Jeśli nie, uruchom model przy użyciu wielu wątków procesora:

Kotlin

    import org.tensorflow.lite.gpu.CompatibilityList
    import org.tensorflow.lite.gpu.GpuDelegate

    val compatList = CompatibilityList()

    val options = if(compatList.isDelegateSupportedOnThisDevice) {
        // if the device has a supported GPU, add the GPU delegate
        Model.Options.Builder().setDevice(Model.Device.GPU).build()
    } else {
        // if the GPU is not supported, run on 4 threads
        Model.Options.Builder().setNumThreads(4).build()
    }

    // Initialize the model as usual feeding in the options object
    val myModel = MyModel.newInstance(context, options)

    // Run inference per sample code
      

Java

    import org.tensorflow.lite.support.model.Model
    import org.tensorflow.lite.gpu.CompatibilityList;
    import org.tensorflow.lite.gpu.GpuDelegate;

    // Initialize interpreter with GPU delegate
    Model.Options options;
    CompatibilityList compatList = CompatibilityList();

    if(compatList.isDelegateSupportedOnThisDevice()){
        // if the device has a supported GPU, add the GPU delegate
        options = Model.Options.Builder().setDevice(Model.Device.GPU).build();
    } else {
        // if the GPU is not supported, run on 4 threads
        options = Model.Options.Builder().setNumThreads(4).build();
    }

    MyModel myModel = new MyModel.newInstance(context, options);

    // Run inference per sample code
      

Generowanie interfejsów modeli za pomocą generatora kodu LiteRT

W przypadku modelu LiteRT wzbogaconego o metadane deweloperzy mogą użyć generatora kodu opakowującego LiteRT na Androida, aby utworzyć kod opakowujący specyficzny dla platformy. Kod opakowujący eliminuje potrzebę bezpośredniej interakcji z ByteBuffer. Zamiast tego deweloperzy mogą wchodzić w interakcje z modelem TensorFlow Lite za pomocą obiektów z określonym typem, takich jak BitmapRect.

Użyteczność generatora kodu zależy od kompletności wpisu metadanych modelu LiteRT. W sekcji <Codegen usage> w odpowiednich polach w metadata_schema.fbs znajdziesz informacje o tym, jak narzędzie do generowania kodu analizuje poszczególne pola.

Generowanie kodu opakowującego

W terminalu musisz zainstalować te narzędzia:

pip install tflite-support

Po zakończeniu generowania kodu możesz go użyć, wpisując tę składnię:

tflite_codegen --model=./model_with_metadata/mobilenet_v1_0.75_160_quantized.tflite \
    --package_name=org.tensorflow.lite.classify \
    --model_class_name=MyClassifierModel \
    --destination=./classify_wrapper

Wynikowy kod będzie znajdować się w katalogu docelowym. Jeśli korzystasz z Google Colab lub innego środowiska zdalnego, możesz łatwiej spakować wynik do archiwum ZIP i pobrać go do projektu Android Studio:

# Zip up the generated code
!zip -r classify_wrapper.zip classify_wrapper/

# Download the archive
from google.colab import files
files.download('classify_wrapper.zip')

Korzystanie z wygenerowanego kodu

Krok 1. Zaimportuj wygenerowany kod

W razie potrzeby rozpakuj wygenerowany kod do struktury katalogów. Za katalog główny wygenerowanego kodu przyjmuje się SRC_ROOT.

Otwórz projekt Android Studio, w którym chcesz użyć modelu LiteRT, i zaimportuj wygenerowany moduł, klikając kolejno File –> New –> Import Module –> wybierz SRC_ROOT

W powyższym przykładzie katalog i zaimportowany moduł będą się nazywać classify_wrapper.

Krok 2. Zaktualizuj plik build.gradle aplikacji

W module aplikacji, który będzie korzystać z wygenerowanego modułu biblioteki:

W sekcji android dodaj ten kod:

aaptOptions {
   noCompress "tflite"
}

W sekcji zależności dodaj te elementy:

implementation project(":classify_wrapper")

Krok 3. Korzystanie z modelu

// 1. Initialize the model
MyClassifierModel myImageClassifier = null;

try {
    myImageClassifier = new MyClassifierModel(this);
} catch (IOException io){
    // Error reading the model
}

if(null != myImageClassifier) {

    // 2. Set the input with a Bitmap called inputBitmap
    MyClassifierModel.Inputs inputs = myImageClassifier.createInputs();
    inputs.loadImage(inputBitmap));

    // 3. Run the model
    MyClassifierModel.Outputs outputs = myImageClassifier.run(inputs);

    // 4. Retrieve the result
    Map<String, Float> labeledProbability = outputs.getProbability();
}

Przyspieszanie wnioskowania z użyciem modelu

Wygenerowany kod umożliwia programistom przyspieszenie działania kodu dzięki użyciu delegatów i liczby wątków. Można je ustawić podczas inicjowania obiektu modelu, ponieważ przyjmuje on 3 parametry:

  • Context: kontekst z działania lub usługi Androida
  • (Opcjonalnie) Device: delegat przyspieszania TFLite. Na przykład: GPUDelegate
  • (Opcjonalnie) numThreads: liczba wątków używanych do uruchamiania modelu – domyślnie jest to jeden.

Aby na przykład użyć delegata GPU i maksymalnie 3 wątków, możesz zainicjować model w ten sposób:

try {
    myImageClassifier = new MyClassifierModel(this, Model.Device.GPU, 3);
} catch (IOException io){
    // Error reading the model
}

Rozwiązywanie problemów

Jeśli pojawi się błąd „java.io.FileNotFoundException: This file can not be opened as a file descriptor; it is probably compressed”, wstaw te wiersze w sekcji android modułu aplikacji, który będzie używać modułu biblioteki:

aaptOptions {
   noCompress "tflite"
}