Riconoscimento di suoni e parole per Android

Questo tutorial mostra come utilizzare TensorFlow Lite con modelli di machine learning predefiniti per riconoscere suoni e parole pronunciate in un'app Android. I modelli di classificazione audio come quelli mostrati in questo tutorial possono essere utilizzati per rilevare attività, identificare azioni o riconoscere comandi vocali.

Demo animata di riconoscimento audio Questo tutorial ti mostra come scaricare il codice di esempio, caricare il progetto in Android Studio e spiega le parti principali dell'esempio di codice in modo da poter iniziare ad aggiungere questa funzionalità alla tua app. Il codice dell'app di esempio utilizza TensorFlow Task Library for Audio , che gestisce la maggior parte della registrazione e della preelaborazione dei dati audio. Per ulteriori informazioni su come l'audio viene pre-elaborato per l'utilizzo con i modelli di machine learning, consulta Preparazione e incremento dei dati audio .

Classificazione audio con machine learning

Il modello di machine learning in questo tutorial riconosce suoni o parole da campioni audio registrati con un microfono su un dispositivo Android. L'app di esempio in questo tutorial ti consente di passare da YAMNet/classifier , un modello che riconosce i suoni, a un modello che riconosce parole pronunciate specifiche, addestrato utilizzando lo strumento TensorFlow Lite Model Maker . I modelli eseguono previsioni su clip audio che contengono 15.600 singoli campioni per clip e durano circa 1 secondo.

Esempio di configurazione ed esecuzione

Per la prima parte di questo tutorial, scaricherai l'esempio da GitHub e lo eseguirai utilizzando Android Studio. Le sezioni seguenti di questo tutorial esplorano le sezioni pertinenti dell'esempio, in modo da poterle applicare alle tue app Android.

Requisiti di sistema

  • Android Studio versione 2021.1.1 (Bumblebee) o successiva.
  • Android SDK versione 31 o successiva
  • Dispositivo Android con una versione del sistema operativo minima SDK 24 (Android 7.0 - Nougat) con modalità sviluppatore abilitata.

Ottieni il codice di esempio

Crea una copia locale del codice di esempio. Utilizzerai questo codice per creare un progetto in Android Studio ed eseguire l'applicazione di esempio.

Per clonare e configurare il codice di esempio:

  1. Clona il repository git
    git clone https://github.com/tensorflow/examples.git
    
  2. Facoltativamente, configura la tua istanza git per utilizzare il checkout sparse, in modo da avere solo i file per l'app di esempio:

    cd examples
    git sparse-checkout init --cone
    git sparse-checkout set lite/examples/audio_classification/android
    

Importare ed eseguire il progetto

Crea un progetto dal codice di esempio scaricato, crea il progetto e quindi eseguilo.

Per importare e creare il progetto di codice di esempio:

  1. Avvia Android Studio .
  2. In Android Studio, scegli File > Nuovo > Importa progetto .
  3. Passare alla directory del codice di esempio contenente il file build.gradle ( .../examples/lite/examples/audio_classification/android/build.gradle ) e selezionare quella directory.

Se selezioni la directory corretta, Android Studio crea un nuovo progetto e lo crea. Questo processo può richiedere alcuni minuti, a seconda della velocità del tuo computer e se hai utilizzato Android Studio per altri progetti. Una volta completata la build, Android Studio visualizza un messaggio BUILD SUCCESSFUL nel pannello di stato dell'output della build .

Per eseguire il progetto:

  1. Da Android Studio, esegui il progetto selezionando Esegui > Esegui 'app' .
  2. Seleziona un dispositivo Android collegato con un microfono per testare l'app.

Le sezioni successive mostrano le modifiche che devi apportare al tuo progetto esistente per aggiungere questa funzionalità alla tua app, utilizzando questa app di esempio come punto di riferimento.

Aggiungi dipendenze del progetto

Nella tua applicazione, devi aggiungere dipendenze di progetto specifiche per eseguire modelli di machine learning TensorFlow Lite e accedere a funzioni di utilità che convertono formati di dati standard, come l'audio, in un formato di dati tensore che può essere elaborato dal modello che stai utilizzando.

