Benutzerdefiniertes Objekterkennungsmodell mit TensorFlow Lite (Android) erstellen und bereitstellen

1. Hinweis

In diesem Codelab lernen Sie, wie Sie ein benutzerdefiniertes Objekterkennungsmodell mit einer Reihe von Trainingsbildern mit TFLite Model Maker trainieren und dann Ihr Modell mit TFLite Task Library in einer Android-App bereitstellen. Sie werden Folgendes tun:

  • Android-App erstellen, die Zutaten auf Bildern von Speisen erkennt
  • Integrieren Sie ein vortrainiertes TFLite-Objekterkennungsmodell und sehen Sie, was Ihr Modell maximal erkennen kann.
  • Trainieren Sie ein benutzerdefiniertes Objekterkennungsmodell, um die Zutaten/Komponenten einer Mahlzeit mithilfe des benutzerdefinierten Datasets salad und des TFLite Model Maker zu erkennen.
  • Stellen Sie das benutzerdefinierte Modell mithilfe der TFLite-Task-Bibliothek in der Android-App bereit.

Am Ende erstellen Sie in etwa Folgendes:

b9705235366ae162.png

Voraussetzungen

Dieses Codelab wurde für erfahrene mobile Entwickler entwickelt, die Erfahrung mit maschinellem Lernen sammeln möchten. Sie sollten mit Folgendem vertraut sein:

  • Android-Entwicklung mit Kotlin und Android Studio
  • Grundlegende Python-Syntax

Lerninhalte

  • Modell eines benutzerdefinierten Objekterkennungsmodells mit TFLite Model Maker trainieren.
  • Implementierung eines TFLite-Objekterkennungsmodells mithilfe der TFLite-Task-Bibliothek

Voraussetzungen

  • Eine aktuelle Version von Android Studio (Version 4.2 oder höher)
  • Android Studio Emulator oder physisches Android-Gerät
  • Beispielcode
  • Grundkenntnisse der Android-Entwicklung in Kotlin

2. Objekterkennung

Die Objekterkennung ist eine Reihe von Aufgaben für maschinelles Sehen, die Objekte in einem digitalen Bild erkennen und suchen. Anhand eines Bild- oder Videostreams kann ein Objekterkennungsmodell ermitteln, welche bekannten Objekte vorhanden sein könnten, und Informationen zu seinen Positionen im Bild bereitstellen.

TensorFlow bietet vortrainierte, für Mobilgeräte optimierte Modelle, die gängige Objekte wie Autos und Oranges erkennen können. Sie können diese vortrainierten Modelle mit nur wenigen Codezeilen in Ihre mobile App einbinden. Möglicherweise möchten oder sollten Sie Objekte in charakteristischeren oder außergewöhnlicheren Kategorien erkennen. Dazu müssen Sie eigene Trainingsbilder erfassen und dann ein eigenes Objekterkennungsmodell trainieren und bereitstellen.

TensorFlow Lite

TensorFlow Lite ist eine plattformübergreifende Bibliothek für maschinelles Lernen, die für die Ausführung von Modellen für maschinelles Lernen auf Edge-Geräten optimiert ist, einschließlich Android- und iOS-Mobilgeräten.

TensorFlow Lite ist die zentrale Engine, die im ML Kit verwendet wird, um Modelle für maschinelles Lernen auszuführen. Die TensorFlow Lite-Umgebung besteht aus zwei Komponenten, mit denen sich Modelle für maschinelles Lernen auf Mobilgeräten einfach trainieren und bereitstellen lassen:

  • Model Maker ist eine Python-Bibliothek, mit der Sie TensorFlow Lite-Modelle mit nur wenigen Codezeilen ganz einfach anhand Ihrer eigenen Daten trainieren können. Dazu sind keine Kenntnisse im maschinellen Lernen erforderlich.
  • Die Aufgabenbibliothek ist eine plattformübergreifende Bibliothek, mit der sich TensorFlow Lite-Modelle mit nur wenigen Codezeilen in Ihren Apps ganz einfach bereitstellen lassen.

In diesem Codelab geht es um TFLite. Konzepte und Codeblöcke, die für TFLite und Objekterkennung nicht relevant sind, werden nicht erläutert. Sie können sie einfach kopieren und einfügen.

3. Einrichten

