Diese Seite wurde von der Cloud Translation API übersetzt.
Switch to English

Verwenden Sie ein TensorFlow Lite-Modell, um auf das ML Kit unter Android zu schließen

Mit dem ML Kit können Sie Inferenzen mit einem TensorFlow Lite- Modell auf dem Gerät durchführen.

Diese API erfordert Android SDK Level 16 (Jelly Bean) oder neuer.

Bevor Sie beginnen

  1. Wenn Sie dies noch nicht getan haben, fügen Sie Firebase zu Ihrem Android-Projekt hinzu .
  2. build.gradle in Ihrer build.gradle Datei auf Projektebene sicher, dass das Maven-Repository von Google sowohl in Ihrem buildscript als auch in Ihrem allprojects Abschnitt enthalten ist.
  3. Fügen Sie die Abhängigkeiten für die ML Kit Android-Bibliotheken zu Ihrer Gradle-Datei (normalerweise app/build.gradle ) Ihres Moduls (App-Ebene) app/build.gradle :
    apply plugin: 'com.android.application'
    apply plugin: 'com.google.gms.google-services'
    
    dependencies {
      // ...
    
      implementation 'com.google.firebase:firebase-ml-model-interpreter:22.0.3'
    }
    
  4. Konvertieren Sie das TensorFlow-Modell, das Sie verwenden möchten, in das TensorFlow Lite-Format. Siehe TOCO: TensorFlow Lite Optimizing Converter .

Hosten oder bündeln Sie Ihr Modell

Bevor Sie ein TensorFlow Lite-Modell für Rückschlüsse in Ihrer App verwenden können, müssen Sie das Modell ML Kit zur Verfügung stellen. ML Kit kann TensorFlow Lite-Modelle verwenden, die über Firebase remote gehostet, mit der App-Binärdatei gebündelt oder beides.

Durch das Hosten eines Modells auf Firebase können Sie das Modell aktualisieren, ohne eine neue App-Version zu veröffentlichen, und Sie können Remote Config und A / B Testing verwenden, um verschiedene Modelle dynamisch für verschiedene Benutzergruppen bereitzustellen.

Wenn Sie das Modell nur durch Hosten mit Firebase bereitstellen und nicht mit Ihrer App bündeln, können Sie die anfängliche Downloadgröße Ihrer App reduzieren. Beachten Sie jedoch, dass, wenn das Modell nicht mit Ihrer App gebündelt ist, keine modellbezogenen Funktionen verfügbar sind, bis Ihre App das Modell zum ersten Mal herunterlädt.

Indem Sie Ihr Modell mit Ihrer App bündeln, können Sie sicherstellen, dass die ML-Funktionen Ihrer App weiterhin funktionieren, wenn das von Firebase gehostete Modell nicht verfügbar ist.

Hostmodelle auf Firebase

So hosten Sie Ihr TensorFlow Lite-Modell auf Firebase:

  1. Klicken Sie im Abschnitt ML Kit der Firebase-Konsole auf die Registerkarte Benutzerdefiniert .
  2. Klicken Sie auf Benutzerdefiniertes Modell hinzufügen (oder Anderes Modell hinzufügen ).
  3. Geben Sie einen Namen an, der zur Identifizierung Ihres Modells in Ihrem Firebase-Projekt verwendet wird, und laden Sie dann die TensorFlow Lite-Modelldatei .tflite (normalerweise endend mit .tflite oder .lite ).
  4. Erklären Sie im Manifest Ihrer App, dass eine INTERNET-Berechtigung erforderlich ist:
    <uses-permission android:name="android.permission.INTERNET" />
    

Nachdem Sie Ihrem Firebase-Projekt ein benutzerdefiniertes Modell hinzugefügt haben, können Sie das Modell in Ihren Apps unter dem von Ihnen angegebenen Namen referenzieren. Sie können jederzeit ein neues TensorFlow Lite-Modell hochladen. Ihre App lädt das neue Modell herunter und verwendet es beim nächsten Neustart der App. Sie können die Gerätebedingungen definieren, die erforderlich sind, damit Ihre App versucht, das Modell zu aktualisieren (siehe unten).

