Erkennen von Absichten anhand gesprochener Sprache mit dem Speech SDK für C#

Das Speech SDK von Azure KI Services ist in den Language Understanding Service (LUIS) integriert, um Absichtserkennung zu ermöglichen. Eine Absicht ist eine Aufgabe, die der Benutzer ausführen möchte: einen Flug buchen, sich über das Wetter informieren oder einen Anruf tätigen. Der Benutzer kann beliebige Begriffe verwenden, die sich für ihn natürlich anfühlen. LUIS ordnet Benutzeranforderungen den von Ihnen definierten Absichten zu.

Hinweis

Eine LUIS-Anwendung definiert die Absichten und Entitäten, die Sie erkennen möchten. Sie unterscheidet sich von der C#-Anwendung, die den Speech Service verwendet. In diesem Artikel bedeutet „App“ die LUIS-App, während „Anwendung“ den C#-Code bedeutet.

In diesem Leitfaden verwenden Sie das Speech SDK, um eine C#-Konsolenanwendung zu entwickeln, die Absichten aus Benutzeräußerungen über das Mikrofon Ihres Geräts ableitet. Folgendes wird vermittelt:

  • Erstellen eines Visual Studio-Projekts, das auf das Speech SDK NuGet-Paket verweist
  • Erstellen einer Sprachkonfiguration und Abrufen einer Absichtserkennung
  • Abrufen des Modells für Ihre LUIS-App und Hinzufügen der benötigten Absicht
  • Angeben der Sprache für die Spracherkennung
  • Erkennen von Sprache aus einer Datei
  • Verwenden von asynchroner, ereignisgesteuerter kontinuierlicher Erkennung

Voraussetzungen

Vergewissern Sie sich, dass folgende Elemente vorhanden sind, bevor Sie mit diesem Leitfaden beginnen:

LUIS und Spracherkennung

LUIS ist in Speech Service integriert, um Absichten aus Sprache zu erkennen. Ein Speech Service-Abonnement ist nicht erforderlich, nur LUIS.

LUIS verwendet zwei Arten von Schlüsseln:

Schlüsseltyp Zweck
Erstellen Ermöglicht Ihnen das programmgesteuerte Erstellen und Ändern von LUIS-Apps.
Vorhersage Wird für den Zugriff auf die LUIS-Anwendung zur Laufzeit verwendet.

Für diesen Leitfaden benötigen Sie den Typ des Vorhersageschlüssels. Dieser Leitfaden verwendet die LUIS-Beispiel-App für die Gebäudeautomatisierung, die Sie erstellen können, indem Sie die Anleitung im Schnellstart Verwenden der vordefinierten Home Automation-App befolgen. Wenn Sie selbst eine LUIS-App erstellt haben, können Sie diese stattdessen verwenden.

Wenn Sie eine LUIS-App erstellen, wird automatisch ein Erstellungsschlüssel generiert, mit dem Sie die App mithilfe von Textabfragen testen können. Mit diesem Schlüssel ist keine Integration des Speech-Diensts möglich und er funktioniert nicht für diesen Leitfaden. Erstellen Sie eine LUIS-Ressource im Azure-Dashboard, und weisen Sie sie der LUIS-App zu. Sie können den Tarif für ein kostenloses Abonnement für diesen Leitfaden verwenden.

Nachdem Sie die LUIS-Ressource im Azure-Dashboard erstellt haben, melden Sie sich beim LUIS-Portal an, wählen Sie Ihre Anwendung auf der Seite Eigene Anwendungen aus, und wechseln Sie dann zur Seite Verwalten der App. Wählen Sie abschließend auf der Seitenleiste Azure-Ressourcen aus.

Shows a screenshot of the LUIS portal keys and endpoint settings.

Auf der Seite Azure-Ressourcen:

Wählen Sie das Symbol neben einem Schlüssel aus, um diesen in die Zwischenablage zu kopieren. (Sie können beide Schlüssel verwenden.)

Erstellen des Projekts und Hinzufügen der Workload

Zum Erstellen eines Visual Studio-Projekts für die Windows-Entwicklung müssen Sie das Projekt erstellen, Visual Studio für die .NET-Desktopentwicklung einrichten, das Speech SDK installieren und die Zielarchitektur auswählen.

