Como reconhecer as intenções de fala usando o SDK de Fala para C#

O SDK de Fala dos Serviços de IA do Azure integra-se ao serviço de Reconhecimento vocal (LUIS) para fornecer reconhecimento de intenção. Uma intenção é algo que o usuário deseja fazer: agendar um voo, conferir o clima ou fazer uma chamada. O usuário pode usar os termos que mais lhe parecerem naturais. O LUIS mapeia as solicitações de usuário para as intenções definidas.

Observação

Um aplicativo LUIS define as intenções e entidades que você deseja reconhecer. Ele é separado do aplicativo C# que usa o serviço de Fala. Neste artigo, “app” significa o aplicativo LUIS, enquanto “aplicativo” significa o código C#.

Neste tutorial, você usará o SDK de Fala para desenvolver um aplicativo de console C# que deriva as intenção de enunciados de usuário por meio do microfone do dispositivo. Você aprenderá como:

  • Criar um projeto do Visual Studio que faz referência ao pacote NuGet do SDK de Fala
  • Criar uma configuração de fala e obter um reconhecedor de intenção
  • Obter o modelo para seu app LUIS e adicionar as intenção que você precisa
  • Especificar o idioma do reconhecimento de fala
  • Reconhecer a fala de um arquivo
  • Usar reconhecimento contínuo, assíncrono e orientado a eventos

Pré-requisitos

Confira se você tem os itens a seguir antes de começar este tutorial:

LUIS e fala

O LUIS integra-se ao serviço de Fala para reconhecer intenções de fala. Você não precisa de uma assinatura do serviço de Fala, apenas do LUIS.

O LUIS usa dois tipos de chaves:

Tipo de chave Finalidade
Criação Permite criar e modificar aplicativos LUIS programaticamente
Previsão Usado para acessar o aplicativo LUIS no runtime

Para este guia, você precisa do tipo de chave de previsão. O tutorial usa o aplicativo LUIS de Automação residencial como exemplo, que pode ser criado seguindo o guia de início rápido Usar o aplicativo de Automação residencial predefinido. Se você criou um aplicativo LUIS próprio, poderá usá-lo.

Ao criar um aplicativo LUIS, o LUIS gera automaticamente uma chave de criação para que você possa testar o aplicativo usando consultas de texto. Essa chave não habilita a integração do Serviço de Fala e não funciona com este tutorial. Crie um recurso LUIS no painel do Azure e atribua-o ao aplicativo LUIS. Você pode usar a camada de assinatura gratuita para este tutorial.

Após criar o recurso LUIS no painel do Azure, faça logon no portal do LUIS, escolha seu aplicativo na página Meus Aplicativos e alterne para a página Gerenciar do aplicativo. Por fim, selecione Recursos do Azure na barra lateral.

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

Na página Recursos do Azure :

Selecione o ícone ao lado da chave para copiá-la para a área de transferência. Você poderá usar outra chave.

Criar o projeto e adicionar a carga de trabalho

Para criar um projeto do Visual Studio para desenvolvimento de Windows, é necessário criar o projeto, configurar o Visual Studio para desenvolvimento de área de trabalho do .NET, instalar o SDK de Fala e escolher a arquitetura de destino.

Para começar, crie o projeto no Visual Studio e verifique se o Visual Studio está configurado para desenvolvimento de área de trabalho do .NET:

  1. Abra o Visual Studio 2019.

  2. Na janela Iniciar, selecione Criar projeto.

  3. Na janela Criar um projeto, escolha Aplicativo de Console (.NET Framework) e selecione Avançar.

  4. Na janela Configure seu novo projeto, insira olámundo no Nome do projeto, escolha ou crie o caminho do diretório na Localização e selecione Criar.

  5. Na barra de menus do Visual Studio, selecione Ferramentas>Obter Ferramentas e Recursos, que abre o Instalador do Visual Studio e exibe a caixa de diálogo Modificando.

  6. Verifique se a carga de trabalho desenvolvimento de área de trabalho do .NET está disponível. Se a carga de trabalho não estiver instalada, selecione a caixa de seleção ao lado dela e, em seguida, Modificar para iniciar a instalação. Talvez o download e a instalação demore alguns minutos.

    Se a caixa de seleção ao lado do desenvolvimento de área de trabalho do .NET já estiver selecionada, selecione Fechar para sair da caixa de diálogo.

    Enable .NET desktop development

  7. Feche o Instalador do Visual Studio.

Instalar o SDK de Fala