Code herunterladen

Klicken Sie auf den folgenden Link, um den gesamten Code für dieses Codelab herunterzuladen:

Entpacken Sie die heruntergeladene ZIP-Datei. Dadurch wird ein Stammordner (odml-pathways-main) mit allen erforderlichen Ressourcen entpackt. Für dieses Codelab benötigen Sie nur die Quellen im Unterverzeichnis object-detection/codelab2/android.

Das Unterverzeichnis android des Repositorys object-detection/codelab2/android enthält zwei Verzeichnisse:

  • android_studio_folder.pngstarter: Startcode, auf dem Sie für dieses Codelab aufbauen.
  • android_studio_folder.pngfinal: Code für die fertige Beispiel-App abgeschlossen

Auslöser-App importieren

Importieren Sie zuerst die Starter-App in Android Studio.

  1. Öffnen Sie Android Studio und wählen Sie Import Project (Gradle, Eclipse ADT usw.) aus.
  2. Öffnen Sie den Ordner starter aus dem Quellcode, den Sie zuvor heruntergeladen haben.

7c0f27882a2698ac

Um sicherzustellen, dass alle Abhängigkeiten für Ihre App verfügbar sind, sollten Sie Ihr Projekt mit Gradle-Dateien synchronisieren, wenn der Import abgeschlossen ist.

  1. Wähle in der Android Studio Symbolleiste die Option Projekt mit Gradle-Dateien synchronisieren (b451ab2d04d835f9.png) aus. Importieren Sie starter/app/build.gradle.

Starter-App ausführen

Nachdem du das Projekt in Android Studio importiert hast, kannst du die App zum ersten Mal ausführen.

Verbinde dein Android-Gerät per USB mit deinem Computer oder starte den Android Studio Emulator und klicke in der Symbolleiste von Android Studio auf Ausführen (Ausführen.png).

4. Einführung der App

Die Starter App enthält einen Boilerplate-Code, mit dem Sie schnell und einfach Änderungen an Ihrem Code vornehmen können:

  • Es können Fotos mit der Kamera des Geräts aufgenommen werden.
  • Es enthält einige Stockfotos, mit denen Sie die Objekterkennung in einem Android Emulator ausprobieren können.
  • Es gibt eine praktische Methode, um das Ergebnis der Objekterkennung auf der Eingabe-Bitmap zu zeichnen.

Sie interagieren hauptsächlich mit diesen Methoden im App-Skelett:

  • fun runObjectDetection(bitmap: Bitmap) Diese Methode wird aufgerufen, wenn Sie ein voreingestelltes Bild auswählen oder ein Foto aufnehmen. bitmap ist das Eingabebild für die Objekterkennung. Später in diesem Codelab werden Sie dieser Methode den Objekterkennungscode hinzufügen.
  • data class DetectionResult(val boundingBoxes: Rect, val text: String) Dies ist eine Datenklasse, die ein Objekterkennungsergebnis für die Visualisierung darstellt. boundingBoxes ist das Rechteck, in dem das Objekt gefunden wird, text ist der Erkennungsergebnisstring, der zusammen mit dem Begrenzungsrahmen des Objekts angezeigt wird.
  • fun drawDetectionResult(bitmap: Bitmap, detectionResults: List<DetectionResult>): Bitmap Diese Methode zeichnet die Ergebnisse der Objekterkennung in detectionResults in der Eingabe-bitmap und gibt die geänderte Kopie davon zurück.

Hier ein Beispiel für eine Ausgabe der Dienstmethode drawDetectionResult:

f6b1e6dad726e129.png

5. Objekterkennung auf dem Gerät hinzufügen

Jetzt erstellen Sie einen Prototyp, indem Sie ein vortrainiertes TFLite-Modell einbinden, das gängige Objekte in der Starter-App erkennt.

Vortrainiertes TFLite-Objekterkennungsmodell herunterladen

Auf TensorFlow Hub können Sie mehrere Objekterkennungsmodelle verwenden. Für dieses Codelab laden Sie das EfficientDet-Lite-Objekterkennungsmodell herunter, das mit dem COCO 2017-Dataset trainiert, für TFLite optimiert und für eine Leistung auf mobilen CPU-, GPU- und EdgeTPU-Modellen entwickelt wurde.

