基于MNIST数据集的手写数字识别应用开发实践

一、基于MNIST数据集的手写数字识别应用开发实践

1、构建项目

①、程序分析:

步骤如下:

  • 一:实现简单的界面,将用户用鼠标或者触屏的输入变成图片。
  • 二:将生成的模型包装起来,成为有公开数据接口的类。 - 三:将输入的图片进行规范化,成为数据接口能够使用的格式。 - 四:最后通过模型来推理(inference)出图片应该是哪个数字,并显示出来。

②、 具体实现:步骤一:获取手写的数字

1、选择文件->新建->项目。在弹出的窗口里选择Visual C#->Windows窗体应用。其中,设计窗口的部分可以使用代码直接完成,代码如下:

    x:Class="MNIST_Demo.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:MNIST_Demo"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d" Width="731.195" Height="496">
    <Grid
        x:Name="parentGrid"
        Margin="40">
        <Grid.RowDefinitions>
            <RowDefinition Height="70" />
            <RowDefinition Height="336" />
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="336" />
            <ColumnDefinition Width="336" />
        </Grid.ColumnDefinitions>


        <TextBlock Text="手写字:"
               FontSize="36"
               VerticalAlignment="Center"
               Grid.Row="0"
               Grid.Column="0" />
        <TextBlock Text="识别结果:"
               FontSize="36"
               VerticalAlignment="Center"
               Grid.Column="1" Margin="0,0,142,0" />
        <Button 
            Name="recognizeButton"
            Content="识别"
            Click="recognizeButton_Click"
            FontSize="26"
            Grid.Column="1" 
            Grid.Row="1" 
            Height="75" 
            Width="150"
            Margin="85,168,0,0" 
            VerticalAlignment="Top"/>
        <Button 
            Name="clearButton"
            Content="清理"
            Click="clearButton_Click"
            FontSize="26"
            Grid.Column="1" 
            Grid.Row="1" 
            Height="75" 
            Width="150"
            Margin="85,261,0,0" 
            VerticalAlignment="Top"/>
        <TextBlock Name="numberLabel"
            FontSize="100" 
            Grid.Column="1" 
            Margin="60,0,100,192"
            Text="" VerticalAlignment="Bottom" Grid.Row="1" SelectionChanged="NumberLabel_SelectionChanged"/>
        <Border BorderThickness="4"
            BorderBrush="Silver"
            Margin="0,0,0,0"
            Grid.Row="1"
            Grid.Column="0"/>



        <Grid Name="inkGrid" 
            Background="PowderBlue"            Grid.Row="1"
            Grid.Column="0">
            <InkCanvas 
                    Name="inkCanvas"
                    Height="336" 
                    Width="336"/>
        </Grid>
    </Grid>
</Page>

③、添加模型

右键单击解决方案资源管理器中的Assets文件夹,然后选择“ 添加” >“ 现有项”。将文件选择器指向ONNX模型的位置,然后单击添加。该项目现在应该有两个新文件: mnist.onnx-训练的模型,mnist.cs -Windows ML生成的代码。

- mnist.cs文件中新生成的代码。 我们分为三类:

  • mnistModel创建机器学习模型表示,在系统默认设备上创建会话,将特定的输入和输出绑定到模型,并异步评估模型。
    • mnistInput初始化模型期望的输入类型。在这种情况下,输入需要一个ImageFeatureValue。
    • mnistOutput初始化模型将输出的类型。在这种情况下,输出将是TensorFloat类型的名为Plus214_Output_0的列表。## ④、加载,绑定和评估模型### a、对于Windows ML应用程序,我们要遵循的模式是:“加载”>“绑定”>“求值”。加载机器学习模型。 将输入和输出绑定到模型。 评估模型并查看结果。 我们将使用mnist.cs中生成的接口代码来加载,绑定和评估应用程序中的模型。首先,在MainPage.xaml.cs中,我们实例化模型,输入和输出。将以下成员变量添加到MainPage类:
- private mnistModel ModelGen;private mnistInput ModelInput = new mnistInput();private mnistOutput ModelOutput;
  • b、在LoadModelAsync中,我们将加载模型。

  • 我们使用任何模型的方法(也就是之前这个方法应该叫的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);}
  • c、我们要将输入和输出绑定到模型。

  • 生成的代码还包括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```C++private void clearButton_Click(object sender, RoutedEventArgs e){    inkCanvas.InkPresenter.StrokeContainer.Clear();    numberLabel.Text = "";}
    ```
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值