Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
В этом руководстве мы создадим простое приложение универсальной платформы Windows, которое использует обученную модель машинного обучения для распознавания числовой цифры, рисуемой пользователем. В этом руководстве основное внимание уделяется загрузке и использованию Windows ML в приложении UWP.
В следующем видео приведен пример, на основе который основан этот учебник.
Если вы предпочитаете просто посмотреть код готового руководства, его можно найти в репозитории WinML GitHub. Он также доступен в C++/CX.
Предпосылки
- Windows 10 (версия 1809 или более поздняя)
- Пакет SDK для Windows 10 (сборка 17763 или более поздней версии)
- Visual Studio 2019 (или Visual Studio 2017, версия 15.7.4 или более поздней версии)
- Расширение генератора кода машинного обучения Windows для Visual Studio 2019 или 2017
- Некоторые базовые знания UWP и C#
1. Открытие проекта в Visual Studio
После скачивания проекта из GitHub запустите Visual Studio и откройте файл MNIST_Demo.sln (он должен находиться в <пути к репозиторию>\Windows-Machine-Learning\Samples\MNIST\Tutorial\cs). Если решение отображается как недоступное, необходимо щелкнуть проект правой кнопкой мыши в обозревателе решений и выбрать "Перезагрузить проект".
Мы предоставили шаблон с реализованными элементами управления и событиями XAML, в том числе:
- InkCanvas для рисования цифры.
- Кнопки для интерпретации цифры и очистки холста.
- Вспомогательные подпрограммы для преобразования выходных данных InkCanvas в видеофрейм.
В обозревателе решений проект содержит три основных файла кода:
- MainPage.xaml — весь код XAML для создания пользовательского интерфейса для inkCanvas, кнопок и меток.
- MainPage.xaml.cs — где живет код приложения.
- Helper.cs — вспомогательные подпрограммы для обрезки и преобразования форматов изображений.
2. Сборка и запуск проекта
На панели инструментов Visual Studio измените платформу решения на x64 , чтобы запустить проект на локальном компьютере, если устройство имеет 64-разрядную версию или x86 , если это 32-разрядная версия. (Вы можете проверить приложение параметров Windows: Система > О > Характеристики устройства > Тип системы.)
Чтобы запустить проект, нажмите кнопку "Начать отладку " на панели инструментов или нажмите клавишу F5. Приложение должно отобразить inkCanvas , где пользователи могут писать цифру, кнопку Распознать , чтобы интерпретировать число, пустое поле метки, в котором интерпретируемая цифра будет отображаться как текст, и кнопка "Очистить цифру", чтобы очистить InkCanvas.
Замечание
Если проект не будет построен, может потребоваться изменить целевую версию развертывания проекта. Щелкните проект правой кнопкой мыши в обозревателе решений и выберите "Свойства". На вкладке "Приложение" задайте целевую версию и минимальную версию , чтобы она соответствовала ОС и пакету SDK.
Замечание
Если вы получите предупреждение о том, что приложение уже установлено, просто нажмите кнопку "Да ", чтобы продолжить развертывание. Возможно, потребуется закрыть Visual Studio и повторно открыть его, если он по-прежнему не работает.
3. Скачивание модели
Затем давайте получим модель машинного обучения для добавления в наше приложение. В этом руководстве мы будем использовать предварительно обученную модель MNIST, которая была обучена с помощью Microsoft Cognitive Toolkit (CNTK) и экспортирована в формат ONNX.
Модель MNIST уже включена в папку Assets, и её нужно добавить в приложение как существующий элемент. Вы также можете скачать предварительно обученную модель из зоопарка моделей ONNX на GitHub.
4. Добавление модели
Щелкните правой кнопкой мыши папку "Ресурсы " в обозревателе решений и выберите "Добавить>существующий элемент". Направьте средство выбора файлов к месту расположения модели ONNX и нажмите Добавить.
Теперь проект должен иметь два новых файла:
- mnist.onnx — ваша обученная модель.
- mnist.cs — созданный в Windows ML код.
Чтобы убедиться, что модель выполняет сборку при компиляции приложения, щелкните правой кнопкой мыши файл mnist.onnx и выберите "Свойства". Для действия сборки выберите "Содержимое".
Теперь давайте рассмотрим только что созданный код в файле mnist.cs . У нас есть три класса:
- mnistModel создает представление модели машинного обучения, создает сеанс на устройстве по умолчанию системы, привязывает определенные входные и выходные данные к модели и оценивает модель асинхронно.
- mnistInput инициализирует типы входных данных, которые ожидает модель. В этом случае входные данные ожидают ImageFeatureValue.
- mnistOutput инициализирует типы, которые будет выводить модель. В этом случае выходные данные будут списком, называемым Plus214_Output_0 типа TensorFloat.
Теперь мы будем использовать эти классы для загрузки, привязки и оценки модели в нашем проекте.
5. Загрузка, привязка и оценка модели
Для приложений Windows ML шаблон, который мы хотим выполнить, — load > Bind > Evaluate.
- Загрузите модель машинного обучения.
- Привязка входных и выходных данных к модели.
- Оцените модель и просмотрите результаты.
Мы будем использовать код интерфейса, созданный в mnist.cs для загрузки, привязки и оценки модели в нашем приложении.
Во-первых, в MainPage.xaml.cs создадим экземпляр модели, входные данные и выходные данные. Добавьте следующие переменные-члены в класс MainPage :
private mnistModel ModelGen;
private mnistInput ModelInput = new mnistInput();
private mnistOutput ModelOutput;
Затем в LoadModelAsync мы загрузим модель. Этот метод следует вызывать перед использованием любого из методов модели (т. е. в событии Loaded на MainPage, при переопределении OnNavigatedTo или где-либо до вызова recognizeButton_Click). Класс mnistModel представляет модель MNIST и создает сеанс на системном устройстве по умолчанию. Чтобы загрузить модель, мы вызываем метод CreateFromStreamAsync , передавая в качестве параметра файл ONNX.
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);
}
Замечание
Если вы увидите красные подчеркивания под IRandomAccessStreamReference, необходимо добавить его пространство имен. Поместите курсор над ним, нажмите Ctrl + . и выберите в раскрывающемся меню Windows.Storage.Streams.
Затем мы хотим привязать входные и выходные данные к модели. Созданный код также включает классы оболочки mnistInput и mnistOutput . Класс mnistInput представляет ожидаемые входные данные модели, а класс mnistOutput представляет ожидаемые выходные данные модели.
Чтобы инициализировать входной объект модели, вызовите конструктор класса mnistInput , передавая данные приложения, и убедитесь, что входные данные соответствуют типу входных данных, который ожидает модель. Класс mnistInput ожидает ImageFeatureValue, поэтому мы используем вспомогательный метод для получения ImageFeatureValue для входных данных.
Используя включенные вспомогательные функции в helper.cs, мы скопируйм содержимое InkCanvas, преобразуем его в тип ImageFeatureValue и привязываем его к нашей модели.
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);
}
Для выходных данных мы просто вызываем EvaluateAsync с указанными входными данными. После инициализации входных данных вызовите метод EvaluateAsync модели, чтобы оценить модель на входных данных. EvaluateAsync привязывает входные и выходные данные к объекту модели и оценивает модель на входных данных.
Так как модель возвращает выходной тензор, сначала нужно преобразовать его в понятный тип данных, а затем проанализировать возвращаемый список, чтобы определить, какая цифра имеет самую высокую вероятность и отобразить ее.
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();
}
Наконец, мы хотим очистить InkCanvas , чтобы разрешить пользователям нарисовать другое число.
private void clearButton_Click(object sender, RoutedEventArgs e)
{
inkCanvas.InkPresenter.StrokeContainer.Clear();
numberLabel.Text = "";
}
6. Запуск приложения
После сборки и запуска приложения (нажмите клавишу F5), мы сможем распознать число, нарисованное на inkCanvas.
Это так - вы сделали свое первое приложение Windows ML! Дополнительные примеры, демонстрирующие использование Windows ML, см. в репозитории Windows-Machine-Learning на сайте GitHub.
Замечание
Используйте следующие ресурсы, чтобы получить помощь по Windows ML.
- Чтобы задать или ответить на технические вопросы о Windows ML, используйте тег windows-machine-learning в Stack Overflow.
- Чтобы сообщить об ошибке, отправьте сообщение о проблеме на сайте GitHub.