Erstellen Sie zunächst das Projekt in Visual Studio, und vergewissern Sie sich, dass Visual Studio für die .NET-Desktopentwicklung eingerichtet ist:

  1. Öffnen Sie Visual Studio 2019.

  2. Wählen Sie im Fenster Start die Option Neues Projekt erstellen aus.

  3. Wählen Sie im Fenster Neues Projekt erstellen die Option Konsolen-App (.NET Framework) und dann Weiter aus.

  4. Geben Sie im Fenster Neues Projekt konfigurieren unter Projektname den Namen helloworld ein, und wählen Sie unter Speicherort den Verzeichnispfad aus, oder erstellen Sie ihn. Wählen Sie anschließend Erstellen aus.

  5. Wählen Sie auf der Visual Studio-Menüleiste Extras>Tools und Features abrufen aus, um den Visual Studio-Installer zu öffnen und das Dialogfeld Änderung anzuzeigen.

  6. Überprüfen Sie, ob die Workload .NET-Desktopentwicklung verfügbar ist. Wurde die Workload noch nicht installiert, aktivieren Sie das Kontrollkästchen daneben, und wählen Sie dann Ändern aus, um die Installation zu starten. Das Herunterladen und Installieren kann einige Minuten dauern.

    Ist das Kontrollkästchen neben .NET-Desktopentwicklung bereits aktiviert, wählen Sie Schließen aus, um das Dialogfeld zu schließen.

    Enable .NET desktop development

  7. Schließen Sie den Visual Studio-Installer.

Installieren des Speech SDK

Der nächste Schritt ist die Installation des Speech-SDK-NuGet-Pakets, damit Sie im Code darauf verweisen können.

  1. Klicken Sie im Projektmappen-Explorer mit der rechten Maustaste auf das Projekt helloworld, und wählen Sie dann NuGet-Pakete verwalten aus, um den NuGet-Paket-Manager anzuzeigen.

    NuGet Package Manager

  2. Navigieren Sie oben rechts zum Dropdownfeld Paketquelle, und stellen Sie sicher, dass nuget.org ausgewählt ist.

  3. Wählen Sie in der oberen linken Ecke Durchsuchen aus.

  4. Geben Sie ins Suchfeld Microsoft.CognitiveServices.Speech ein, und drücken Sie die EINGABETASTE.

  5. Wählen Sie in den Suchergebnissen das Paket Microsoft.CognitiveServices.Speech und anschließend Installieren aus, um die aktuelle stabile Version zu installieren.

    Install Microsoft.CognitiveServices.Speech NuGet package

  6. Akzeptieren Sie alle Vereinbarungen und Lizenzen, um die Installation zu starten.

    Nachdem das Paket installiert wurde, wird eine Bestätigung im Fenster Paket-Manager-Konsole angezeigt.

Auswählen der Zielarchitektur

Erstellen Sie jetzt eine Plattformkonfiguration, die der Architektur Ihres Computers entspricht, um die Konsolenanwendung zu erstellen und auszuführen.

  1. Wählen Sie auf der Menüleiste Build>Konfigurations-Manager aus. Das Dialogfeld Konfigurations-Manager wird angezeigt.

    Configuration Manager dialog box

  2. Wählen Sie im Dropdownfeld Aktive Projektmappenplattform den Eintrag Neu aus. Das Dialogfeld Neue Projektmappenplattform wird angezeigt.

  3. Gehen Sie im Feld Neue Plattform eingeben oder auswählen wie folgt vor:

    • Wenn Sie 64-Bit-Windows ausführen, wählen Sie x64 aus.
    • Wenn Sie 32-Bit-Windows ausführen, wählen Sie x86 aus.
  4. Wählen Sie OK und dann Schließen aus.

Hinzufügen des Codes