Modelle mit einer App bündeln

Um Ihr TensorFlow Lite-Modell mit Ihrer App zu bündeln, kopieren Sie die Modelldatei (normalerweise mit .tflite oder .lite ) in die assets/ Ordner Ihrer App. (Möglicherweise müssen Sie den Ordner zuerst erstellen, indem Sie mit der rechten Maustaste auf die app/ Ordner klicken und dann auf Neu> Ordner> Assets-Ordner klicken.)

build.gradle Sie dann der build.gradle Datei Ihrer App build.gradle , um sicherzustellen, dass Gradle die Modelle beim build.gradle der App nicht komprimiert:

android {

    // ...

    aaptOptions {
        noCompress "tflite"  // Your model's file extension: "tflite", "lite", etc.
    }
}

Die Modelldatei wird in das App-Paket aufgenommen und steht ML Kit als Rohstoff zur Verfügung.

Laden Sie das Modell

Um Ihr TensorFlow Lite-Modell in Ihrer App zu verwenden, konfigurieren Sie ML Kit zunächst mit den Speicherorten, an denen Ihr Modell verfügbar ist: Remote-Verwendung von Firebase, lokalem Speicher oder beidem. Wenn Sie sowohl ein lokales als auch ein Remote-Modell angeben, können Sie das Remote-Modell verwenden, sofern es verfügbar ist, und auf das lokal gespeicherte Modell zurückgreifen, wenn das Remote-Modell nicht verfügbar ist.

Konfigurieren Sie ein von Firebase gehostetes Modell

Wenn Sie Ihr Modell mit Firebase gehostet haben, erstellen Sie ein FirebaseCustomRemoteModel Objekt und geben Sie den Namen an, den Sie dem Modell beim Hochladen zugewiesen haben:

Java

FirebaseCustomRemoteModel remoteModel =
        new FirebaseCustomRemoteModel.Builder("your_model").build();

Kotlin + KTX

val remoteModel = FirebaseCustomRemoteModel.Builder("your_model").build()

Starten Sie dann die Modell-Download-Aufgabe und geben Sie die Bedingungen an, unter denen Sie das Herunterladen zulassen möchten. Wenn sich das Modell nicht auf dem Gerät befindet oder eine neuere Version des Modells verfügbar ist, lädt die Task das Modell asynchron von Firebase herunter:

Java

FirebaseModelDownloadConditions conditions = new FirebaseModelDownloadConditions.Builder()
        .requireWifi()
        .build();
FirebaseModelManager.getInstance().download(remoteModel, conditions)
        .addOnCompleteListener(new OnCompleteListener<Void>() {
            @Override
            public void onComplete(@NonNull Task<Void> task) {
                // Success.
            }
        });

Kotlin + KTX

val conditions = FirebaseModelDownloadConditions.Builder()
    .requireWifi()
    .build()
FirebaseModelManager.getInstance().download(remoteModel, conditions)
    .addOnCompleteListener {
        // Success.
    }

Viele Apps starten die Download-Aufgabe in ihrem Initialisierungscode. Sie können dies jedoch jederzeit tun, bevor Sie das Modell verwenden müssen.

Konfigurieren Sie ein lokales Modell

Wenn Sie das Modell mit Ihrer App gebündelt haben, erstellen Sie ein FirebaseCustomLocalModel Objekt und geben Sie den Dateinamen des TensorFlow Lite-Modells an:

Java

FirebaseCustomLocalModel localModel = new FirebaseCustomLocalModel.Builder()
        .setAssetFilePath("your_model.tflite")
        .build();

Kotlin + KTX

val localModel = FirebaseCustomLocalModel.Builder()
    .setAssetFilePath("your_model.tflite")
    .build()

Erstellen Sie einen Interpreter aus Ihrem Modell

Erstellen Sie nach dem Konfigurieren Ihrer FirebaseModelInterpreter aus einem dieser Objekte ein FirebaseModelInterpreter Objekt.

