Crea ed esegui il deployment di un modello di rilevamento di oggetti personalizzato con TensorFlow Lite (Android)

1. Prima di iniziare

In questo codelab, imparerai ad addestrare un modello di rilevamento di oggetti personalizzato utilizzando un set di immagini di addestramento con TFLite Model Maker, quindi a eseguire il deployment del modello in un'app Android utilizzando la Libreria attività di TFLite. Imparerai a:

  • Crea un'app Android che rilevi gli ingredienti nelle immagini dei pasti.
  • Integra un modello di rilevamento di oggetti preaddestrato TFLite e visualizza il limite di ciò che il modello può rilevare.
  • Addestra un modello di rilevamento di oggetti personalizzato per rilevare gli ingredienti/componenti di un pasto utilizzando un set di dati personalizzato denominato insalata e TFLite Model Maker.
  • Esegui il deployment del modello personalizzato nell'app Android utilizzando la libreria di attività TFLite.

Alla fine, creerai qualcosa di simile all'immagine seguente:

b9705235366ae162.png

Prerequisiti

Questo codelab è stato progettato per sviluppatori di dispositivi mobili esperti che vogliono acquisire esperienza con il machine learning. Dovresti acquisire familiarità con:

  • Sviluppo Android con Kotlin e Android Studio
  • Sintassi Python di base

Cosa imparerai a fare:

  • Come addestrare un modello di rilevamento di oggetti personalizzato utilizzando TFLite Model Maker.
  • Come eseguire il deployment di un modello di rilevamento oggetti TFLite utilizzando la libreria di attività TFLite.

Che cosa ti serve

  • Una versione recente di Android Studio (v4.2+)
  • Emulatore di Android Studio o un dispositivo Android fisico
  • Codice di esempio
  • Conoscenza di base dello sviluppo di Android in Kotlin

2. Rilevamento di oggetti

Il rilevamento di oggetti è un insieme di attività di visione artificiale in grado di rilevare e individuare oggetti in un'immagine digitale. Data un'immagine o un video stream, un modello di rilevamento degli oggetti può identificare quale di un insieme noto di oggetti potrebbe essere presente e fornire informazioni sulle loro posizioni all'interno dell'immagine.

TensorFlow fornisce modelli preaddestrati ottimizzati per dispositivi mobili in grado di rilevare oggetti comuni, come auto, arancioni e così via. Puoi integrare questi modelli preaddestrati nella tua app per dispositivi mobili con poche righe di codice. Tuttavia, potrebbe essere necessario o necessario rilevare gli oggetti in categorie più distintive o insolite. Ciò richiede la raccolta di immagini di addestramento, quindi l'addestramento e il deployment del tuo modello di rilevamento oggetti.

TensorFlow Lite

TensorFlow Lite è una libreria multipiattaforma di machine learning ottimizzata per l'esecuzione di modelli di machine learning su dispositivi periferici, inclusi i dispositivi mobili Android e iOS.

TensorFlow Lite è in realtà il motore principale utilizzato all'interno di ML Kit per eseguire modelli di machine learning. L'ecosistema TensorFlow Lite include due componenti che semplificano l'addestramento e il deployment dei modelli di machine learning sui dispositivi mobili:

  • Model Maker è una libreria Python che consente di addestrare facilmente i modelli TensorFlow Lite utilizzando i tuoi dati con poche righe di codice, senza bisogno di competenze nel machine learning.
  • La libreria di attività è una libreria multipiattaforma che consente di eseguire facilmente il deployment dei modelli TensorFlow Lite con poche righe di codice nelle app per dispositivi mobili.

Questo codelab è incentrato su TFLite. Concetti e blocchi di codice non pertinenti a TFLite e al rilevamento degli oggetti non vengono spiegati e vengono forniti soltanto per copiare e incollare.

3. Configura

Scarica il codice

Fai clic sul seguente link per scaricare tutto il codice di questo codelab:

Apri il file ZIP scaricato. Verrà aperta una cartella principale (odml-pathways-main) che conterrà tutte le risorse necessarie. Per questo codelab, avrai bisogno solo delle origini nella sottodirectory object-detection/codelab2/android.

