Så här identifierar du avsikter från tal med hjälp av Speech SDK för C#

Speech SDK för Azure AI-tjänster integreras med Language Understanding-tjänsten (LUIS) för att ge avsiktsigenkänning. En avsikt är något som användaren vill göra: boka en flygning, titta på vädret eller ringa ett samtal. Användaren kan använda de termer som känns naturliga. LUIS mappar användarbegäranden till de avsikter som du har definierat.

Kommentar

Ett LUIS-programmet definierar avsikter och entiteter som du vill identifiera. Det är separat från det C#-program som använder Speech-tjänsten. I den här artikeln betyder ”app” LUIS-appen medan ”program” innebär C#-koden.

I den här guiden använder du Speech SDK för att utveckla ett C#-konsolprogram som härleder avsikter från användaryttranden via enhetens mikrofon. Du lär dig att:

  • Skapa ett Visual Studio-projekt som refererar till Speech SDK NuGet-paketet
  • Skapa en talkonfiguration och få en avsiktsigenkänning
  • Hämta modellen för LUIS-appen och lägga till de avsikter som du behöver
  • Ange språk för taligenkänning
  • Identifiera tal från en fil
  • Använd asynkron, händelsedriven kontinuerlig igenkänning

Förutsättningar

Se till att du har följande objekt innan du påbörjar den här guiden:

LUIS och tal

LUIS integreras med Speech-tjänsten för att identifiera avsikter från tal. Du behöver inte en Speech-tjänstprenumeration, bara LUIS.

LUIS använder två typer av nycklar:

Nyckeltyp Syfte
Redigering Gör att du kan skapa och ändra LUIS-appar programmatiskt
Förutsägelse Används för att komma åt LUIS-programmet under körning

För den här guiden behöver du typen av förutsägelsenyckel. Den här guiden använder exemplet Home Automation LUIS-app, som du kan skapa genom att följa snabbstarten Använd fördefinierad hemautomatiseringsapp . Om du har skapat en egen LUIS-app kan du använda den i stället.

När du skapar en LUIS-app genererar LUIS automatiskt en redigeringsnyckel så att du kan testa appen med hjälp av textfrågor. Den här nyckeln aktiverar inte integreringen av Speech-tjänsten och fungerar inte med den här guiden. Skapa en LUIS-resurs på Azure-instrumentpanelen och tilldela den till LUIS-appen. Du kan använda den kostnadsfria prenumerationsnivån för den här guiden.

När du har skapat LUIS-resursen på Azure-instrumentpanelen loggar du in på LUIS-portalen, väljer ditt program på sidan Mina appar och växlar sedan till appens hantera-sida. Välj slutligen Azure-resurser i sidofältet.

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

På sidan Azure-resurser :

Välj ikonen bredvid en nyckel för att kopiera den till Urklipp. (Du kan använda någon av nycklarna.)

Skapa projektet och lägg till arbetsbelastningen

Om du vill skapa ett Visual Studio-projekt för Windows-utveckling måste du skapa projektet, konfigurera Visual Studio för .NET Desktop-utveckling, installera Speech SDK och välja målarkitekturen.

Börja genom att skapa projektet i Visual Studio och se till att Visual Studio har konfigurerats för .NET Desktop-utveckling:

  1. Öppna Visual Studio 2019.

  2. I startfönstret väljer du Skapa ett nytt projekt.

  3. I fönstret Skapa ett nytt projekt väljer du Konsolapp (.NET Framework) och sedan Nästa.

  4. I fönstret Konfigurera det nya projektet anger du helloworld i Projektnamn, väljer eller skapar katalogsökvägen i Plats och väljer sedan Skapa.

  5. I menyraden i Visual Studio väljer du Verktyg>Hämta verktyg och funktioner, som öppnar Visual Studio Installer och visar dialogrutan Ändra.

  6. Kontrollera om arbetsbelastningen för .NET-skrivbordsutveckling är tillgänglig. Om arbetsbelastningen inte är installerad markerar du kryssrutan bredvid den och väljer sedan Ändra för att starta installationen. Det kan ta några minuter att ladda ned och installera.

    Om kryssrutan bredvid .NET Desktop Development redan är markerad väljer du Stäng för att avsluta dialogrutan.

    Enable .NET desktop development

  7. Stäng Visual Studio Installer.

Installera Speech SDK