Mit der TFLite-Aufgabenbibliothek können Sie das vortrainierte TFLite-Modell in Ihre Starter-App einbinden. Mit der TFLite-Task-Bibliothek ist es leicht, für Mobilgeräte optimierte Modelle für maschinelles Lernen in eine mobile App einzubinden. Sie unterstützt viele gängige ML-Anwendungsfälle wie Objekterkennung, Bildklassifizierung und Textklassifizierung. Sie können das TFLite-Modell laden und es mit wenigen Codezeilen ausführen.

Modell zur Starter-App hinzufügen

  1. Kopieren Sie das Modell, das Sie gerade heruntergeladen haben, in den Ordner assets der Start-App. Sie finden den Ordner in Android Studio im Projektbereich.

c2609599b7d22641.png

  1. Benennen Sie die Datei model.tflite.

c83e9397177c4561

Abhängigkeiten der Gradle-Datei bei Bibliotheksbibliotheken aktualisieren

Rufe die Datei app/build.gradle auf und füge die folgende Zeile in die dependencies-Konfiguration ein:

implementation 'org.tensorflow:tensorflow-lite-task-vision:0.3.1'

Projekt mit Gradle-Dateien synchronisieren

Damit alle Abhängigkeiten für Ihre App verfügbar sind, sollten Sie Ihr Projekt jetzt mit Gradle-Dateien synchronisieren. Wähle in der Android Studio Symbolleiste die Option Projekt mit Gradle-Dateien synchronisieren (b451ab2d04d835f9.png) aus.

Wenn diese Schaltfläche deaktiviert ist, achten Sie darauf, dass nur der Auslöser/app/build.gradle, nicht das gesamte Repository importiert wird.

Objekterkennung auf dem Gerät einrichten und ausführen

Zum Laden und Ausführen eines Objekterkennungsmodells sind nur drei einfache Schritte erforderlich:

  • Bereite ein Bild / einen Stream vor: TensorImage
  • Detektorobjekt erstellen: ObjectDetector
  • die beiden oben genannten Objekte verbinden: detect(image)

Das geschieht in der Funktion runObjectDetection(bitmap: Bitmap)in der Datei MainActivity.kt.

/**
* TFLite Object Detection Function
*/
private fun runObjectDetection(bitmap: Bitmap) {
    //TODO: Add object detection code here
}

Die Funktion ist momentan leer. Fahren Sie mit den folgenden Schritten fort, um den TFLite-Objektdetektor zu implementieren. In Android Studio werden Sie dann aufgefordert, die erforderlichen Importe hinzuzufügen:

  • org.tensorflow.lite.support.image.TensorImage
  • org.tensorflow.lite.task.vision.detector.ObjectDetector

Bildobjekt erstellen

Die Bilder, die du für dieses Codelab verwendest, stammen entweder von der Kamera auf dem Gerät oder aus voreingestellten Bildern, die du auf der Benutzeroberfläche der App ausgewählt hast. Das Eingabebild wird in das Format Bitmap decodiert und an die Methode runObjectDetection übergeben.

TFLite bietet eine einfache API zum Erstellen einer TensorImage aus Bitmap. Füge den folgenden Code oben in runObjectDetection(bitmap:Bitmap) ein:

// Step 1: create TFLite's TensorImage object
val image = TensorImage.fromBitmap(bitmap)

Detektorinstanz erstellen

Die TFLite-Task-Bibliothek folgt dem Builder-Designmuster. Sie übergeben die Konfiguration an einen Builder und rufen dann einen Detektor ab. Es gibt verschiedene Möglichkeiten, den Objektdetektor anzupassen:

  • Max. Ergebnis (die maximale Anzahl von Objekten, die das Modell erkennen soll)
  • Punktzahl-Schwellenwert (wie wahrscheinlich es ist, dass der Objektdetektor ein erkanntes Objekt zurückgeben soll)
  • Zulassungsliste für Zulassungsliste/Sperrliste (Objekte in einer vordefinierten Liste zulassen/ablehnen)

Initialisieren Sie die Objekterkennungsinstanz, indem Sie den Namen des TFLite-Modells und die Konfigurationsoptionen angeben:

// Step 2: Initialize the detector object
val options = ObjectDetector.ObjectDetectorOptions.builder()
    .setMaxResults(5)
    .setScoreThreshold(0.5f)
    .build()