Wenn Sie nur ein lokal gebündeltes Modell haben, erstellen Sie einfach einen Interpreter aus Ihrem FirebaseCustomLocalModel Objekt:

Java

FirebaseModelInterpreter interpreter;
try {
    FirebaseModelInterpreterOptions options =
            new FirebaseModelInterpreterOptions.Builder(localModel).build();
    interpreter = FirebaseModelInterpreter.getInstance(options);
} catch (FirebaseMLException e) {
    // ...
}

Kotlin + KTX

val options = FirebaseModelInterpreterOptions.Builder(localModel).build()
val interpreter = FirebaseModelInterpreter.getInstance(options)

Wenn Sie ein remote gehostetes Modell haben, müssen Sie überprüfen, ob es heruntergeladen wurde, bevor Sie es ausführen. Sie können den Status der Modell-Download-Aufgabe mithilfe der isModelDownloaded() -Methode des isModelDownloaded() .

Obwohl Sie dies nur bestätigen müssen, bevor Sie den Interpreter ausführen, ist es möglicherweise sinnvoll, diese Überprüfung durchzuführen, wenn Sie den Modellinterpreter instanziieren, wenn Sie sowohl ein remote gehostetes Modell als auch ein lokal gebündeltes Modell haben: Erstellen Sie einen Interpreter aus dem Remote-Modell, wenn Es wurde heruntergeladen und ansonsten vom lokalen Modell.

Java

FirebaseModelManager.getInstance().isModelDownloaded(remoteModel)
        .addOnSuccessListener(new OnSuccessListener<Boolean>() {
            @Override
            public void onSuccess(Boolean isDownloaded) {
                FirebaseModelInterpreterOptions options;
                if (isDownloaded) {
                    options = new FirebaseModelInterpreterOptions.Builder(remoteModel).build();
                } else {
                    options = new FirebaseModelInterpreterOptions.Builder(localModel).build();
                }
                FirebaseModelInterpreter interpreter = FirebaseModelInterpreter.getInstance(options);
                // ...
            }
        });

Kotlin + KTX

FirebaseModelManager.getInstance().isModelDownloaded(remoteModel)
    .addOnSuccessListener { isDownloaded -> 
    val options =
        if (isDownloaded) {
            FirebaseModelInterpreterOptions.Builder(remoteModel).build()
        } else {
            FirebaseModelInterpreterOptions.Builder(localModel).build()
        }
    val interpreter = FirebaseModelInterpreter.getInstance(options)
}

Wenn Sie nur ein remote gehostetes Modell haben, sollten Sie die modellbezogenen Funktionen deaktivieren, z. B. einen Teil Ihrer Benutzeroberfläche ausblenden oder ausblenden, bis Sie bestätigen, dass das Modell heruntergeladen wurde. Sie können dies tun, indem Sie einen Listener an die download() -Methode des Modellmanagers anhängen:

Java

FirebaseModelManager.getInstance().download(remoteModel, conditions)
        .addOnSuccessListener(new OnSuccessListener<Void>() {
            @Override
            public void onSuccess(Void v) {
              // Download complete. Depending on your app, you could enable
              // the ML feature, or switch from the local model to the remote
              // model, etc.
            }
        });

Kotlin + KTX

FirebaseModelManager.getInstance().download(remoteModel, conditions)
    .addOnCompleteListener {
        // Download complete. Depending on your app, you could enable the ML
        // feature, or switch from the local model to the remote model, etc.
    }

Geben Sie die Ein- und Ausgabe des Modells an

Konfigurieren Sie als Nächstes die Eingabe- und Ausgabeformate des Modellinterpreten.

Ein TensorFlow Lite-Modell verwendet als Eingabe ein oder mehrere mehrdimensionale Arrays als Ausgabe. Diese Arrays enthalten entweder byte , int , long oder float Werte. Sie müssen ML Kit mit der Anzahl und den Abmessungen ("Form") der von Ihrem Modell verwendeten Arrays konfigurieren.

