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:
- Uma conta LUIS. Você pode obter uma gratuitamente por meio do portal do LUIS.
- Visual Studio 2019 (qualquer edição).
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.
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:
Abra o Visual Studio 2019.
Na janela Iniciar, selecione Criar projeto.
Na janela Criar um projeto, escolha Aplicativo de Console (.NET Framework) e selecione Avançar.
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.
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.
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.
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.
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.
No canto superior direito, localize a caixa suspensa Origem do Pacote e verifique se nuget.org está selecionado.
No canto superior esquerdo, selecione Procurar.
Na caixa de pesquisa, digite Microsoft.CognitiveServices.Speech e selecione Enter.
Nos resultados da pesquisa, selecione o pacote Microsoft.CognitiveServices.Speech e, em seguida, selecione Instalar para instalar a versão estável mais recente.
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.
Na barra de menus, selecione Compilar>Gerenciador de Configuração. A caixa de diálogo Gerenciador de Configurações é exibida.
Na caixa suspensa Plataforma de solução ativa, selecione Novo. A caixa de diálogo Nova plataforma de solução é exibida.
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.
Selecione OK e, em seguida, Fechar.
Adicionar o código
Em seguida, adicione o código ao projeto.
No Gerenciador de Soluções, abra o arquivo Program.cs.
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;
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(); }
Crie um método
RecognizeIntentAsync()
assíncrono vazio, conforme mostrado aqui:static async Task RecognizeIntentAsync() { }
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?"); } } }
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.
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:
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.