Als Nächstes fügen Sie dem Projekt Code hinzu.

  1. Öffnen Sie im Projektmappen-Explorer die Datei Program.cs.

  2. Ersetzen Sie den Block mit using-Anweisungen am Anfang der Datei durch die folgenden Deklarationen:

    using System;
    using System.Threading.Tasks;
    using Microsoft.CognitiveServices.Speech;
    using Microsoft.CognitiveServices.Speech.Audio;
    using Microsoft.CognitiveServices.Speech.Intent;
    
  3. Ersetzen Sie die angegebene Methode Main() durch die folgende asynchrone Entsprechung:

    public static async Task Main()
    {
        await RecognizeIntentAsync();
        Console.WriteLine("Please press Enter to continue.");
        Console.ReadLine();
    }
    
  4. Erstellen Sie eine leere asynchrone RecognizeIntentAsync()-Methode, wie nachfolgend gezeigt:

    static async Task RecognizeIntentAsync()
    {
    }
    
  5. Fügen Sie im Textkörper dieser neuen Methode den folgenden Code hinzu:

    // Creates an instance of a speech config with specified subscription key
    // and service region. Note that in contrast to other services supported by
    // the Cognitive Services Speech SDK, the Language Understanding service
    // requires a specific subscription key from https://www.luis.ai/.
    // The Language Understanding service calls the required key 'endpoint key'.
    // Once you've obtained it, replace with below with your own Language Understanding subscription key
    // and service region (e.g., "westus").
    // The default language is "en-us".
    var config = SpeechConfig.FromSubscription("YourLanguageUnderstandingSubscriptionKey", "YourLanguageUnderstandingServiceRegion");
    
    // Creates an intent recognizer using microphone as audio input.
    using (var recognizer = new IntentRecognizer(config))
    {
        // Creates a Language Understanding model using the app id, and adds specific intents from your model
        var model = LanguageUnderstandingModel.FromAppId("YourLanguageUnderstandingAppId");
        recognizer.AddIntent(model, "YourLanguageUnderstandingIntentName1", "id1");
        recognizer.AddIntent(model, "YourLanguageUnderstandingIntentName2", "id2");
        recognizer.AddIntent(model, "YourLanguageUnderstandingIntentName3", "any-IntentId-here");
    
        // Starts recognizing.
        Console.WriteLine("Say something...");
    
        // Starts intent recognition, and returns after a single utterance is recognized. The end of a
        // single utterance is determined by listening for silence at the end or until a maximum of 15
        // seconds of audio is processed.  The task returns the recognition text as result. 
        // Note: Since RecognizeOnceAsync() returns only a single utterance, it is suitable only for single
        // shot recognition like command or query. 
        // For long-running multi-utterance recognition, use StartContinuousRecognitionAsync() instead.
        var result = await recognizer.RecognizeOnceAsync().ConfigureAwait(false);
    
        // Checks result.
        if (result.Reason == ResultReason.RecognizedIntent)
        {
            Console.WriteLine($"RECOGNIZED: Text={result.Text}");
            Console.WriteLine($"    Intent Id: {result.IntentId}.");
            Console.WriteLine($"    Language Understanding JSON: {result.Properties.GetProperty(PropertyId.LanguageUnderstandingServiceResponse_JsonResult)}.");
        }
        else if (result.Reason == ResultReason.RecognizedSpeech)
        {
            Console.WriteLine($"RECOGNIZED: Text={result.Text}");
            Console.WriteLine($"    Intent not recognized.");
        }
        else if (result.Reason == ResultReason.NoMatch)
        {
            Console.WriteLine($"NOMATCH: Speech could not be recognized.");
        }
        else if (result.Reason == ResultReason.Canceled)
        {
            var cancellation = CancellationDetails.FromResult(result);
            Console.WriteLine($"CANCELED: Reason={cancellation.Reason}");
    
            if (cancellation.Reason == CancellationReason.Error)
            {
                Console.WriteLine($"CANCELED: ErrorCode={cancellation.ErrorCode}");
                Console.WriteLine($"CANCELED: ErrorDetails={cancellation.ErrorDetails}");
                Console.WriteLine($"CANCELED: Did you update the subscription info?");
            }
        }
    }
    
  6. Ersetzen Sie die Platzhalter in dieser Methode wie folgt durch Ihren LUIS-Ressourcenschlüssel, die Region und die App-ID.

    Platzhalter Ersetzen durch
    YourLanguageUnderstandingSubscriptionKey Ihr LUIS-Ressourcenschlüssel. Auch hier müssen Sie dieses Element aus Ihrem Azure-Dashboard abrufen. Sie finden es auf der Seite Azure-Ressourcen Ihrer App (unter Verwalten) im LUIS-Portal.
    YourLanguageUnderstandingServiceRegion Der kurze Bezeichner für die Region Ihrer LUIS-Ressource, z. B. westus für „USA, Westen“. Siehe Regionen.
    YourLanguageUnderstandingAppId die LUIS-App-ID Sie finden sie auf der Seite Einstellungen Ihrer App im LUIS-Portal.