Wenn Sie die Form und den Datentyp der Eingabe und Ausgabe Ihres Modells nicht kennen, können Sie Ihr Modell mit dem TensorFlow Lite Python-Interpreter überprüfen. Beispielsweise:

import tensorflow as tf

interpreter = tf.lite.Interpreter(model_path="my_model.tflite")
interpreter.allocate_tensors()

# Print input shape and type
print(interpreter.get_input_details()[0]['shape'])  # Example: [1 224 224 3]
print(interpreter.get_input_details()[0]['dtype'])  # Example: <class 'numpy.float32'>

# Print output shape and type
print(interpreter.get_output_details()[0]['shape'])  # Example: [1 1000]
print(interpreter.get_output_details()[0]['dtype'])  # Example: <class 'numpy.float32'>

Nachdem Sie das Format der Eingabe und Ausgabe Ihres Modells festgelegt haben, können Sie den Modellinterpreter Ihrer App konfigurieren, indem Sie ein FirebaseModelInputOutputOptions Objekt erstellen.

Zum Beispiel kann ein Gleitkommawert Bildklassifikationsmodell eine als Eingabe könnte nehmen N x224x224x3 Array von float - Werten, die eine Charge von N 224x224 Dreikanal (RGB) Bilder, und erzeugt als Ausgabe eine Liste von 1000 float Werten, die jeweils die Wahrscheinlichkeit, dass das Bild Mitglied einer der 1000 Kategorien ist, die das Modell vorhersagt.

Für ein solches Modell würden Sie die Ein- und Ausgabe des Modellinterpreten wie folgt konfigurieren:

Java

FirebaseModelInputOutputOptions inputOutputOptions =
        new FirebaseModelInputOutputOptions.Builder()
                .setInputFormat(0, FirebaseModelDataType.FLOAT32, new int[]{1, 224, 224, 3})
                .setOutputFormat(0, FirebaseModelDataType.FLOAT32, new int[]{1, 5})
                .build();

Kotlin + KTX

val inputOutputOptions = FirebaseModelInputOutputOptions.Builder()
        .setInputFormat(0, FirebaseModelDataType.FLOAT32, intArrayOf(1, 224, 224, 3))
        .setOutputFormat(0, FirebaseModelDataType.FLOAT32, intArrayOf(1, 5))
        .build()

Führen Sie eine Inferenz für die Eingabedaten durch

Um eine Inferenz mit dem Modell durchzuführen, rufen Sie Ihre Eingabedaten ab und führen Sie alle Transformationen für die Daten durch, die erforderlich sind, um ein Eingabearray mit der richtigen Form für Ihr Modell zu erhalten.

Wenn Sie beispielsweise ein Bildklassifizierungsmodell mit einer Eingabeform von [1 224 224 3] Gleitkommawerten haben, können Sie ein Eingabearray aus einem Bitmap Objekt generieren, wie im folgenden Beispiel gezeigt:

Java

Bitmap bitmap = getYourInputImage();
bitmap = Bitmap.createScaledBitmap(bitmap, 224, 224, true);

int batchNum = 0;
float[][][][] input = new float[1][224][224][3];
for (int x = 0; x < 224; x++) {
    for (int y = 0; y < 224; y++) {
        int pixel = bitmap.getPixel(x, y);
        // Normalize channel values to [-1.0, 1.0]. This requirement varies by
        // model. For example, some models might require values to be normalized
        // to the range [0.0, 1.0] instead.
        input[batchNum][x][y][0] = (Color.red(pixel) - 127) / 128.0f;
        input[batchNum][x][y][1] = (Color.green(pixel) - 127) / 128.0f;
        input[batchNum][x][y][2] = (Color.blue(pixel) - 127) / 128.0f;
    }
}

Kotlin + KTX

val bitmap = Bitmap.createScaledBitmap(yourInputImage, 224, 224, true)