L'app di esempio utilizza le seguenti librerie TensorFlow Lite:

Le seguenti istruzioni mostrano come aggiungere le dipendenze del progetto richieste al tuo progetto di app Android.

Per aggiungere dipendenze del modulo:

  1. Nel modulo che utilizza TensorFlow Lite, aggiorna il file build.gradle del modulo per includere le seguenti dipendenze. Nel codice di esempio, questo file si trova qui: .../examples/lite/examples/audio_classification/android/build.gradle

    dependencies {
    ...
        implementation 'org.tensorflow:tensorflow-lite-task-audio'
    }
    
  2. In Android Studio, sincronizza le dipendenze del progetto selezionando: File > Sincronizza progetto con file Gradle .

Inizializza il modello ML

Nella tua app Android, devi inizializzare il modello di machine learning TensorFlow Lite con i parametri prima di eseguire previsioni con il modello. Questi parametri di inizializzazione dipendono dal modello e possono includere impostazioni come soglie di precisione minime predefinite per previsioni ed etichette per parole o suoni che il modello può riconoscere.

Un modello TensorFlow Lite include un file *.tflite contenente il modello. Il file del modello contiene la logica della previsione e in genere include metadati su come interpretare i risultati della previsione, ad esempio i nomi delle classi di previsione. I file del modello dovrebbero essere archiviati nella directory src/main/assets del tuo progetto di sviluppo, come nell'esempio di codice:

  • <project>/src/main/assets/yamnet.tflite

Per comodità e leggibilità del codice, l'esempio dichiara un oggetto associato che definisce le impostazioni per il modello.

Per inizializzare il modello nella tua app:

  1. Crea un oggetto associato per definire le impostazioni per il modello:

    companion object {
      const val DISPLAY_THRESHOLD = 0.3f
      const val DEFAULT_NUM_OF_RESULTS = 2
      const val DEFAULT_OVERLAP_VALUE = 0.5f
      const val YAMNET_MODEL = "yamnet.tflite"
      const val SPEECH_COMMAND_MODEL = "speech.tflite"
    }
    
  2. Crea le impostazioni per il modello costruendo un oggetto AudioClassifier.AudioClassifierOptions :

    val options = AudioClassifier.AudioClassifierOptions.builder()
      .setScoreThreshold(classificationThreshold)
      .setMaxResults(numOfResults)
      .setBaseOptions(baseOptionsBuilder.build())
      .build()
    
  3. Utilizza questo oggetto impostazioni per costruire un oggetto TensorFlow Lite AudioClassifier che contiene il modello:

    classifier = AudioClassifier.createFromFileAndOptions(context, "yamnet.tflite", options)
    

Abilita l'accelerazione hardware

Quando inizializzi un modello TensorFlow Lite nella tua app, dovresti prendere in considerazione l'utilizzo delle funzionalità di accelerazione hardware per accelerare i calcoli di previsione del modello. I delegati TensorFlow Lite sono moduli software che accelerano l'esecuzione di modelli di machine learning utilizzando hardware di elaborazione specializzato su un dispositivo mobile, come unità di elaborazione grafica (GPU) o unità di elaborazione tensore (TPU). L'esempio di codice utilizza il delegato NNAPI per gestire l'accelerazione hardware dell'esecuzione del modello:

val baseOptionsBuilder = BaseOptions.builder()
   .setNumThreads(numThreads)
...
when (currentDelegate) {
   DELEGATE_CPU -> {
       // Default
   }
   DELEGATE_NNAPI -> {
       baseOptionsBuilder.useNnapi()
   }
}

L'utilizzo dei delegati per l'esecuzione dei modelli TensorFlow Lite è consigliato, ma non obbligatorio. Per ulteriori informazioni sull'utilizzo dei delegati con TensorFlow Lite, consulta Delegati TensorFlow Lite .

Preparare i dati per il modello