Nachdem Sie diese Änderungen vorgenommen haben, können Sie die Anwendung erstellen (STRG+UMSCHALT+B) und ausführen (F5). Wenn Sie dazu aufgefordert werden, sprechen Sie „Turn off the lights“ (Licht ausschalten) in das Mikrofon Ihres PCs. Die Anwendung zeigt das Ergebnis im Konsolenfenster an.

Die folgenden Abschnitte enthalten eine Erläuterung des Codes.

Erstellen einer Absichtserkennung

Zunächst müssen Sie eine Sprachkonfiguration aus dem LUIS-Vorhersageschlüssel und der Region erstellen. Sprachkonfigurationen können verwendet werden, um Erkennungen für die verschiedenen Funktionen des Speech SDK zu erstellen. Die Sprachkonfiguration bietet mehrere Möglichkeiten, um die Ressource anzugeben, die Sie verwenden möchten. Hier verwenden wir FromSubscription. Diese Angabe übernimmt den Ressourcenschlüssel und die Region.

Hinweis

Verwenden Sie Schlüssel und Region Ihrer LUIS-Ressource, keine Speech-Ressource.

Als nächstes erstellen Sie eine Absichtserkennung mit new IntentRecognizer(config). Da die Konfiguration bereits weiß, welche Ressource verwendet werden soll, entfällt die erneute Angabe des Schlüssels beim Erstellen der Erkennung.

Importieren eines LUIS-Modells und Hinzufügen von Absichten

Importieren Sie nun das Modell aus der LUIS-App mit LanguageUnderstandingModel.FromAppId(), und fügen Sie die LUIS-Absichten hinzu, die Sie über die AddIntent()-Methode der Erkennung erkennen möchten. Diese beiden Schritte verbessern die Genauigkeit der Spracherkennung, indem sie Wörter angeben, die der Benutzer wahrscheinlich in seinen Anforderungen verwenden wird. Sie müssen nicht alle Absichten der App hinzufügen, wenn Sie sie nicht alle in Ihrer Anwendung erkennen müssen.

Für das Hinzufügen von Absichten sind drei Argumente erforderlich: das zuvor erstellte LUIS-Modell (mit dem Namen model), der Absichtsname und eine Absichts-ID. Der Unterschied zwischen der ID und dem Namen ist wie folgt.

AddIntent()-Argument Zweck
intentName Der Name der Absicht, wie in der LUIS-App definiert. Dieser Wert muss genau mit dem Namen der LUIS-Absicht übereinstimmen.
intentID Eine ID, die vom Speech SDK einer erkannten Absicht zugewiesen wird. Dieser Wert kann beliebig sein und muss nicht dem Absichtsnamen entsprechen, der in der LUIS-App definiert ist. Wenn beispielsweise mehrere Absichten von demselben Code verarbeitet werden, können Sie für sie die gleiche ID verwenden.

Die LUIS-App für die Gebäudeautomatisierung verwendet zwei Absichten: eine zum Einschalten eines Geräts und eine zum Ausschalten eines Geräts. Die folgenden Zeilen fügen diese Absichten der Erkennung hinzu. Ersetzen Sie die drei AddIntent-Zeilen in der RecognizeIntentAsync()-Methode durch diesen Code.

recognizer.AddIntent(model, "HomeAutomation.TurnOff", "off");
recognizer.AddIntent(model, "HomeAutomation.TurnOn", "on");

Anstatt einzelne Absichten hinzuzufügen, können Sie auch die Methode AddAllIntents verwenden, um der Erkennung alle Absichten in einem Modell hinzuzufügen.