A próxima etapa é instalar o pacote NuGet do SDK de Fala, para que você possa referenciá-lo no código.

  1. No Gerenciador de Soluções, clique com o botão direito do mouse no projeto olámundo e depois selecione Gerenciar Pacotes NuGet para mostrar o Gerenciador de Pacotes NuGet.

    NuGet Package Manager

  2. No canto superior direito, localize a caixa suspensa Origem do Pacote e verifique se nuget.org está selecionado.

  3. No canto superior esquerdo, selecione Procurar.

  4. Na caixa de pesquisa, digite Microsoft.CognitiveServices.Speech e selecione Enter.

  5. Nos resultados da pesquisa, selecione o pacote Microsoft.CognitiveServices.Speech e, em seguida, selecione Instalar para instalar a versão estável mais recente.

    Install Microsoft.CognitiveServices.Speech NuGet package

  6. Aceite todos os contratos e licenças para iniciar a instalação.

    Depois que o pacote for instalado, uma confirmação será exibida no Console do gerenciador de pacotes.

Escolha a arquitetura de destino

Agora, para criar e executar o aplicativo de console, crie uma configuração de plataforma que corresponda à arquitetura do seu computador.

  1. Na barra de menus, selecione Compilar>Gerenciador de Configuração. A caixa de diálogo Gerenciador de Configurações é exibida.

    Configuration Manager dialog box

  2. Na caixa suspensa Plataforma de solução ativa, selecione Novo. A caixa de diálogo Nova plataforma de solução é exibida.

  3. Na caixa suspensa Digite ou selecione a nova plataforma:

    • Se você estiver executando o Windows 64 bits, selecione x64.
    • Se você estiver executando o Windows 32 bits, selecione x86.
  4. Selecione OK e, em seguida, Fechar.

Adicionar o código

Em seguida, adicione o código ao projeto.

  1. No Gerenciador de Soluções, abra o arquivo Program.cs.

  2. Substitua o bloco de instruções using no início do arquivo pelas declarações a seguir:

    using System;
    using System.Threading.Tasks;
    using Microsoft.CognitiveServices.Speech;
    using Microsoft.CognitiveServices.Speech.Audio;
    using Microsoft.CognitiveServices.Speech.Intent;
    
  3. Substitua o método Main() fornecido com o seguinte equivalente assíncrono:

    public static async Task Main()
    {
        await RecognizeIntentAsync();
        Console.WriteLine("Please press Enter to continue.");
        Console.ReadLine();
    }
    
  4. Crie um método RecognizeIntentAsync() assíncrono vazio, conforme mostrado aqui:

    static async Task RecognizeIntentAsync()
    {
    }
    
  5. No corpo deste novo método, adicione este código:

    // 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. Substitua os espaços reservados nesse método pela sua chave de recurso do LUIS, região e ID do aplicativo, conforme mostrado a seguir.

    Espaço reservado Substitua por
    YourLanguageUnderstandingSubscriptionKey A chave de recurso do LUIS. Novamente, você deve obter esse item do seu painel do Azure,. Você pode encontrá-lo na página Recursos do Azure do seu aplicativo (em Gerenciar) no portal do LUIS.
    YourLanguageUnderstandingServiceRegion O identificador curto para a região na qual o recurso do LUIS se encontra, como westus para Oeste dos EUA. Consulte Regiões.
    YourLanguageUnderstandingAppId A ID do aplicativo de LUIS. Você pode encontrá-la na página Configurações do seu aplicativo no portal do LUIS.

Com essas alterações concluídas, crie (Control+Shift+B) e execute (F5) o aplicativo. Quando solicitado, tente dizer “Apague as luzes” no microfone do seu computador. O aplicativo exibe o resultado na janela do console.

As seções a seguir incluem uma discussão sobre o código.

Criar um reconhecedor de intenção

Primeiro você precisa criar uma configuração de fala em sua chave de previsão e região do LUIS. Você pode usar as configurações de fala para criar reconhecedores para as várias funcionalidades do SDK de Fala. A configuração de fala tem várias maneiras de especificar o recurso que você deseja usar. Aqui, usamos FromSubscription, que usa a chave de recurso e a região.

Observação

Use a chave e a região do recurso do LUIS, e não um recurso de Fala.

Em seguida, crie um reconhecedor de intenção usando new IntentRecognizer(config). Depois que a configuração souber qual recurso usar, você não precisará especificar a chave novamente ao criar o reconhecedor.

Importar um modelo LUIS e adicionar intenções

Agora, importe o modelo do app LUIS usando LanguageUnderstandingModel.FromAppId() e adicione as intenções de LUIS que você deseja reconhecer por meio do método AddIntent() do reconhecedor. Essas duas etapas melhoram a precisão do reconhecimento de fala, indicando as palavras que o usuário provavelmente usará nas solicitações. Você não precisará adicionar todas as intenções do aplicativo se não precisar reconhecer todas elas em seu aplicativo.

