Leitfaden zur Audioklassifizierung für Android

Mit der Aufgabe „MediaPipe-Audioklassifikator“ können Sie Audiodaten klassifizieren. Mit dieser Aufgabe können Sie Geräuschereignisse aus einer Reihe von trainierten Kategorien identifizieren. In dieser Anleitung erfahren Sie, wie Sie den Audioklassifikator in Android-Apps verwenden.

Weitere Informationen zu den Funktionen, Modellen und Konfigurationsoptionen dieser Aufgabe finden Sie in der Übersicht.

Codebeispiel

Der Beispielcode von MediaPipe Tasks ist eine einfache Implementierung einer Audioklassifikator-App für Android. In diesem Beispiel wird das Mikrofon eines physischen Android-Geräts verwendet, um Geräusche kontinuierlich zu klassifizieren. Es kann auch der Klassifikator auf Sounddateien angewendet werden, die auf dem Gerät gespeichert sind.

Du kannst die App als Ausgangspunkt für deine eigene Android-App verwenden oder beim Ändern einer vorhandenen App darauf zurückgreifen. Der Beispielcode für den Audioklassifikator wird auf GitHub gehostet.

Code herunterladen

In der folgenden Anleitung erfahren Sie, wie Sie mit dem git-Befehlszeilentool eine lokale Kopie des Beispielcodes erstellen.

So laden Sie den Beispielcode herunter:

  1. Klonen Sie das Git-Repository mit dem folgenden Befehl:
    git clone https://github.com/google-ai-edge/mediapipe-samples
    
  2. Konfigurieren Sie optional die Git-Instanz für die Verwendung von Sparse Checkout, sodass Sie nur die Dateien für die Beispiel-App „Audioklassifikator“ haben:
    cd mediapipe
    git sparse-checkout init --cone
    git sparse-checkout set examples/audio_classifier/android
    

Nachdem Sie eine lokale Version des Beispielcodes erstellt haben, können Sie das Projekt in Android Studio importieren und die App ausführen. Eine Anleitung dazu finden Sie im Einrichtungsleitfaden für Android.

Schlüsselkomponenten

Die folgenden Dateien enthalten den wichtigen Code für diese Beispielanwendung für die Audioklassifizierung:

  • AudioClassifierHelper.kt: Initialisiert den Audioklassifikator und verarbeitet die Modell- und Delegierungsauswahl.
  • RecorderFragment.kt: Erstellt die Benutzeroberfläche und den Steuercode für die Live-Audioaufnahme.
  • LibraryFragment.kt: Erstellt die Benutzeroberfläche und den Steuerungscode für die Auswahl von Audiodateien.
  • ProbabilitiesAdapter.kt: verarbeitet und formatiert die Vorhersageergebnisse des Klassifikators.

Einrichtung

In diesem Abschnitt werden die wichtigsten Schritte zum Einrichten der Entwicklungsumgebung und Programmierprojekte speziell für die Verwendung des Audioklassifikators beschrieben. Allgemeine Informationen zum Einrichten der Entwicklungsumgebung für die Verwendung von MediaPipe-Aufgaben, einschließlich der Anforderungen an die Plattformversion, finden Sie im Einrichtungsleitfaden für Android.

Abhängigkeiten

Der Audioklassifikator verwendet die com.google.mediapipe:tasks-audio-Mediathek. Fügen Sie diese Abhängigkeit der Datei build.gradle Ihres Android-App-Entwicklungsprojekts hinzu. Importieren Sie die erforderlichen Abhängigkeiten mit dem folgenden Code:

dependencies {
    ...
    implementation 'com.google.mediapipe:tasks-audio:latest.release'
}

Modell

Die MediaPipe-Audioklassifikatoraufgabe erfordert ein trainiertes Modell, das mit dieser Aufgabe kompatibel ist. Weitere Informationen zu verfügbaren trainierten Modellen für den Audioklassifikator finden Sie in der Aufgabenübersicht im Abschnitt „Modelle“.

Wählen Sie das Modell aus, laden Sie es herunter und speichern Sie es dann in Ihrem Projektverzeichnis:

<dev-project-root>/src/main/assets

Verwenden Sie die Methode BaseOptions.Builder.setModelAssetPath(), um den vom Modell verwendeten Pfad anzugeben. Auf diese Methode wird im Codebeispiel im nächsten Abschnitt verwiesen.

Im Beispielcode für den Audioklassifikator wird das Modell in der Datei AudioClassifierHelper.kt definiert.

Aufgabe erstellen

Sie können die createFromOptions-Funktion verwenden, um die Aufgabe zu erstellen. Die Funktion createFromOptions akzeptiert Konfigurationsoptionen wie den Ausführungsmodus, die Sprache für Anzeigenamen, die maximale Anzahl von Ergebnissen, den Konfidenzgrenzwert und eine Liste der zulässigen oder abgelehnten Kategorien. Weitere Informationen zu Konfigurationsoptionen finden Sie unter Konfigurationsübersicht.