val detector = ObjectDetector.createFromFileAndOptions(
    this, // the application context
    "model.tflite", // must be same as the filename in assets folder
    options
)

Feedfeed(s) in den Detektor

Fügen Sie fun runObjectDetection(bitmap:Bitmap) den folgenden Code hinzu. Ihre Bilder werden dann an den Detektor gesendet.

// Step 3: feed given image to the model and print the detection result
val results = detector.detect(image)

Nach Abschluss des Detektors wird eine Liste von Detection zurückgegeben, die jeweils Informationen zu einem Objekt enthält, das das Modell im Bild gefunden hat. Jedes Objekt wird so beschrieben:

  • boundingBox: das Rechteck, das das Vorhandensein eines Objekts und seine Position im Bild angibt
  • categories: Gibt an, um welche Art von Objekt es sich handelt und wie zuverlässig das Modell mit dem Erkennungsergebnis ist. Das Modell gibt mehrere Kategorien zurück und die sicherste ist.
  • label: Der Name der Objektkategorie.
  • classificationConfidence: eine Gleitkommazahl zwischen 0,0 und 1,0, wobei 1,0 für 100 % steht

Fügen Sie fun runObjectDetection(bitmap:Bitmap) den folgenden Code hinzu. Sie ruft eine Methode auf, um die Ergebnisse der Objekterkennung an Logcat zu drucken.

// Step 4: Parse the detection result and show it
debugPrint(results)

Füge dann die Methode debugPrint() der Klasse MainActivity hinzu:

private fun debugPrint(results : List<Detection>) {
    for ((i, obj) in results.withIndex()) {
        val box = obj.boundingBox

        Log.d(TAG, "Detected object: ${i} ")
        Log.d(TAG, "  boundingBox: (${box.left}, ${box.top}) - (${box.right},${box.bottom})")

        for ((j, category) in obj.categories.withIndex()) {
            Log.d(TAG, "    Label $j: ${category.label}")
            val confidence: Int = category.score.times(100).toInt()
            Log.d(TAG, "    Confidence: ${confidence}%")
        }
    }
} 

Der Objektdetektor ist fertig. Kompilieren und führen Sie die App aus, indem Sie in der Android Studio-Symbolleiste auf Ausführen (Ausführen.png) klicken. Sobald die App auf dem Gerät angezeigt wird, tippen Sie auf eines der voreingestellten Bilder, um den Objektdetektor zu starten. Sehen Sie sich dann das Fenster Logcat*(* 16bd6ea224cf8cf1*)* in der IDE an. Es sollte in etwa so aussehen:

D/TFLite-ODT: Detected object: 0 
D/TFLite-ODT:   boundingBox: (0.0, 15.0) - (2223.0,1645.0)
D/TFLite-ODT:     Label 0: dining table
D/TFLite-ODT:     Confidence: 77%
D/TFLite-ODT: Detected object: 1 
D/TFLite-ODT:   boundingBox: (702.0, 3.0) - (1234.0,797.0)
D/TFLite-ODT:     Label 0: cup
D/TFLite-ODT:     Confidence: 69%

Damit sehen Sie, dass der Detektor zwei Objekte gesehen hat. Die erste lautet:

  • Ein Objekt befindet sich innerhalb des Rechtecks von (0, 15) bis (2223, 1645)
  • Das Label ist Esstisch
  • Das Modell ist zuversichtlich, dass der erste ein Esstisch ist (77%)

Technisch ist das alles, was Sie brauchen, um die TFLite-Task-Bibliothek nutzen zu können. Sie haben momentan alles gefunden. Glückwunsch!

Auf der Benutzeroberfläche befinden Sie sich jedoch immer noch am Anfang. Jetzt müssen Sie die erkannten Ergebnisse auf der Benutzeroberfläche verwenden.

6. Ergebnis der Erkennung im Eingabebild zeichnen

In den vorherigen Schritten haben Sie das Erkennungsergebnis in logcat ausgegeben: einfach und schnell. In diesem Schritt werden Sie die bereits in der Start-App implementierte Dienstprogrammmethode verwenden, um:

  • Begrenzungsrahmen auf ein Bild zeichnen
  • Einen Kategorienamen und einen Konfidenzprozentsatz innerhalb des Begrenzungsrahmens zeichnen
  1. Ersetzen Sie den Aufruf debugPrint(results) durch das folgende Code-Snippet:
