Intenties van spraak herkennen met behulp van de Speech SDK voor C#

De Speech SDK van Azure AI-services kan worden geïntegreerd met de Language Understanding-service (LUIS) om intentieherkenning te bieden. Een intentie is iets dat de gebruiker wil doen: een vlucht reserveren, de weersverwachting controleren of iemand bellen. De gebruiker kan elke term gebruiken die natuurlijk aanvoelt. LUIS wijst gebruikersaanvragen toe aan de intenties die u hebt gedefinieerd.

Notitie

Een LUIS-toepassing definieert de intenties en entiteiten die u wilt herkennen. Deze toepassing staat los van de C#-toepassing die gebruikmaakt van de Speech-service. In dit artikel verwijst 'app' naar de LUIS-app en 'toepassing' naar de C#-code.

In deze handleiding gebruikt u de Speech SDK om een C#-consoletoepassing te ontwikkelen die intenties afleidt van gebruikersuitingen via de microfoon van uw apparaat. U leert het volgende:

  • Een Visual Studio-project maken dat verwijst naar het NuGet-pakket van de Speech SDK
  • Een spraakconfiguratie maken en een intentieherkenning ophalen
  • Het model voor uw LUIS-app ophalen en de benodigde intenties toevoegen
  • De taal voor spraakherkenning opgeven
  • Spraak herkennen uit een bestand
  • Asynchrone, gebeurtenisgestuurde continue herkenning gebruiken

Vereisten

Zorg ervoor dat u de volgende items hebt voordat u aan deze handleiding begint:

LUIS en spraakherkenning

LUIS kan worden geïntegreerd met de Speech-service voor het herkennen van intenties van spraak. U hebt geen abonnement op de Speech-service nodig, alleen op LUIS.

LUIS maakt gebruik van twee soorten sleutels:

Type sleutel Doel
Ontwerpen Hiermee kunt u via programmacode LUIS-apps maken en wijzigen
Voorspelling Wordt gebruikt voor toegang tot de LUIS-toepassing in runtime

Voor deze handleiding hebt u het type voorspellingssleutel nodig. In deze handleiding wordt gebruikgemaakt van de voorbeeld-LUIS-app voor Home Automation, die u kunt maken door de quickstart vooraf gedefinieerde home automation-app gebruiken te volgen. Als u zelf een LUIS-app hebt gemaakt, kunt u deze gebruiken.

Wanneer u een LUIS-app maakt, genereert LUIS automatisch een ontwerpsleutel, zodat u de app kunt testen met behulp van tekstquery's. Deze sleutel schakelt de integratie van de Speech-service niet in en werkt niet met deze handleiding. Maak een LUIS-resource in het Azure-dashboard en wijs deze toe aan de LUIS-app. U kunt de gratis abonnementslaag voor deze handleiding gebruiken.

Als u de LUIS-resource in het Azure-dashboard hebt gemaakt, meldt u zich aan bij de LUIS-portal, kiest u uw toepassing op de pagina My Apps en gaat u naar de pagina Manage van de app. Selecteer ten slotte Azure-resources in de zijbalk.

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

Op de pagina Azure-resources :

Selecteer het pictogram naast een sleutel om deze naar het klembord te kopiëren. (U kunt een van beide sleutels gebruiken.)

Het project maken en de workload toevoegen

Als u een Visual Studio-project voor Windows-ontwikkeling wilt maken, moet u het project maken, Visual Studio instellen voor .NET-desktopontwikkeling, de Speech SDK installeren en de doelarchitectuur kiezen.