Die Aufgabe „Audioklassifikator“ unterstützt die folgenden Eingabedatentypen: Audioclips und Audiostreams. Beim Erstellen einer Aufgabe müssen Sie den Ausführungsmodus angeben, der Ihrem Eingabedatentyp entspricht. Wählen Sie den Tab für Ihren Eingabedatentyp aus, um zu sehen, wie Sie die Aufgabe erstellen und die Inferenz ausführen.

Audioclips

AudioClassifierOptions options =
    AudioClassifierOptions.builder()
        .setBaseOptions(
            BaseOptions.builder().setModelAssetPath("model.tflite").build())
        .setRunningMode(RunningMode.AUDIO_CLIPS)
        .setMaxResults(5)
        .build();
audioClassifier = AudioClassifier.createFromOptions(context, options);
    

Audiostream

AudioClassifierOptions options =
    AudioClassifierOptions.builder()
        .setBaseOptions(
            BaseOptions.builder().setModelAssetPath("model.tflite").build())
        .setRunningMode(RunningMode.AUDIO_STREAM)
        .setMaxResults(5)
        .setResultListener(audioClassifierResult -> {
             // Process the classification result here.
        })
        .build();
audioClassifier = AudioClassifier.createFromOptions(context, options);
    

Mit der Beispielcodeimplementierung für den Audioklassifikator können Nutzer zwischen den Verarbeitungsmodi wechseln. Dadurch wird der Code zur Aufgabenerstellung komplizierter und ist für Ihren Anwendungsfall möglicherweise nicht geeignet. Sie finden den Code für den Moduswechsel in der initClassifier()-Funktion des AudioClassifierHelper.

Konfigurationsoptionen

Diese Aufgabe umfasst die folgenden Konfigurationsoptionen für Android-Apps:

Option Beschreibung Wertebereich Standardwert
runningMode Legt den Ausführungsmodus für die Task fest. Der Audioklassifikator hat zwei Modi:

AUDIO_CLIPS: Der Modus zum Ausführen der Audioaufgabe für unabhängige Audioclips.

AUDIO_STREAM: Der Modus zum Ausführen der Audioaufgabe in einem Audiostream, z. B. über ein Mikrofon. In diesem Modus muss resultListener aufgerufen werden, um einen Listener einzurichten, der die Klassifizierungsergebnisse asynchron empfängt.
{AUDIO_CLIPS, AUDIO_STREAM} AUDIO_CLIPS
displayNamesLocale Legt die Sprache von Labels fest, die für Anzeigenamen bereitgestellt werden, die in den Metadaten des Aufgabenmodells angegeben sind, sofern verfügbar. Der Standardwert für Englisch ist en. Mit der TensorFlow Lite Metadata Writer API können Sie den Metadaten eines benutzerdefinierten Modells lokalisierte Labels hinzufügen. Sprachcode en
maxResults Legt die optionale maximale Anzahl der Klassifizierungsergebnisse mit den besten Bewertungen fest, die zurückgegeben werden sollen. Wenn < 0, werden alle verfügbaren Ergebnisse zurückgegeben. Beliebige positive Zahlen -1
scoreThreshold Legt den Schwellenwert für den Vorhersagewert fest, der den in den Modellmetadaten angegebenen Grenzwert überschreibt (falls vorhanden). Ergebnisse unter diesem Wert werden abgelehnt. [0,0;1,0] Nicht festgelegt
categoryAllowlist Legt die optionale Liste der zulässigen Kategorienamen fest. Wenn das Feld nicht leer ist, werden Klassifizierungsergebnisse herausgefiltert, deren Kategoriename nicht in diesem Set enthalten ist. Doppelte oder unbekannte Kategorienamen werden ignoriert. Diese Option und categoryDenylist schließen sich gegenseitig aus und die Verwendung beider Werte führt zu einem Fehler. Beliebige Strings Nicht festgelegt
categoryDenylist Legt die optionale Liste der nicht zulässigen Kategorienamen fest. Wenn das Feld nicht leer ist, werden Klassifizierungsergebnisse herausgefiltert, deren Kategoriename in diesem Satz enthalten ist. Doppelte oder unbekannte Kategorienamen werden ignoriert. Diese Option und categoryAllowlist schließen sich gegenseitig aus und die Verwendung beider Optionen führt zu einem Fehler. Beliebige Strings Nicht festgelegt
resultListener Legt den Ergebnis-Listener so fest, dass er die Klassifizierungsergebnisse asynchron empfängt, wenn sich der Audioklassifikator im Audiostreammodus befindet. Kann nur verwendet werden, wenn der Laufmodus auf AUDIO_STREAM festgelegt ist Nicht festgelegt
errorListener Legt einen optionalen Fehler-Listener fest. Nicht festgelegt