Para adicionar intenções, forneça três argumentos: o modelo LUIS (nomeado model), o nome da intenção e o ID da intenção. A diferença entre a ID e o nome é a seguinte.

Argumento AddIntent() Finalidade
intentName O nome da intenção conforme definido no app LUIS. Esse valor precisa corresponder exatamente ao nome de intenção de LUIS.
intentID Uma ID atribuída a uma intenção reconhecida pelo SDK de Fala. Esse valor pode ser o que você desejar; ele não precisa corresponder ao nome da intenção definido no aplicativo LUIS. Se várias intenções forem tratadas pelo mesmo código, por exemplo, seria possível usar a mesma ID para elas.

O aplicativo LUIS de Automação Residencial tem duas intenções: uma para ligar um dispositivo e outra para desligá-lo. As linhas a seguir adicionam essas intenções ao reconhecedor. Substitua as três linhas AddIntent no método RecognizeIntentAsync() com esse código.

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

Em vez de adicionar as intenções individuais, você também pode usar o método AddAllIntents para adicionar todas as intenções em um modelo ao reconhecedor.

Iniciar reconhecimento

Com o reconhecedor criado e as intenções adicionadas, o reconhecimento pode começar. O SDK de Fala é compatível com reconhecimento pontual e contínuo.

Modo de reconhecimento Métodos de chamada Resultado
Pontual RecognizeOnceAsync() Retorna a intenção reconhecida, se houver, após uma declaração.
Contínuo StartContinuousRecognitionAsync()
StopContinuousRecognitionAsync()
Reconhece vários enunciados; emite eventos (por exemplo, IntermediateResultReceived) quando os resultados estão disponíveis.

O aplicativo usa o modo de única execução, por isso ele chama o RecognizeOnceAsync() para iniciar o reconhecimento. O resultado é um objeto IntentRecognitionResult que contém informações sobre a intenção reconhecida. Extraia a resposta JSON do LUIS usando a seguinte expressão:

result.Properties.GetProperty(PropertyId.LanguageUnderstandingServiceResponse_JsonResult)

O aplicativo não analisa o resultado JSON. Ele exibe apenas o texto JSON na janela do console.

Single LUIS recognition results

Especificar idioma de reconhecimento

Por padrão, o LUIS reconhece as intenções em inglês dos EUA (en-us). É possível reconhecer intenções em outros idiomas atribuindo um código de localidade à propriedade SpeechRecognitionLanguage da configuração de fala. Por exemplo, adicione config.SpeechRecognitionLanguage = "de-de"; em nosso aplicativo antes de criar o reconhecedor para reconhecer as intenções em alemão. Para saber mais, consulte suporte para idioma do LUIS.

Reconhecimento contínuo de um arquivo

O código a seguir ilustra duas outras funcionalidades do reconhecimento de intenção usando o SDK de Fala. A primeira, mencionada anteriormente, é o reconhecimento contínuo, em que o reconhecedor emite eventos quando os resultados estão disponíveis. Esses eventos são processados por manipuladores de eventos que você fornecer. Com o reconhecimento contínuo, você chama o método StartContinuousRecognitionAsync() do reconhecedor para iniciar o reconhecimento, em vez de RecognizeOnceAsync().

A outra funcionalidade é a leitura do áudio que contém a fala, processado de um arquivo WAV. Essa implementação envolve a criação de uma configuração de áudio que pode ser usada ao criar o reconhecedor de intenção. O arquivo precisa ser mono (canal único) com uma taxa de amostragem de 16 kHz.

Para experimentar esses recursos, exclua ou comente o corpo do método RecognizeIntentAsync() e adicione o seguinte código em seu lugar.

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

Revise o código para incluir sua chave de previsão do LUIS, a região e a ID do aplicativo e adicione as intenções da Automação Residencial da mesma forma que antes. Altere whatstheweatherlike.wav ao nome de seu arquivo de áudio gravado. Em seguida, copie o arquivo de áudio para o diretório de build e execute o aplicativo.

Por exemplo, se você disser “Apague as luzes”, pausar e depois disser “Acenda as luzes” em seu arquivo de áudio gravado, talvez seja exibida uma saída de console semelhante à seguinte:

Audio file LUIS recognition results

A equipe do SDK de Fala mantém ativamente um grande conjunto de exemplos em um repositório de software livre. Para ver o repositório de códigos-fonte de exemplo, consulte o SDK de Fala da IA do Azure no GitHub. Há exemplos para C#, C++, Java, Python, Objective-C, Swift, JavaScript, UWP, Unity e Xamarin. Procure o código neste artigo na pasta samples/csharp/sharedcontent/console.

Próximas etapas

Início Rápido: Reconhecer fala de um microfone