Nella tua app Android, il tuo codice fornisce dati al modello per l'interpretazione trasformando i dati esistenti come clip audio in un formato dati Tensor che può essere elaborato dal tuo modello. I dati in un tensore che passi a un modello devono avere dimensioni o forma specifiche che corrispondano al formato dei dati utilizzati per addestrare il modello.

Il modello YAMNet/classificatore e i modelli di comandi vocali personalizzati utilizzati in questo esempio di codice accettano oggetti dati Tensor che rappresentano clip audio a canale singolo o mono registrate a 16kHz in clip da 0,975 secondi (15600 campioni). Eseguendo previsioni su nuovi dati audio, la tua app deve trasformare tali dati audio in oggetti dati tensore di quella dimensione e forma. L' API audio della libreria attività TensorFlow Lite gestisce la trasformazione dei dati per te.

Nel codice di esempio della classe AudioClassificationHelper , l'app registra l'audio dal vivo dai microfoni del dispositivo utilizzando un oggetto Android AudioRecord . Il codice utilizza AudioClassifier per creare e configurare l'oggetto per registrare l'audio a una frequenza di campionamento appropriata per il modello. Il codice utilizza anche AudioClassifier per creare un oggetto TensorAudio per archiviare i dati audio trasformati. Quindi l'oggetto TensorAudio viene passato al modello per l'analisi.