Starten der Erkennung

Sobald die Erkennung erstellt und die Absichten hinzugefügt wurden, kann die Erkennung beginnen. Das Speech SDK unterstützt sowohl einstufige als auch fortlaufende Erkennung.

Erkennungsmodus Aufzurufende Methoden Ergebnis
Einstufig RecognizeOnceAsync() Gibt die erkannte Absicht (falls vorhanden) nach einer Äußerung zurück.
Fortlaufend StartContinuousRecognitionAsync()
StopContinuousRecognitionAsync()
Erkennt mehrere Äußerungen; gibt Ereignisse (z. B. IntermediateResultReceived) aus, wenn Ergebnisse verfügbar sind.

Die Anwendung verwendet den einstufigen Modus und ruft daher RecognizeOnceAsync() auf, um die Erkennung zu beginnen. Das Ergebnis ist ein IntentRecognitionResult-Objekt, das Informationen über die erkannte Absicht enthält. Die LUIS JSON-Antwort wird durch den folgenden Ausdruck extrahiert:

result.Properties.GetProperty(PropertyId.LanguageUnderstandingServiceResponse_JsonResult)

Die Anwendung analysiert das JSON-Ergebnis nicht. Sie zeigt lediglich den JSON-Text im Konsolenfenster an.

Single LUIS recognition results

Angeben der Erkennungssprache

Standardmäßig erkennt LUIS Absichten in amerikanischem Englisch (en-us). Durch das Zuweisen eines Gebietsschemacodes zur SpeechRecognitionLanguage-Eigenschaft der Sprachkonfiguration können Sie Absichten in anderen Sprachen erkennen. Fügen Sie z. B. config.SpeechRecognitionLanguage = "de-de"; in unserer Anwendung hinzu, bevor Sie die Erkennung erstellen, um Absichten in Deutsch zu erkennen. Weitere Informationen finden Sie unter LUIS-Sprachunterstützung.

Kontinuierliche Erkennung aus einer Datei

Der folgende Code zeigt zwei weitere Möglichkeiten der Absichtserkennung mit dem Speech SDK. Die erste (bereits erwähnte) Möglichkeit ist die kontinuierliche Erkennung, bei der die Erkennung Ereignisse ausgibt, wenn Ergebnisse verfügbar sind. Diese Ereignisse werden dann von Ereignishandlern verarbeitet, die Sie bereitstellen. Bei kontinuierlicher Erkennung rufen Sie anstelle von RecognizeOnceAsync() die Methode StartContinuousRecognitionAsync() der Erkennung auf, um die Erkennung zu starten.

Die andere Möglichkeit ist das Lesen der Audiodaten aus einer WAV-Datei, die die zu verarbeitende Spracheingabe enthalten. Bei der Implementierung wird eine Audiokonfiguration erstellt, die beim Erstellen der Absichtserkennung verwendet werden kann. Die Datei muss einen Kanal (Mono) mit einer Samplingrate von 16 kHz enthalten.

Damit Sie diese Funktionen testen können, löschen Sie den Text der RecognizeIntentAsync()-Methode, oder kommentieren Sie ihn aus, und fügen Sie den folgenden Code an der Stelle ein.

// Creates an instance of a speech config with specified subscription key
// and service region. Note that in contrast to other services supported by
// the Cognitive Services Speech SDK, the Language Understanding service
// requires a specific subscription key from https://www.luis.ai/.
// The Language Understanding service calls the required key 'endpoint key'.
// Once you've obtained it, replace with below with your own Language Understanding subscription key
// and service region (e.g., "westus").
var config = SpeechConfig.FromSubscription("YourLanguageUnderstandingSubscriptionKey", "YourLanguageUnderstandingServiceRegion");