val resultToDisplay = results.map {
    // Get the top-1 category and craft the display text
    val category = it.categories.first()
    val text = "${category.label}, ${category.score.times(100).toInt()}%"

    // Create a data object to display the detection result
    DetectionResult(it.boundingBox, text)
}
// Draw the detection result on the bitmap and show it.
val imgWithResult = drawDetectionResult(bitmap, resultToDisplay)
runOnUiThread {
    inputImageView.setImageBitmap(imgWithResult)
}
  1. Klicken Sie in der Android Studio Symbolleiste auf Ausführen ( Ausführen.png).
  2. Tippen Sie nach dem Laden der App auf eines der voreingestellten Bilder, um das Erkennungsergebnis aufzurufen.

Möchten Sie ein eigenes Foto ausprobieren? Tippen Sie auf die Schaltfläche Foto aufnehmen, um Fotos von Objekten in der Nähe aufzunehmen.

8b024362b15096a6

7. Benutzerdefiniertes Objekterkennungsmodell trainieren

Im vorherigen Schritt haben Sie ein vortrainiertes TFLite-Objekterkennungsmodell in die Android-App integriert und erkannte, dass in den Beispielbildern gängige Objekte wie Bowls oder Esstische erkannt werden. Ihr Ziel ist es jedoch, die Zutaten des Gerichts auf dem Bild zu erkennen, weshalb die allgemeine Objekterkennung nicht zum Anwendungsfall passt. Sie möchten ein benutzerdefiniertes Objekterkennungsmodell trainieren, indem Sie ein Trainings-Dataset mit den Zutaten verwenden, die wir erkennen möchten.

Hier finden Sie ein Dataset mit Bildern und Labels, mit denen Sie Ihr eigenes benutzerdefiniertes Modell trainieren können. Sie wurde mit Bildern aus dem Open Images Dataset V4 erstellt.

Colaboratory

Als Nächstes trainieren wir das benutzerdefinierte Modell in Google Colab.

Es dauert etwa 30 Minuten, das benutzerdefinierte Modell zu trainieren.

Wenn Sie es eilig haben, können Sie ein Modell herunterladen, das wir für Sie mit dem bereitgestellten Dataset vortrainiert haben, und mit dem nächsten Schritt fortfahren.

8. Benutzerdefiniertes TFLite-Modell in die Android-App einbinden

Sie haben das Modell zur Salaterkennung jetzt trainiert. Jetzt können Sie es einbinden und Ihre App von einem gängigen Objektdetektor auf einen Salatdetektor umstellen.

  1. Kopieren Sie das Salat-TFLite-Modell in den Ordner assets. Geben Sie dem neuen Modell den Namen salad.tflite.

91e8d37c4f78eddb.png

  1. Öffne die MainActivity.kt-Datei und suche den Initialisierungscode ObjectDetector.
  2. EfficientDet-Lite-Modell (model.tflite) durch Salatmodell (salad.tflite) ersetzen
val detector = ObjectDetector.createFromFileAndOptions(
    this, // the application context
    "salad.tflite", // must be same as the filename in assets folder
    options
)
  1. Klicken Sie in der Symbolleiste von Android Studio auf Run (Ausführen.png), um die App mit dem neuen Modell noch einmal auszuführen. Voilà! Die App erkennt jetzt Käse, Salat und Backwaren.

b9705235366ae162.png

9. Glückwunsch!

Sie haben mit TFLite ein benutzerdefiniertes Modell trainiert und die Funktionen für die Objekterkennung in Ihre App aufgenommen. Es ist alles, was Sie für die Einrichtung benötigen.

Behandelte Themen

  • Vortrainierte TFLite-Objekterkennungsmodelle in TensorFlow Hub finden
  • Objekte mithilfe der TFLite-Task-Bibliothek in Android-Apps einbinden
  • Modell zur benutzerdefinierten Objekterkennung mit TFLite Model Maker trainieren

Nächste Schritte

  • Firebase mit dem TFLite-Modell bereitstellen
  • Trainingsdaten zum Trainieren eines eigenen Modells erfassen
  • Objekterkennung in deiner eigenen Android-App anwenden

Weitere Informationen