val batchNum = 0
val input = Array(1) { Array(224) { Array(224) { FloatArray(3) } } }
for (x in 0..223) {
    for (y in 0..223) {
        val pixel = bitmap.getPixel(x, y)
        // Normalize channel values to [-1.0, 1.0]. This requirement varies by
        // model. For example, some models might require values to be normalized
        // to the range [0.0, 1.0] instead.
        input[batchNum][x][y][0] = (Color.red(pixel) - 127) / 255.0f
        input[batchNum][x][y][1] = (Color.green(pixel) - 127) / 255.0f
        input[batchNum][x][y][2] = (Color.blue(pixel) - 127) / 255.0f
    }
}

Erstellen Sie dann ein FirebaseModelInputs Objekt mit Eingabedaten, und gibt ihnen und das Ein- und Ausgabespezifikation des Modells zum Modell Interpreter ‚s run - Methode:

Java

FirebaseModelInputs inputs = new FirebaseModelInputs.Builder()
        .add(input)  // add() as many input arrays as your model requires
        .build();
firebaseInterpreter.run(inputs, inputOutputOptions)
        .addOnSuccessListener(
                new OnSuccessListener<FirebaseModelOutputs>() {
                    @Override
                    public void onSuccess(FirebaseModelOutputs result) {
                        // ...
                    }
                })
        .addOnFailureListener(
                new OnFailureListener() {
                    @Override
                    public void onFailure(@NonNull Exception e) {
                        // Task failed with an exception
                        // ...
                    }
                });

Kotlin + KTX

val inputs = FirebaseModelInputs.Builder()
        .add(input) // add() as many input arrays as your model requires
        .build()
firebaseInterpreter.run(inputs, inputOutputOptions)
        .addOnSuccessListener { result ->
            // ...
        }
        .addOnFailureListener { e ->
            // Task failed with an exception
            // ...
        }

Wenn der Aufruf erfolgreich ist, können Sie die Ausgabe getOutput() indem Sie die Methode getOutput() des Objekts aufrufen, das an den Erfolgslistener übergeben wird. Beispielsweise:

Java

float[][] output = result.getOutput(0);
float[] probabilities = output[0];

Kotlin + KTX

val output = result.getOutput<Array<FloatArray>>(0)
val probabilities = output[0]

Wie Sie die Ausgabe verwenden, hängt vom verwendeten Modell ab.

Wenn Sie beispielsweise als nächsten Schritt eine Klassifizierung durchführen, können Sie die Indizes des Ergebnisses den Beschriftungen zuordnen, die sie darstellen:

Java

BufferedReader reader = new BufferedReader(
        new InputStreamReader(getAssets().open("retrained_labels.txt")));
for (int i = 0; i < probabilities.length; i++) {
    String label = reader.readLine();
    Log.i("MLKit", String.format("%s: %1.4f", label, probabilities[i]));
}

Kotlin + KTX

val reader = BufferedReader(
        InputStreamReader(assets.open("retrained_labels.txt")))
for (i in probabilities.indices) {
    val label = reader.readLine()
    Log.i("MLKit", String.format("%s: %1.4f", label, probabilities[i]))
}

Anhang: Modellsicherheit

Unabhängig davon, wie Sie Ihre TensorFlow Lite-Modelle für ML Kit verfügbar machen, speichert ML Kit sie im standardmäßigen serialisierten Protobuf-Format im lokalen Speicher.

Theoretisch bedeutet dies, dass jeder Ihr Modell kopieren kann. In der Praxis sind die meisten Modelle jedoch so anwendungsspezifisch und durch Optimierungen verschleiert, dass das Risiko dem von Wettbewerbern ähnelt, die Ihren Code zerlegen und wiederverwenden. Sie sollten sich dieses Risikos jedoch bewusst sein, bevor Sie ein benutzerdefiniertes Modell in Ihrer App verwenden.

Ab Android API Level 21 (Lollipop) und neuer wird das Modell in ein Verzeichnis heruntergeladen, das von der automatischen Sicherung ausgeschlossen ist .

com.google.firebase.ml.custom.models Android API Level 20 wird das Modell in ein Verzeichnis mit dem Namen com.google.firebase.ml.custom.models im app-privaten internen Speicher heruntergeladen. Wenn Sie die BackupAgent mit BackupAgent , können Sie dieses Verzeichnis ausschließen.