La sottodirectory android nel repository object-detection/codelab2/android contiene due directory:

  • cartella_studio_android.pngstarter: il codice di avvio sulla quale crei questo codelab.
  • cartella_studio_android.pngfinal: è stato completato il codice per l'app di esempio terminata.

Importare l'app iniziale

Iniziamo importando l'app iniziale in Android Studio.

  1. Apri Android Studio e seleziona Importa progetto (Gradle, Eclipse ADT ecc.).
  2. Apri la cartella starter dal codice sorgente che hai scaricato in precedenza.

7c0f27882a2698ac.png

Per assicurarti che tutte le dipendenze siano disponibili per la tua app, devi sincronizzare il tuo progetto con file di Gradle al termine del processo di importazione.

  1. Seleziona Sincronizza progetto con file Gradle ( b451ab2d04d835f9.png) dalla barra degli strumenti di Android Studio. Importa starter/app/build.gradle

Esegui l'app iniziale

Ora che hai importato il progetto in Android Studio, puoi eseguire l'app per la prima volta.

Collega il dispositivo Android tramite USB al computer o avvia l'emulatore Android Studio, quindi fai clic su Esegui (esegui.png) nella barra degli strumenti di Android Studio.

4. Comprendere l'app iniziale

Per mantenere questo codelab semplice e incentrato sui bit di machine learning, l'app iniziale contiene un codice boilerplate che esegue alcune operazioni per te:

  • Può scattare foto utilizzando la fotocamera del dispositivo.
  • Contiene alcune immagini stock che puoi utilizzare per provare il rilevamento di oggetti su un emulatore Android.
  • Offre un metodo pratico per disegnare il risultato del rilevamento di oggetti sulla bitmap di input.

interagirai principalmente con questi metodi nello scheletro dell'app:

  • fun runObjectDetection(bitmap: Bitmap) Questo metodo viene chiamato quando scegli un'immagine preimpostata o scatti una foto. bitmap è l'immagine di input per il rilevamento di oggetti. Più avanti nel codelab, aggiungerai il codice di rilevamento oggetti a questo metodo.
  • data class DetectionResult(val boundingBoxes: Rect, val text: String) Questa è una classe di dati che rappresenta un risultato di rilevamento di oggetti per la visualizzazione. boundingBoxes è il rettangolo in cui si trova l'oggetto, mentre text è la stringa del risultato di rilevamento da visualizzare insieme al riquadro di delimitazione dell'oggetto.
  • fun drawDetectionResult(bitmap: Bitmap, detectionResults: List<DetectionResult>): Bitmap Questo metodo traccia i risultati del rilevamento degli oggetti in detectionResults sull'input bitmap e restituisce la copia modificata dello stesso.

Ecco un esempio di output del metodo di utilità drawDetectionResult.

f6b1e6dad726e129.png

5. Aggiungi rilevamento oggetti sul dispositivo

Ora creerai un prototipo integrando un modello TFLite preaddestrato in grado di rilevare oggetti comuni nell'app di avvio.

Scarica un modello di rilevamento di oggetti TFLite preaddestrato

Su TensorFlow Hub puoi utilizzare diversi modelli di rilevatori di oggetti. Per questo codelab, scaricherai il modello di rilevamento di oggetti EffectiveDet-Lite, addestrato sul set di dati COCO 2017, ottimizzato per TFLite e progettato per le prestazioni su CPU mobile, GPU ed EdgeTPU.

Successivamente, utilizza la libreria di attività TFLite per integrare il modello TFLite preaddestrato nella tua app iniziale. La libreria di attività TFLite semplifica l'integrazione di modelli di machine learning ottimizzati per dispositivi mobili in un'app per dispositivi mobili. Supporta molti casi d'uso di machine learning comuni, tra cui rilevamento di oggetti, classificazione di immagini e classificazione di testo. Puoi caricare il modello TFLite ed eseguirlo con poche righe di codice.

Aggiungere il modello all'app iniziale

  1. Copia il modello che hai appena scaricato nella cartella assets dell'app iniziale. Puoi trovare la cartella nel pannello di navigazione Progetto in Android Studio.

c2609599b7d22641.png

  1. Assegna al file il nome model.tflite.

c83e9397177c4561.png

Aggiornare le dipendenze della libreria delle attività del file Gradle

Passa al file app/build.gradle e aggiungi questa riga alla configurazione dependencies:

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

