Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Neste tutorial, criaremos um aplicativo simples da Plataforma Universal do Windows que usa um modelo de aprendizado de máquina treinado para reconhecer um dígito numérico desenhado pelo usuário. Este tutorial se concentra principalmente em como carregar e usar o Windows ML em seu aplicativo UWP.
O vídeo a seguir mostra o exemplo no qual este tutorial se baseia.
Se você preferir simplesmente olhar para o código do tutorial concluído, você pode encontrá-lo no repositório GitHub WinML. Também está disponível em C++/CX.
Pré-requisitos
- Windows 10 (Versão 1809 ou superior)
- SDK do Windows 10 (Build 17763 ou superior)
- Visual Studio 2019 (ou Visual Studio 2017, versão 15.7.4 ou posterior)
- Extensão do Gerador de Código do Windows Machine Learning para Visual Studio 2019 ou 2017
- Alguns conhecimentos básicos de UWP e C#
1. Abra o projeto no Visual Studio
Depois de baixar o projeto do GitHub, inicie o Visual Studio e abra o arquivo MNIST_Demo.sln (ele deve estar localizado em <Path to repo>\Windows-Machine-Learning\Samples\MNIST\Tutorial\cs). Se a solução for mostrada como indisponível, você precisará clicar com o botão direito do mouse no projeto no Gerenciador de Soluções e selecionar Recarregar Projeto.
Fornecemos um modelo com controles e eventos XAML implementados, incluindo:
- Um InkCanvas para desenhar um dígito.
- Botões para interpretar o dígito e limpar a tela.
- Rotinas auxiliares para converter a saída do InkCanvas em um VideoFrame.
Dentro do Gerenciador de Soluções, o projeto tem três arquivos de código principais:
- MainPage.xaml - Todo o nosso código XAML para criar a interface do usuário para o InkCanvas, botões e rótulos.
- MainPage.xaml.cs - Onde reside o nosso código de aplicação.
- Helper.cs - Rotinas auxiliares para cortar e converter formatos de imagem.
2. Construa e execute o projeto
Na barra de ferramentas do Visual Studio, altere a plataforma de solução para x64 para executar o projeto em sua máquina local se o dispositivo for de 64 bits ou x86 se for de 32 bits. (Você pode verificar no aplicativo Configurações do Windows: Sistema > Sobre > Especificações do dispositivo > Tipo de sistema.)
Para executar o projeto, clique no botão Iniciar depuração na barra de ferramentas ou pressione F5. O aplicativo deve mostrar um InkCanvas onde os usuários podem escrever um dígito, um botão Reconhecer para interpretar o número, um campo de rótulo vazio onde o dígito interpretado será exibido como texto e um botão Limpar Dígito para limpar o InkCanvas.
Observação
Se o projeto não conseguir ser compilado, talvez seja necessário alterar a versão alvo de implementação do projeto. Clique com o botão direito do mouse no projeto no Gerenciador de Soluções e selecione Propriedades. Na guia Aplicativo , defina a versão de destino e a versão Min para corresponder ao seu sistema operacional e SDK.
Observação
Se você receber um aviso de que o aplicativo já está instalado, basta selecionar Sim para continuar com a implantação. Talvez seja necessário fechar o Visual Studio e reabrir se ele ainda não funcionar.
3. Faça o download de um modelo
Em seguida, vamos obter um modelo de aprendizado de máquina para adicionar ao nosso aplicativo. Para este tutorial, usaremos um modelo MNIST pré-treinado que foi treinado com o Microsoft Cognitive Toolkit (CNTK) e exportado para o formato ONNX.
O modelo MNIST já foi incluído na pasta Ativos e você precisará adicioná-lo ao seu aplicativo como um item existente. Você também pode baixar o modelo pré-treinado do ONNX Model Zoo no GitHub.
4. Adicione o modelo
Clique com o botão direito do mouse na pasta Ativos no Gerenciador de Soluções e selecione Adicionar>Item Existente. Aponte o seletor de arquivos para o local do seu modelo ONNX e clique em Adicionar.
O projeto deverá agora ter dois novos ficheiros:
- mnist.onnx - Seu modelo treinado.
- mnist.cs - O código gerado pelo Windows ML.
Para garantir que o modelo seja compilado quando compilamos nosso aplicativo, clique com o botão direito do mouse no arquivo mnist.onnx e selecione Propriedades. Em Build Action, selecione Content.
Agora, vamos dar uma olhada no código recém-gerado no arquivo mnist.cs . Temos três classes:
- mnistModel cria a representação do modelo de aprendizado de máquina, cria uma sessão no dispositivo padrão do sistema, vincula as entradas e saídas específicas ao modelo e avalia o modelo de forma assíncrona.
- mnistInput inicializa os tipos de entrada esperados pelo modelo. Nesse caso, espera-se um valor de entrada de ImageFeatureValue.
- mnistOutput inicializa os tipos que o modelo produzirá. Neste caso, a saída será uma lista chamada Plus214_Output_0 do tipo TensorFloat.
Agora usaremos essas classes para carregar, vincular e avaliar o modelo em nosso projeto.
5. Carregue, encaderne e avalie o modelo
Para aplicativos de ML do Windows, o padrão que queremos seguir é: Load > Bind > Evaluate.
- Carregue o modelo de aprendizado de máquina.
- Vincule entradas e saídas ao modelo.
- Avalie o modelo e visualize os resultados.
Usaremos o código de interface gerado em mnist.cs para carregar, vincular e avaliar o modelo em nosso aplicativo.
Primeiro, em MainPage.xaml.cs, vamos instanciar o modelo, entradas e saídas. Adicione as seguintes variáveis de membro à classe MainPage :
private mnistModel ModelGen;
private mnistInput ModelInput = new mnistInput();
private mnistOutput ModelOutput;
Em seguida, em LoadModelAsync, carregaremos o modelo. Este método deve ser chamado antes de utilizarmos qualquer método do modelo (ou seja, no evento Loaded da MainPage, numa redefinição de OnNavigatedTo, ou em qualquer ponto antes de o recognizeButton_Click ser chamado). A classe mnistModel representa o modelo MNIST e cria a sessão no dispositivo padrão do sistema. Para carregar o modelo, chamamos o método CreateFromStreamAsync , passando o arquivo ONNX como o parâmetro.
private async Task LoadModelAsync()
{
// Load a machine learning model
StorageFile modelFile = await StorageFile.GetFileFromApplicationUriAsync(new Uri($"ms-appx:///Assets/mnist.onnx"));
ModelGen = await mnistModel.CreateFromStreamAsync(modelFile as IRandomAccessStreamReference);
}
Observação
Se você receber sublinhados vermelhos em IRandomAccessStreamReference, precisará incluir seu namespace. Coloque o cursor sobre ele, pressione Ctrl + . e selecione usar Windows.Storage.Streams no menu suspenso.
Em seguida, queremos vincular nossas entradas e saídas ao modelo. O código gerado também inclui classes wrapper mnistInput e mnistOutput . A classe mnistInput representa as entradas esperadas do modelo e a classe mnistOutput representa as saídas esperadas do modelo.
Para inicializar o objeto de entrada do modelo, chame o construtor da classe mnistInput , passando os dados do aplicativo, e certifique-se de que os dados de entrada correspondam ao tipo de entrada esperado pelo modelo. A classe mnistInput espera um ImageFeatureValue, portanto, usamos um método auxiliar para obter um ImageFeatureValue para a entrada.
Usando nossas funções auxiliares incluídas no helper.cs, copiaremos o conteúdo do InkCanvas, convertê-lo-emos para digitar ImageFeatureValue e vinculá-lo-emos ao nosso modelo.
private async void recognizeButton_Click(object sender, RoutedEventArgs e)
{
// Bind model input with contents from InkCanvas
VideoFrame vf = await helper.GetHandWrittenImage(inkGrid);
ModelInput.Input3 = ImageFeatureValue.CreateFromVideoFrame(vf);
}
Para a saída, basta chamar EvaluateAsync com a entrada especificada. Depois que as entradas forem inicializadas, chame o método EvaluateAsync do modelo para avaliar seu modelo nos dados de entrada. EvaluateAsync vincula suas entradas e saídas ao objeto do modelo e avalia o modelo nas entradas.
Como o modelo retorna um tensor de saída, primeiro vamos querer convertê-lo em um tipo de dados amigável e, em seguida, analisar a lista retornada para determinar qual dígito tinha a maior probabilidade e exibir aquele.
private async void recognizeButton_Click(object sender, RoutedEventArgs e)
{
// Bind model input with contents from InkCanvas
VideoFrame vf = await helper.GetHandWrittenImage(inkGrid);
ModelInput.Input3 = ImageFeatureValue.CreateFromVideoFrame(vf);
// Evaluate the model
ModelOutput = await ModelGen.EvaluateAsync(ModelInput);
// Convert output to datatype
IReadOnlyList<float> vectorImage = ModelOutput.Plus214_Output_0.GetAsVectorView();
IList<float> imageList = vectorImage.ToList();
// Query to check for highest probability digit
var maxIndex = imageList.IndexOf(imageList.Max());
// Display the results
numberLabel.Text = maxIndex.ToString();
}
Finalmente, vamos querer limpar o InkCanvas para permitir que os usuários desenhem outro número.
private void clearButton_Click(object sender, RoutedEventArgs e)
{
inkCanvas.InkPresenter.StrokeContainer.Clear();
numberLabel.Text = "";
}
6. Inicie a aplicação
Depois de construir e iniciar o aplicativo (pressione F5), seremos capazes de reconhecer um número desenhado no InkCanvas.
É isso - você fez seu primeiro aplicativo de ML do Windows! Para obter mais exemplos que demonstram como usar o Windows ML, confira nosso repositório Windows-Machine-Learning no GitHub.
Observação
Use os seguintes recursos para obter ajuda com o Windows ML:
- Para fazer ou responder a perguntas técnicas sobre o Windows ML, use a tag windows-machine-learning em Stack Overflow.
- Para relatar um bug, registre um problema em nosso GitHub.