Als u wilt beginnen, maakt u het project in Visual Studio en zorgt u ervoor dat Visual Studio is ingesteld voor .NET-desktopontwikkeling:

  1. Open Visual Studio 2019.

  2. Selecteer een nieuw project maken in het venster Start.

  3. Kies in het venster Een nieuw project makenConsole-app (.NET Framework) en selecteer vervolgens Volgende.

  4. Voer in het venster Uw nieuwe project configurerenhelloworld in bij Projectnaam, kies of maak het mappad bij Locatie en selecteer vervolgens Maken.

  5. Selecteer in de menubalk van Visual Studio Hulpprogramma's>Hulpprogramma's en functies ophalen. Hiermee opent u Visual Studio Installer en wordt het dialoogvenster Wijzigen weergegeven.

  6. Controleer of de workload .NET-desktopontwikkeling beschikbaar is. Als de werkbelasting niet is geïnstalleerd, schakelt u het selectievakje ernaast in en selecteert u Wijzigen om de installatie te starten. Het downloaden en installeren kan enkele minuten duren.

    Als het selectievakje naast .NET-desktopontwikkeling is ingeschakeld, selecteert u Sluiten om het dialoogvenster af te sluiten.

    Enable .NET desktop development

  7. Sluit Visual Studio Installer.

De Speech-SDK installeren

De volgende stap bestaat uit het installeren van het NuGet-pakket voor de Speech SDK, zodat u ernaar kunt verwijzen in de code.

  1. Klik in de Solution Explorer met de rechtermuisknop op het helloworld-project en selecteer vervolgens NuGet-pakketten beheren om NuGet-pakketbeheer weer te geven.

    NuGet Package Manager

  2. Zoek in de rechterbovenhoek de vervolgkeuzelijst Pakketbron en zorg ervoor dat nuget.org is geselecteerd.

  3. Selecteer Bladeren in de linkerbovenhoek.

  4. Typ Microsoft.CognitiveServices.Speech in het zoekvak en selecteer Invoeren.

  5. Bij de zoekresultaten selecteert u het Microsoft.CognitiveServices.Speech-pakket en selecteert u vervolgens Installeren om de meest recente stabiele versie te installeren.

    Install Microsoft.CognitiveServices.Speech NuGet package

  6. Accepteer alle overeenkomsten en licenties om de installatie te starten.

    Nadat het pakket is geïnstalleerd, wordt er een bevestiging weergegeven in het venster Package Manager-console.

De doelarchitectuur kiezen

Als u nu de consoletoepassing wilt bouwen en uitvoeren, maakt u een platformconfiguratie die overeenkomt met de architectuur van uw computer.

  1. Selecteer Bouwen>Configuration Manager in de menubalk. Het dialoogvenster Configuration Manager wordt weergegeven.

    Configuration Manager dialog box

  2. In de vervolgkeuzelijst Platform actieve oplossing selecteert u Nieuw. Het dialoogvenster Platform nieuwe oplossing wordt weergegeven.

  3. In de vervolgkeuzelijst Typ of selecteer het nieuwe platform:

    • Als u 64-bits Windows uitvoert, selecteert u x64.
    • Als u 32-bits Windows uitvoert, selecteert u x86.
  4. Selecteer OK en vervolgens Sluiten.

Code toevoegen

Vervolgens voegt u code toe aan het project.

  1. Open in Solution Explorer het bestand Program.cs.

  2. Vervang het blok using met instructies aan het begin van het bestand door de volgende declaraties:

    using System;
    using System.Threading.Tasks;
    using Microsoft.CognitiveServices.Speech;
    using Microsoft.CognitiveServices.Speech.Audio;
    using Microsoft.CognitiveServices.Speech.Intent;
    
  3. Vervang de opgegeven Main() methode door het volgende asynchrone equivalent:

    public static async Task Main()
    {
        await RecognizeIntentAsync();
        Console.WriteLine("Please press Enter to continue.");
        Console.ReadLine();
    }
    
  4. Maak een lege asynchrone methode RecognizeIntentAsync(), zoals hier wordt weergegeven:

    static async Task RecognizeIntentAsync()
    {
    }
    
  5. Voeg in de hoofdtekst van deze nieuwe methode deze code toe:

    // 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. Vervang de tijdelijke aanduidingen in deze methode als volgt door uw LUIS-resourcesleutel, -regio en -app-id.

    Plaatsaanduiding Replace with
    YourLanguageUnderstandingSubscriptionKey Uw LUIS-resourcesleutel. Nogmaals, u moet dit item ophalen uit uw Azure-dashboard. U vindt deze op de pagina Azure-resources van uw app (onder Beheren) in de LUIS-portal.
    YourLanguageUnderstandingServiceRegion De korte id voor de regio waarin uw LUIS-resource zich bevindt, zoals westus voor VS - west. Zie Regio's.
    YourLanguageUnderstandingAppId De id van de LUIS-app. U vindt deze op de Instellingen pagina van uw app in de LUIS-portal.