Daten vorbereiten

Der Audioklassifikator funktioniert mit Audioclips und Audiostreams. Die Aufgabe übernimmt die Vorverarbeitung der Dateneingabe, einschließlich Resampling, Zwischenspeichern und Framing. Allerdings müssen Sie die Eingabeaudiodaten in ein com.google.mediapipe.tasks.components.containers.AudioData-Objekt konvertieren, bevor Sie sie an die Audioklassifikatoraufgabe übergeben.

Audioclips

import com.google.mediapipe.tasks.components.containers.AudioData;

// Load an audio on the user’s device as a float array.

// Convert a float array to a MediaPipe’s AudioData object.
AudioData audioData =
    AudioData.create(
        AudioData.AudioDataFormat.builder()
            .setNumOfChannels(numOfChannels)
            .setSampleRate(sampleRate)
            .build(),
        floatData.length);
audioData.load(floatData);
    

Audiostream

import android.media.AudioRecord;
import com.google.mediapipe.tasks.components.containers.AudioData;

AudioRecord audioRecord =
    audioClassifier.createAudioRecord(/* numChannels= */ 1, /* sampleRate= */ 16000);
audioRecord.startRecording();

...

// To get a one second clip from the AudioRecord object:
AudioData audioData =
    AudioData.create(
        16000 /*sample counts per second*/);
        AudioData.AudioDataFormat.create(audioRecord.getFormat()),
audioData.load(audioRecord)
    

Task ausführen

Sie können die classify-Funktion für Ihren Laufmodus aufrufen, um Inferenzen auszulösen. Die Audio Classifier API gibt die möglichen Kategorien für die Audioereignisse zurück, die in den Eingabeaudiodaten erkannt wurden.

Audioclips

AudioClassifierResult classifierResult = audioClassifier.classify(audioData);
    

Audiostream

// Run inference on the audio block. The classifications results will be available
// via the `resultListener` provided in the `AudioClassifierOptions` when
// the audio classifier was created.
audioClassifier.classifyAsync(audioBlock, timestampMs);
    

Wichtige Hinweise:

  • Bei Ausführung im Audiostreammodus müssen Sie der Audioklassifikatoraufgabe auch einen Zeitstempel zur Verfügung stellen, damit erfasst wird, welche Audiodaten innerhalb des Streams für die Inferenz verwendet wurden.
  • Bei Ausführung im Audioclipmodell blockiert die Aufgabe „Audioklassifikator“ den aktuellen Thread, bis die Verarbeitung der Audioeingabe abgeschlossen ist. Damit Antworten auf der Benutzeroberfläche nicht blockiert werden, führen Sie die Verarbeitung in einem Hintergrundthread aus.

Ein Beispiel für die Ausführung des Audioklassifikators mit Audioclips finden Sie in der Klasse AudioClassifierHelper im Codebeispiel.

Ergebnisse verarbeiten und anzeigen

Nach dem Ausführen einer Inferenz gibt die Aufgabe „Audioklassifikator“ eine Liste möglicher Kategorien für die Audioereignisse in den Audioeingaben zurück. Die folgende Liste zeigt ein Beispiel für die Ausgabedaten dieser Aufgabe:

AudioClassifierResult:
  Timestamp in microseconds: 100
  ClassificationResult #0:
    Timestamp in microseconds: 100  
    Classifications #0 (single classification head):
      head index: 0
      category #0:
        category name: "Speech"
        score: 0.6
        index: 0
      category #1:
        category name: "Music"
        score: 0.2
        index: 1

In einer Android-App gibt die Aufgabe ein ClassificationResult zurück, das eine Liste von AudioClassifierResult-Objekten enthält, die Vorhersagen für ein Audioereignis darstellen, einschließlich des Kategorielabels und des Konfidenzwerts.

Audioclips

// In the audio clips mode, the classification results are for the entire audio
// clip. The results are timestamped AudioClassifierResult objects, each
// classifying an interval of the entire audio clip that starts at
// ClassificationResult.timestampMs().get().

for (ClassificationResult result : audioClassifierResult.classificationResults()) {
  // Audio interval start timestamp:
  result.timestampMs().get();
  // Classification result of the audio interval.
  result.classifications();
}
    

Audiostream

// In the audio stream mode, the classification results list only contains one
// element, representing the classification result of the audio block that
// starts at ClassificationResult.timestampMs in the audio stream.

ClassificationResult result = audioClassifierResult.classificationResults().get(0);
// The audio block start timestamp
audioClassifierResult.timestampMs();
// Alternatively, the same timestamp can be retrieved from
// result.timestampMs().get();

// Classification result.
result.classifications();
    

In der Klasse ProbabilitiesAdapter des Codebeispiels finden Sie ein Beispiel dafür, wie die von dieser Aufgabe zurückgegebenen Klassifizierungsergebnisse angezeigt werden.