Sincronizzare il progetto con file Gradle

Per assicurarti che tutte le dipendenze siano disponibili per la tua app, a questo punto dovresti sincronizzare il tuo progetto con file di Gradle. Seleziona Sincronizza progetto con file Gradle (b451ab2d04d835f9.png) dalla barra degli strumenti di Android Studio.

(Se questo pulsante non è attivo, assicurati di importare solo starter/app/build.gradle, non l'intero repository.)

Configurare ed eseguire il rilevamento degli oggetti sul dispositivo su un'immagine

Ci sono solo tre semplici passaggi con tre API per caricare ed eseguire un modello di rilevamento degli oggetti:

  • prepara un'immagine/uno stream: TensorImage
  • crea un oggetto rilevatore: ObjectDetector
  • connetti i due oggetti in alto: detect(image)

che puoi raggiungere all'interno della funzione runObjectDetection(bitmap: Bitmap)nel file MainActivity.kt.

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

Al momento la funzione è vuota. Per implementare il rilevatore di oggetti TFLite, vai ai passaggi seguenti. Durante il processo, Android Studio ti chiederà di aggiungere le importazioni necessarie:

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

Crea oggetto immagine

Le immagini che utilizzerai per questo codelab verranno dalla fotocamera del dispositivo o dalle immagini preimpostate selezionate nell'interfaccia utente dell'app. L'immagine di input viene decodificata nel formato Bitmap e trasmessa al metodo runObjectDetection.

TFLite fornisce un'API semplice per creare un TensorImage da Bitmap. Aggiungi il seguente codice in alto a runObjectDetection(bitmap:Bitmap):

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

Creare un'istanza di Detector

La libreria di attività TFLite segue lo schema di progettazione di Builder. Passi la configurazione a un generatore, da cui poi acquisisci un rilevatore. Esistono diverse opzioni da configurare, incluse quelle per regolare la sensibilità del rilevatore di oggetti:

  • risultato massimo (il numero massimo di oggetti che il modello deve rilevare)
  • soglia di sicurezza (il grado di confidenza che il rilevatore di oggetti deve restituire per un oggetto rilevato)
  • etichetta lista consentita/denylist (consentire/negare gli oggetti in un elenco predefinito)

Inizializza l'istanza del rilevatore di oggetti specificando il nome file del modello TFLite e le opzioni di configurazione:

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

Invia immagini al rilevatore

Aggiungi il seguente codice a fun runObjectDetection(bitmap:Bitmap). Le tue immagini verranno inviate al rilevatore.

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

Al termine, il rilevatore restituisce un elenco di Detection, ognuno dei quali contiene informazioni su un oggetto trovato nell'immagine. Ogni oggetto è descritto con:

  • boundingBox: il rettangolo per dichiarare la presenza di un oggetto e la sua posizione all'interno dell'immagine
  • categories: che tipo di oggetto è e quanto è sicuro il modello con il risultato del rilevamento. Il modello restituisce più categorie, a partire dalla più sicura.
  • label: il nome della categoria dell'oggetto.
  • classificationConfidence: un numero in virgola mobile compreso tra 0,0 e 1,0, dove 1,0 rappresenta il 100%

Aggiungi il seguente codice a fun runObjectDetection(bitmap:Bitmap). Viene chiamato un metodo per stampare i risultati di rilevamento di oggetti in Logcat.

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

Quindi aggiungi questo debugPrint()metodo alla classe MainActivity:

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

Ora il rilevatore di oggetti è pronto. Compila ed esegui l'app facendo clic su Esegui ( esegui.png) nella barra degli strumenti di Android Studio. Una volta che l'app viene visualizzata sul dispositivo, tocca una delle immagini preimpostate per avviare il rilevatore di oggetti. Quindi, controlla la finestra Logcat*(* 16bd6ea224cf8cf1.png*)* all'interno del tuo IDE e il risultato dovrebbe essere simile a questo:

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%

Questo indica che il rilevatore ha rilevato 2 oggetti. La prima è:

  • Un oggetto è all'interno di un rettangolo di (0, 15) - (2223, 1645)
  • L'etichetta è tavola da pranzo
  • Il modello ha la certezza che il primo sia un tavolo da pranzo (77%)

Tecnicamente è tutto ciò che ti serve per far funzionare la Libreria attività di TFLite: è tutto al momento! Complimenti,

Tuttavia, dal lato utente, sei ancora nel punto iniziale. Ora devi utilizzare i risultati rilevati nell'interfaccia utente, dopo aver elaborato i risultati.

6. Disegna il risultato del rilevamento sull'immagine di input

Nei passaggi precedenti, hai stampato il risultato del rilevamento in logcat: semplice e veloce. In questo passaggio, utilizzerai il metodo di utilità già implementato nell'app iniziale, allo scopo di:

  • disegnare un riquadro di delimitazione su un'immagine
  • Disegna un nome di categoria e una percentuale di confidenza all'interno del riquadro di delimitazione
  1. Sostituisci la chiamata debugPrint(results) con il seguente snippet di codice:
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. Ora fai clic su Esegui ( esegui.png) nella barra degli strumenti di Android Studio.
  2. Una volta caricata l'app, tocca una delle immagini preimpostate per visualizzare il risultato del rilevamento.

Vuoi provare con la tua foto? Tocca il pulsante Scatta una foto e acquisisci alcune foto di oggetti intorno a te.

8b024362b15096a6.png

7. Addestra un modello di rilevamento di oggetti personalizzato

Nel passaggio precedente hai integrato un modello di rilevamento di oggetti TFLite preaddestrato nell'app Android e hai verificato che può rilevare oggetti comuni, come ciotole o tavoli da pranzo, in immagini di esempio. Tuttavia, il tuo obiettivo è rilevare gli ingredienti dei piatti nell'immagine, quindi il rilevamento generale degli oggetti non si adatta al tuo caso d'uso. Vuoi addestrare un modello di rilevamento di oggetti personalizzato utilizzando un set di dati di addestramento con gli ingredienti che vogliamo rilevare.

Di seguito è riportato un set di dati contenente immagini ed etichette che puoi utilizzare per esercitarti a addestrare il tuo modello personalizzato. È stata creata utilizzando immagini provenienti dal set di dati di Open Images V4.

Colaboratory

Passiamo ora a Google Colab per addestrare il modello personalizzato.

Per addestrare il modello personalizzato sono necessari circa 30 minuti.

Se hai poco tempo, puoi scaricare un modello che abbiamo preaddestrato per te sul set di dati fornito e procedere al passaggio successivo.

8. Integrare il modello TFLite personalizzato nell'app Android

Ora che hai addestrato un modello di rilevamento di insalata, esegui l'integrazione e trasforma l'app da un rilevatore comune di oggetti a un rilevatore di insalata.

  1. Copia il modello TFLite insalata nella cartella assets. Assegna al nuovo modello il nome salad.tflite.

91e8d37c4f78eddb.png

  1. Apri il file MainActivity.kt e cerca il codice di inizializzazione di ObjectDetector.
  2. Sostituisci il modello EffectiveDet-Lite (model.tflite) con il modello insalata (salad.tflite)
val detector = ObjectDetector.createFromFileAndOptions(
    this, // the application context
    "salad.tflite", // must be same as the filename in assets folder
    options
)
  1. Fai clic su Esegui (esegui.png) nella barra degli strumenti di Android Studio per eseguire nuovamente l'app con il nuovo modello. Ecco fatto. L'app è ora in grado di riconoscere formaggi, insalate, prodotti da forno.

b9705235366ae162.png

9. Complimenti!

Hai utilizzato TFLite per addestrare un modello personalizzato e aggiungere funzionalità di rilevamento oggetti alla tua app. È tutto ciò che ti serve per iniziare a lavorare.

Cosa abbiamo trattato

  • Come trovare modelli di rilevamento di oggetti TFLite preaddestrati su TensorFlow Hub
  • Come integrare i modelli di rilevamento delle obiezioni nella tua app Android utilizzando la libreria di attività TFLite
  • Come addestrare il modello di rilevamento di oggetti personalizzato con TFLite Model Maker

Passaggi successivi

  • Utilizza Firebase per migliorare il deployment del modello TFLite
  • Raccogli dati di addestramento per addestrare il tuo modello
  • Applicare il rilevamento degli oggetti nella tua app Android

Ulteriori informazioni