Met deze wijzigingen kunt u de toepassing bouwen (Control+Shift+B) en de toepassing uitvoeren (F5). Wanneer u hierom wordt gevraagd, zegt u 'De lichten uitschakelen' in de microfoon van uw pc. De toepassing geeft het resultaat weer in het consolevenster.

In de volgende secties wordt dieper ingegaan op de code.

Een mechanisme voor intentieherkenning maken

Eerst moet u een spraakconfiguratie maken op basis van uw LUIS-voorspellingssleutel en -regio. U kunt spraakconfiguraties gebruiken om recognizers te maken voor de verschillende mogelijkheden van de Speech SDK. De spraakconfiguratie heeft meerdere manieren om de resource op te geven die u wilt gebruiken; hier gebruiken FromSubscriptionwe, die de resourcesleutel en regio gebruikt.

Notitie

Gebruik de sleutel en regio van uw LUIS-resource, niet een Spraak-resource.

Maak vervolgens een mechanisme voor intentieherkenning met behulp van new IntentRecognizer(config). Omdat de configuratie al weet welke resource moet worden gebruikt, hoeft u de sleutel niet opnieuw op te geven bij het maken van de recognizer.

Een LUIS-model importeren en intenties toevoegen

Importeer het model nu uit de LUIS-app met LanguageUnderstandingModel.FromAppId() en voeg de intenties van LUIS toe die u wilt herkennen via de methode AddIntent() van het mechanisme. Deze twee stappen verbeteren de nauwkeurigheid van spraakherkenning door woorden aan te geven die de gebruiker waarschijnlijk zal gebruiken in aanvragen. U hoeft niet alle intenties van de app toe te voegen als u ze niet allemaal in uw toepassing hoeft te herkennen.

Als u intenties wilt toevoegen, moet u drie argumenten opgeven: het LUIS-model (benoemd model), de naam van de intentie en een intentie-id. Het verschil tussen de id en de naam is als volgt.

Argument voor AddIntent() Doel
intentName De naam van de intentie zoals gedefinieerd in de LUIS-app. Deze waarde moet exact overeenkomen met de naam van de LUIS-intentie.
intentID Een id die door de Speech SDK wordt toegewezen aan een herkende intentie. Deze waarde kan zijn wat u wilt; deze hoeft niet overeen te komen met de naam van de intentie zoals gedefinieerd in de LUIS-app. Als in dezelfde code bijvoorbeeld meerdere intenties worden afgehandeld, kun u dezelfde id voor de intenties gebruiken.

De LUIS-app Home Automation heeft twee intenties: een voor het inschakelen van een apparaat en een andere voor het uitschakelen van een apparaat. Met de onderstaande regels worden deze intenties toegevoegd aan het mechanisme voor intentieherkenning. Vervang de drie regels AddIntent in de methode RecognizeIntentAsync() door deze code.

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

In plaats van afzonderlijke intenties toe te voegen, kunt u ook de AddAllIntents methode gebruiken om alle intenties in een model toe te voegen aan de recognizer.

Herkenning starten