Per fornire dati audio al modello ML:

  • Utilizza l'oggetto AudioClassifier per creare un oggetto TensorAudio e un oggetto AudioRecord :

    fun initClassifier() {
    ...
      try {
        classifier = AudioClassifier.createFromFileAndOptions(context, currentModel, options)
        // create audio input objects
        tensorAudio = classifier.createInputTensorAudio()
        recorder = classifier.createAudioRecord()
      }
    

Esegui previsioni

Nella tua app Android, dopo aver connesso un oggetto AudioRecord e un oggetto TensorAudio a un oggetto AudioClassifier, puoi eseguire il modello rispetto a tali dati per produrre una previsione o un'inferenza . Il codice di esempio per questo tutorial esegue previsioni su clip da un flusso di input audio registrato dal vivo a una velocità specifica.

L'esecuzione del modello consuma risorse significative, quindi è importante eseguire le previsioni del modello ML su un thread in background separato. L'app di esempio utilizza un oggetto [ScheduledThreadPoolExecutor](https://developer.android.com/reference/java/util/concurrent/ScheduledThreadPoolExecutor) per isolare l'elaborazione del modello da altre funzioni dell'app.

I modelli di classificazione audio che riconoscono i suoni con un inizio e una fine chiari, come le parole, possono produrre previsioni più accurate su un flusso audio in entrata analizzando clip audio sovrapposte. Questo approccio aiuta il modello a evitare previsioni mancanti per le parole troncate alla fine di una clip. Nell'app di esempio, ogni volta che esegui una previsione, il codice preleva l'ultima clip da 0,975 secondi dal buffer di registrazione audio e la analizza. È possibile fare in modo che il modello analizzi clip audio sovrapposti impostando il valore interval del pool di esecuzione del thread di analisi del modello su una lunghezza inferiore alla lunghezza delle clip analizzate. Ad esempio, se il modello analizza clip da 1 secondo e imposti l'intervallo su 500 millisecondi, il modello analizzerà ogni volta l'ultima metà della clip precedente e 500 millisecondi di nuovi dati audio, creando una sovrapposizione dell'analisi della clip del 50%.

Per iniziare a eseguire previsioni sui dati audio:

  1. Utilizza il metodo AudioClassificationHelper.startAudioClassification() per avviare la registrazione audio per il modello:

    fun startAudioClassification() {
      if (recorder.recordingState == AudioRecord.RECORDSTATE_RECORDING) {
        return
      }
      recorder.startRecording()
    }
    
  2. Imposta la frequenza con cui il modello genera un'inferenza dalle clip audio impostando un interval di frequenza fissa nell'oggetto ScheduledThreadPoolExecutor :

    executor = ScheduledThreadPoolExecutor(1)
    executor.scheduleAtFixedRate(
      classifyRunnable,
      0,
      interval,
      TimeUnit.MILLISECONDS)
    
  3. L'oggetto classifyRunnable nel codice precedente esegue il metodo AudioClassificationHelper.classifyAudio() , che carica gli ultimi dati audio disponibili dal registratore ed esegue una previsione:

    private fun classifyAudio() {
      tensorAudio.load(recorder)
      val output = classifier.classify(tensorAudio)
      ...
    }
    

Interrompere l'elaborazione della previsione

Assicurati che il codice dell'app interrompa la classificazione audio quando il frammento o l'attività di elaborazione audio dell'app perde il focus. L'esecuzione continua di un modello di machine learning ha un impatto significativo sulla durata della batteria di un dispositivo Android. Utilizza il metodo onPause() dell'attività Android o del frammento associato alla classificazione audio per interrompere la registrazione audio e l'elaborazione della previsione.

Per interrompere la registrazione e la classificazione dell'audio:

  • Utilizza il metodo AudioClassificationHelper.stopAudioClassification() per interrompere la registrazione e l'esecuzione del modello, come mostrato di seguito nella classe AudioFragment :

    override fun onPause() {
      super.onPause()
      if (::audioHelper.isInitialized ) {
        audioHelper.stopAudioClassification()
      }
    }
    

Gestire l'output del modello

Nella tua app Android, dopo aver elaborato una clip audio, il modello produce un elenco di previsioni che il codice della tua app deve gestire eseguendo una logica aziendale aggiuntiva, visualizzando i risultati all'utente o eseguendo altre azioni. L'output di qualsiasi modello TensorFlow Lite varia in termini di numero di previsioni prodotte (una o più) e di informazioni descrittive per ciascuna previsione. Nel caso dei modelli dell'app di esempio, le previsioni sono un elenco di suoni o parole riconosciuti. L'oggetto opzioni AudioClassifier utilizzato nell'esempio di codice consente di impostare il numero massimo di previsioni con il metodo setMaxResults() , come illustrato nella sezione Inizializzare il modello ML .

Per ottenere i risultati della previsione dal modello:

  1. Ottieni i risultati del metodo classify() dell'oggetto AudioClassifier e passali all'oggetto listener (riferimento al codice):

    private fun classifyAudio() {
      ...
      val output = classifier.classify(tensorAudio)
      listener.onResult(output[0].categories, inferenceTime)
    }
    
  2. Utilizza la funzione onResult() dell'ascoltatore per gestire l'output eseguendo la logica aziendale o visualizzando i risultati all'utente:

    private val audioClassificationListener = object : AudioClassificationListener {
      override fun onResult(results: List<Category>, inferenceTime: Long) {
        requireActivity().runOnUiThread {
          adapter.categoryList = results
          adapter.notifyDataSetChanged()
          fragmentAudioBinding.bottomSheetLayout.inferenceTimeVal.text =
            String.format("%d ms", inferenceTime)
        }
      }
    

Il modello utilizzato in questo esempio genera un elenco di previsioni con un'etichetta per il suono o la parola classificata e un punteggio di previsione compreso tra 0 e 1 come Float che rappresenta la confidenza della previsione, dove 1 rappresenta il punteggio di confidenza più alto. In generale, i pronostici con un punteggio inferiore al 50% (0,5) sono considerati inconcludenti. Tuttavia, il modo in cui gestisci i risultati della previsione di basso valore dipende da te e dalle esigenze della tua applicazione.

Una volta che il modello ha restituito una serie di risultati di previsione, l'applicazione può agire su tali previsioni presentando il risultato all'utente o eseguendo logica aggiuntiva. Nel caso del codice di esempio, l'applicazione elenca i suoni o le parole identificati nell'interfaccia utente dell'app.

Prossimi passi

Puoi trovare ulteriori modelli TensorFlow Lite per l'elaborazione audio su TensorFlow Hub e nella pagina della guida ai modelli pre-addestrati . Per ulteriori informazioni sull'implementazione del machine learning nella tua applicazione mobile con TensorFlow Lite, consulta la Guida per sviluppatori di TensorFlow Lite .