Nästa steg är att installera Speech SDK NuGet-paketet så att du kan referera till det i koden.

  1. Högerklicka på helloworld-projektet i Solution Explorer och välj sedan Hantera NuGet-paket för att visa NuGet Package Manager.

    NuGet Package Manager

  2. Leta upp listrutan Paketkälla i det övre högra hörnet och kontrollera att nuget.org är markerat.

  3. I det övre vänstra hörnet väljer du Bläddra.

  4. I sökrutan skriver du Microsoft.CognitiveServices.Speech och väljer Retur.

  5. I sökresultaten väljer du paketet Microsoft.CognitiveServices.Speech och väljer sedan Installera för att installera den senaste stabila versionen.

    Install Microsoft.CognitiveServices.Speech NuGet package

  6. Acceptera alla avtal och licenser för att starta installationen.

    När paketet har installerats visas en bekräftelse i fönstret Package Manager Console .

Välj målarkitekturen

Skapa nu en plattformskonfiguration som matchar datorns arkitektur för att skapa och köra konsolprogrammet.

  1. I menyraden väljer du Skapa>Configuration Manager. Dialogrutan Configuration Manager visas.

    Configuration Manager dialog box

  2. I listrutan Aktiv lösningsplattform väljer du Nytt. Dialogrutan Ny lösningsplattform visas.

  3. I listrutan Typ eller välj den nya plattformen :

    • Om du kör 64-bitars Windows väljer du x64.
    • Om du kör 32-bitars Windows väljer du x86.
  4. Välj OK och sedan Stäng.

Lägga till koden

Sedan lägger du till kod i projektet.

  1. Öppna filen Program.cs från Solution Explorer.

  2. Ersätt -instruktionsblocket using i början av filen med följande deklarationer:

    using System;
    using System.Threading.Tasks;
    using Microsoft.CognitiveServices.Speech;
    using Microsoft.CognitiveServices.Speech.Audio;
    using Microsoft.CognitiveServices.Speech.Intent;
    
  3. Ersätt den angivna Main() metoden med följande asynkrona motsvarighet:

    public static async Task Main()
    {
        await RecognizeIntentAsync();
        Console.WriteLine("Please press Enter to continue.");
        Console.ReadLine();
    }
    
  4. Skapa en tom asynkron metod RecognizeIntentAsync(), som du ser här:

    static async Task RecognizeIntentAsync()
    {
    }
    
  5. Lägg till den här koden i brödtexten för den här nya metoden:

    // 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. Ersätt platshållarna i den här metoden med din LUIS-resursnyckel, region och app-ID på följande sätt.

    Platshållare Replace with
    YourLanguageUnderstandingSubscriptionKey Din LUIS-resursnyckel. Återigen måste du hämta det här objektet från din Azure-instrumentpanel. Du hittar den på appens Azure-resurssida (under Hantera) i LUIS-portalen.
    YourLanguageUnderstandingServiceRegion Den korta identifieraren för den region som LUIS-resursen finns i, till exempel westus för USA, västra. Se regioner.
    YourLanguageUnderstandingAppId LUIS-app-ID. Du hittar den på appens Inställningar-sida i LUIS-portalen.

Med de här ändringarna kan du skapa (Control+Skift+B) och köra (F5) programmet. När du uppmanas att göra det kan du prova att säga "Stäng av lamporna" i datorns mikrofon. Programmet visar resultatet i konsolfönstret.

Följande avsnitt innehåller en beskrivning av koden.

Skapa en avsiktsigenkännare

Först måste du skapa en talkonfiguration från din LUIS-förutsägelsenyckel och -region. Du kan använda talkonfigurationer för att skapa identifierare för de olika funktionerna i Speech SDK. Talkonfigurationen har flera sätt att ange den resurs som du vill använda. här använder FromSubscriptionvi , som tar resursnyckeln och regionen.

Kommentar

Använd nyckeln och regionen för luis-resursen, inte en Speech-resurs.

Nästa steg är att skapa en avsiktsigenkännare med hjälp av new IntentRecognizer(config). Eftersom konfigurationen redan vet vilken resurs som ska användas behöver du inte ange nyckeln igen när du skapar identifieraren.

Importera en LUIS-modell och lägga till avsikter

Nu importerar du modellen från LUIS-appen med hjälp av LanguageUnderstandingModel.FromAppId() och lägger till de LUIS-avsikter som du vill känna igen igenkännarens AddIntent()-metod. De här två stegen förbättrar taligenkänningens noggrannhet genom att ange ord som det är troligt att användaren använder i sina begäranden. Du behöver inte lägga till alla appens avsikter om du inte behöver känna igen alla i ditt program.

Om du vill lägga till avsikter måste du ange tre argument: LUIS-modellen (med namnet model), avsiktsnamnet och ett avsikts-ID. Skillnaden mellan ID och namnet är som följer.