Het mechanisme voor intentieherkenning is gemaakt en de intenties zijn toegevoegd. We kunnen dus het proces van herkenning starten. De Speech SDK biedt ondersteuning voor herkenning van zowel afzonderlijke opnamen als continue herkenning.

Herkennings-modus Methoden om aan te roepen Resultaat
Eén opname RecognizeOnceAsync() Retourneert de herkende intentie, indien aanwezig, na één utterance.
Continu StartContinuousRecognitionAsync()
StopContinuousRecognitionAsync()
Herkent meerdere uitingen; verzendt gebeurtenissen (bijvoorbeeld IntermediateResultReceived) wanneer resultaten beschikbaar zijn.

De toepassing maakt gebruik van de modus voor één opname en roept daarom aan RecognizeOnceAsync() om de herkenning te starten. Het resultaat is een IntentRecognitionResult-object met informatie over de herkende intentie. U extraheert het LUIS JSON-antwoord met behulp van de volgende expressie:

result.Properties.GetProperty(PropertyId.LanguageUnderstandingServiceResponse_JsonResult)

De toepassing parseert het JSON-resultaat niet. Alleen de JSON-tekst wordt weergegeven in het consolevenster.

Single LUIS recognition results

Herkenningstaal opgeven

Standaard herkent LUIS intenties in het Amerikaans-Engels (en-us). U kunt een landinstellingscode toewijzen aan de eigenschap SpeechRecognitionLanguage van de spraakconfiguratie om intenties in andere talen te herkennen. Voeg bijvoorbeeld onze toepassing toe config.SpeechRecognitionLanguage = "de-de"; voordat u de recognizer maakt om intenties in het Duits te herkennen. Zie LUIS-taalondersteuning voor meer informatie.

Continue herkenning uit een bestand

De volgende code illustreert nog twee mogelijkheden van intentieherkenning met behulp van de Speech SDK. De eerste mogelijkheid, die eerder is genoemd, is continue spraakherkenning. Hierbij verzendt het mechanisme voor intentieherkenning gebeurtenissen wanneer er resultaten beschikbaar zijn. Deze gebeurtenissen worden verwerkt door gebeurtenis-handlers die u opgeeft. Met continue herkenning roept u de methode van StartContinuousRecognitionAsync() de recognizer aan om herkenning te starten in plaats van RecognizeOnceAsync().

De andere mogelijkheid is het lezen van de audio met de spraak die moet worden verwerkt uit een WAV-bestand. Implementatie omvat het maken van een audioconfiguratie die kan worden gebruikt bij het maken van de intentieherkenning. Het bestand moet éénkanaals (mono) zijn met een samplefrequentie van 16 kHz.

Als u deze functies wilt uitproberen, verwijdert of markeert u de hoofdtekst van de RecognizeIntentAsync() methode en voegt u de volgende code toe.

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

Pas de code aan om uw LUIS-voorspellingssleutel, -regio en -app-id op te nemen en om de intenties van Home Automation toe te voegen, zoals voorheen. Ga naar whatstheweatherlike.wav de naam van het opgenomen audiobestand. Vervolgens bouwt u het audiobestand naar de buildmap en voert u de toepassing uit.

Als u bijvoorbeeld 'De lichten uitschakelen' zegt, pauzeert en zegt u 'De lichten inschakelen' in uw opgenomen audiobestand, kan de console-uitvoer worden weergegeven die lijkt op het volgende:

Audio file LUIS recognition results

Het Speech SDK-team onderhoudt actief een grote set voorbeelden in een opensource-opslagplaats. Zie de Azure AI Speech SDK op GitHub voor de voorbeeldopslagplaats voor broncode. Er zijn voorbeelden voor C#, C++, Java, Python, Objective-C, Swift, JavaScript, UWP, Unity en Xamarin. Zoek de code uit dit artikel in de map samples/csharp/sharedcontent/console .

Volgende stappen

Quickstart: Spraak herkennen vanuit een microfoon