// Creates an intent recognizer using file as audio input.
// Replace with your own audio file name.
using (var audioInput = AudioConfig.FromWavFileInput("YourAudioFile.wav"))
{
    using (var recognizer = new IntentRecognizer(config, audioInput))
    {
        // The TaskCompletionSource to stop recognition.
        var stopRecognition = new TaskCompletionSource<int>(TaskCreationOptions.RunContinuationsAsynchronously);

        // Creates a Language Understanding model using the app id, and adds specific intents from your model
        var model = LanguageUnderstandingModel.FromAppId("YourLanguageUnderstandingAppId");
        recognizer.AddIntent(model, "YourLanguageUnderstandingIntentName1", "id1");
        recognizer.AddIntent(model, "YourLanguageUnderstandingIntentName2", "id2");
        recognizer.AddIntent(model, "YourLanguageUnderstandingIntentName3", "any-IntentId-here");

        // Subscribes to events.
        recognizer.Recognizing += (s, e) =>
        {
            Console.WriteLine($"RECOGNIZING: Text={e.Result.Text}");
        };

        recognizer.Recognized += (s, e) =>
        {
            if (e.Result.Reason == ResultReason.RecognizedIntent)
            {
                Console.WriteLine($"RECOGNIZED: Text={e.Result.Text}");
                Console.WriteLine($"    Intent Id: {e.Result.IntentId}.");
                Console.WriteLine($"    Language Understanding JSON: {e.Result.Properties.GetProperty(PropertyId.LanguageUnderstandingServiceResponse_JsonResult)}.");
            }
            else if (e.Result.Reason == ResultReason.RecognizedSpeech)
            {
                Console.WriteLine($"RECOGNIZED: Text={e.Result.Text}");
                Console.WriteLine($"    Intent not recognized.");
            }
            else if (e.Result.Reason == ResultReason.NoMatch)
            {
                Console.WriteLine($"NOMATCH: Speech could not be recognized.");
            }
        };

        recognizer.Canceled += (s, e) =>
        {
            Console.WriteLine($"CANCELED: Reason={e.Reason}");

            if (e.Reason == CancellationReason.Error)
            {
                Console.WriteLine($"CANCELED: ErrorCode={e.ErrorCode}");
                Console.WriteLine($"CANCELED: ErrorDetails={e.ErrorDetails}");
                Console.WriteLine($"CANCELED: Did you update the subscription info?");
            }

            stopRecognition.TrySetResult(0);
        };

        recognizer.SessionStarted += (s, e) =>
        {
            Console.WriteLine("\n    Session started event.");
        };

        recognizer.SessionStopped += (s, e) =>
        {
            Console.WriteLine("\n    Session stopped event.");
            Console.WriteLine("\nStop recognition.");
            stopRecognition.TrySetResult(0);
        };


        // Starts continuous recognition. Uses StopContinuousRecognitionAsync() to stop recognition.
        await recognizer.StartContinuousRecognitionAsync().ConfigureAwait(false);

        // Waits for completion.
        // Use Task.WaitAny to keep the task rooted.
        Task.WaitAny(new[] { stopRecognition.Task });

        // Stops recognition.
        await recognizer.StopContinuousRecognitionAsync().ConfigureAwait(false);
    }
}

Überarbeiten Sie den Code, sodass er Ihren LUIS-Vorhersageschlüssel, Ihre Region und Ihre App-ID enthält, und fügen Sie die Absichten der Heimautomatisierung wie zuvor hinzu. Ändern Sie whatstheweatherlike.wav in den Namen Ihrer aufgezeichneten Audiodatei. Erstellen Sie anschließend die Audiodatei, kopieren Sie sie in das Buildverzeichnis, und führen Sie die Anwendung aus.

Wenn Sie beispielsweise in Ihrer aufgezeichneten Audiodatei „Licht ausschalten“ sagen, eine Pause machen, und dann „Licht einschalten“ sagen, erscheint möglicherweise folgende Konsolenausgabe:

Audio file LUIS recognition results

Das Speech SDK-Team verwaltet eine große Anzahl von Beispielen in einem Open-Source-Repository. Das Repository für Beispielquellcode finden Sie im Azure KI Speech SDK auf GitHub. Dort gibt es Beispiele für C#, C++, Java, Python, Objective-C, Swift, JavaScript, UWP, Unity und Xamarin. Den Code aus diesem Artikel finden Sie im Ordner samples/csharp/sharedcontent/console.

Nächste Schritte

Schnellstart: Erkennen von Spracheingaben per Mikrofon