AddIntent()-argument Syfte
intentName Namnet på avsikten enligt vad som definierats i LUIS-appen. Det här värdet måste matcha LUIS-avsiktsnamnet exakt.
intentID Ett ID som tilldelas till en igenkänd avsikt av Speech SDK. Det här värdet kan vara vad du vill. Den behöver inte motsvara avsiktsnamnet enligt definitionen i LUIS-appen. Om flera avsikter till exempel hanteras av samma kod kan du använda samma ID för dem.

Home Automation LUIS-appen har två avsikter: en för att aktivera en enhet och en annan för att stänga av en enhet. Raderna nedan lägger till dessa avsikter till igenkännaren. Ersätt de tre AddIntent-raderna i metoden RecognizeIntentAsync() med den här koden.

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

I stället för att lägga till enskilda avsikter kan du också använda AddAllIntents metoden för att lägga till alla avsikter i en modell till identifieraren.

Starta igenkänning

När igenkännaren har skapats och avsikterna lagts till kan igenkänningen börja. Speech SDK stöder både engångsigenkänning och kontinuerlig igenkänning.

Igenkänningsläge Metoder att anropa Resultat
Engångsigenkänning RecognizeOnceAsync() Returnerar den igenkända avsikten, om sådan finns, efter ett yttrande.
Kontinuerligt StartContinuousRecognitionAsync()
StopContinuousRecognitionAsync()
Identifierar flera yttranden. genererar händelser (till exempel IntermediateResultReceived) när resultaten är tillgängliga.

Programmet använder enkelbildsläge och anropar RecognizeOnceAsync() därför för att påbörja igenkänningen. Resultatet är ett IntentRecognitionResult-objekt som innehåller information om den igenkända avsikten. Du extraherar LUIS JSON-svaret med hjälp av följande uttryck:

result.Properties.GetProperty(PropertyId.LanguageUnderstandingServiceResponse_JsonResult)

Programmet parsar inte JSON-resultatet. Den visar bara JSON-texten i konsolfönstret.

Single LUIS recognition results

Ange igenkänningsspråk

Som standard känner LUIS igen avsikter på amerikansk engelska (en-us). Genom att tilldela en kod för nationella inställningar till egenskapen SpeechRecognitionLanguage i talkonfigurationen kan du känna igen avsikter på andra språk. Lägg till exempel i config.SpeechRecognitionLanguage = "de-de"; vårt program innan du skapar identifieraren för att identifiera avsikter på tyska. Mer information finns i LUIS-språkstöd.

Kontinuerlig igenkänning från en fil

Följande kod illustrerar ytterligare två funktioner för avsiktsigenkänning med hjälp av Speech SDK. Den första, som nämnts tidigare, är kontinuerlig igenkänning, där igenkännaren genererar händelser när resultat finns tillgängliga. Dessa händelser bearbetas av händelsehanterare som du anger. Med kontinuerlig igenkänning anropar du identifierarens StartContinuousRecognitionAsync() metod för att starta igenkänningen i stället RecognizeOnceAsync()för .

Den andra funktionen är att läsa det ljud som innehåller det tal som ska bearbetas från en WAV-fil. Implementeringen innebär att skapa en ljudkonfiguration som kan användas när du skapar avsiktsigenkänningen. Filen måste vara enkanalig (mono) med en samplingsfrekvens på 16 kHz.

Om du vill testa de här funktionerna tar du bort eller kommenterar ut metodens RecognizeIntentAsync() brödtext och lägger till följande kod i stället.

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

Ändra koden så att den innehåller din LUIS-förutsägelsenyckel, region och app-ID och för att lägga till avsikterna För hemautomatisering som tidigare. Ändra whatstheweatherlike.wav till namnet på den inspelade ljudfilen. Skapa sedan, kopiera ljudfilen till byggkatalogen och kör programmet.

Om du till exempel säger "Stäng av lamporna", pausar och sedan säger "Tänd lamporna" i din inspelade ljudfil kan konsolutdata som liknar följande visas:

Audio file LUIS recognition results

Speech SDK-teamet har aktivt en stor uppsättning exempel på en lagringsplats med öppen källkod. Exempellagringsplatsen för källkod finns i Azure AI Speech SDK på GitHub. Det finns exempel för C#, C++, Java, Python, Objective-C, Swift, JavaScript, UWP, Unity och Xamarin. Leta efter koden från den här artikeln i mappen samples/csharp/sharedcontent/console .

Nästa steg

Snabbstart: Identifiera tal från en mikrofon