0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

通过一些简单的应用实践对AI应用有更深入的了解

8g3K_AI_Thinker 来源:未知 作者:李倩 2018-06-25 15:24 次阅读

又是一个很有热度的周末,除了炎热的天气,还有火热的世界杯。今天人工智能头条为大家准备的技术干货,让大家可以在空调下,吃瓜看球两不耽误就可以轻松完成AI应用实践入门。多少次,在我们查找很多资源、技术指导后,实操时还是会被一个报错而终止了前进的道路。小编也曾经历过这样的心路历程,所以一份好的指南对于刚开始实践操作的同学来说简直太有爱了,不仅节约了很多时间,操作和思路也都是清晰的。如果你是刚入门的AI小白,想通过一些简单的应用实践对AI应用有更深入的了解,现在就开始和我们一起开始吧!

作者简介:邹欣,现任微软亚洲研究院研发经理,负责必应搜索客户端、必应输入法、必应词典、微软小娜等产品。曾出版《移山之道》、《编辑之美》(合作)、《构建之法》三部书籍。

下面为大家介绍邹欣老师的AI应用开发实践系列教程之手写识别应用入门,本次教程学习主要分三步:

从零开始搭建你的开发环境,无论是Windows 还是 MAC OS 环境

简单的 MNIST 模型训练

入门手写体识别应用实践

这波操作大家放心可以轻松完成,教程中不仅介绍了每步需要做什么,还为你准备了有参考价值的命令行、代码、各安装软件版本号的明确说明、需要下载或者访问的链接以及截图和教程视频,可以说非常全面、到位了。

▌为你的 Windows 搭建开发环境并开始训练第一个模型

(1)准备工作:一台能联网的电脑,使用 win10 64 位操作系统,请确保鼠标、键盘、显示器都是好的

(2)安装步骤:

安装 Git

安装 VS,等待时间看网络状况,没准可以看半场球反正不用担心不用着急。

安装 python

安装 CUDA 和 cuDNN:这是教程中最繁琐的一步,这一步直接拉高教程的平均难度。

配置机器学习环境:这是教程中最简单的一步,为了方便用户配置环境,微软提供了一键安装工具!简直业界良心!

安装 VS Tools For AI插件

(3)离线模型的训练:注意在此过程中使用最新的 mnist.py 文件

文章链接:

https://blog.csdn.net/softwareteacher/article/details/80770079

▌为你的 MAC OS 搭建开发环境并开始训练第一个模型

(1)准备工作:一台能联网的电脑,使用 MAC OS 操作系统,请确保鼠标、键盘、显示器都是好的

(2)安装步骤:

安装 VS,同样时间长的小伙伴们不妨考虑去看半场球啊!

安装 python

安装 Tools for AI 插件

安装 Git

下载机器学习示例库

(3)模型训练:也是小编的第一个模型!在教程中孩子特别补充讲解了如何在远程 Linux 上进行训练。

文章链接:

https://blog.csdn.net/softwareteacher/article/details/80770239

▌AI应用开发实践—手写识别应用入门

敲重点!!!环境搭建和模型训练都搞定后,接下来终于可以上手应用实践了,以下为手写识别应用教程全文,enjoy!

手写体识别的应用已经非常流行了,如输入法,图片中的文字识别等。但对于大多数开发人员来说,如何实现这样的一个应用,还是会感觉无从下手。本文从简单的 MNIST 训练出来的模型开始,和大家一起入门手写体识别。

在本教程结束后,会得到一个能用的 AI应用,也许是你的第一个AI应用。虽然离实际使用还有较大的距离(具体差距在文章后面会分析),但会让你对AI应用有一个初步的认识,有能力逐步搭建出能够实际应用的模型。

原文链接:

https://blog.csdn.net/softwareteacher/article/details/80770347

▌准备工作

使用 win10 64 位操作系统的计算机

参考上一篇博客 AI应用开发实战 - 从零开始配置环境。在电脑上训练并导出 MNIST 模型。

▌一. 思路

通过上一篇文章搭建环境的介绍后,就能得到一个能识别单个手写数字的模型了,并且识别的准确度会在 98%,甚至 99% 以上了。那么我们要怎么使用这个模型来搭建应用呢?

大致的步骤如下:

实现简单的界面,将用户用鼠标或者触屏的输入变成图片。

将生成的模型包装起来,成为有公开数据接口的类。

将输入的图片进行规范化,成为数据接口能够使用的格式。

最后通过模型来推理 (inference) 出图片应该是哪个数字,并显示出来。

是不是很简单?

▌二.动手

步骤一:获取手写的数字

提问:那我们要怎么获取手写的数字呢?

回答:我们可以写一个简单的 WinForm 画图程序,让我们可以用鼠标手写数字,然后把图片保存下来。

首先,我们打开 Visual Studio,选择文件->新建->项目。

在弹出的窗口里选择 Visual C#->Windows窗体应用,项目名称不妨叫做 DrawDigit,解决方案名称不妨叫做 MnistForm,点击确定。

此时,Visual Studio 也自动弹出了一个窗口的设计图。

在 DrawDigit 项目上点击右键,选择属性,在生成一栏将平台目标从 Any CPU 改为 x 64。

否则,DrawDigit(首选32位)与它引用的 MnistForm(64位)的编译平台不一致会引发 System.BadImageFormatException 的异常。

然后我们对这个窗口做一些简单的修改:

首先我们打开 VS 窗口左侧的工具箱,这个窗口程序需要以下三种组件:

1. PictureBox:用来手写数字,并且把数字保存成图片

2. Label:用来显示模型的识别结果

3. Button:用来清理PictureBox的手写结果

那经过一些简单的选择与拖动还有调整大小,这个窗口现在是这样的:

一些注意事项

这些组件都可以通过右键->查看属性,在属性里修改它们的设置

为了方便把 PictureBox 里的图片转化成 Mnist 能识别的格式,PictureBox 的需要是正方形

可以给这些控件起上有意义的名称。

可以调整一下 label 控件大小、字体等,让它更美观。

经过一些简单的调整,这个窗口现在是这样的:

现在来让我们愉快地给这些组件添加事件!

还是在属性窗口,我们选择某个组件,右键->查看属性,点击闪电符号,给组件绑定对应的事件。每次绑定后,会跳到代码部分,生成一个空函数。点回设计视图继续操作即可。

组件类型 事件
pictureBox1 在Mouse下双击MouseDown、MouseUp、MouseMove来生成对应的响应事件函数。
button1 如上,在Action下双击Click。
Form1 如上,在Behavior下双击Load

然后我们开始补全对应的函数体内容。

注意,如果在上面改变了控件的名称,下面的代码需要做对应的更改。

废话少说上代码!

usingSystem;usingSystem.Collections.Generic;usingSystem.ComponentModel;usingSystem.Data;usingSystem.Drawing;usingSystem.Drawing.Drawing2D;//用于优化绘制的结果usingSystem.Linq;usingSystem.Text;usingSystem.Threading.Tasks;usingSystem.Windows.Forms;usingMnistModel;namespaceDrawDigit{publicpartialclassForm1:Form{publicForm1(){InitializeComponent();}privateBitmapdigitImage;//用来保存手写数字privatePointstartPoint;//用于绘制线段,作为线段的初始端点坐标privateMnistmodel;//用于识别手写数字privateconstintMnistImageSize=28;//Mnist模型所需的输入图片大小privatevoidForm1_Load(objectsender,EventArgse){//当窗口加载时,绘制一个白色方框model=newMnist();digitImage=newBitmap(pictureBox1.Width,pictureBox1.Height);Graphicsg=Graphics.FromImage(digitImage);g.Clear(Color.White);pictureBox1.Image=digitImage;}privatevoidclean_click(objectsender,EventArgse){//当点击清除时,重新绘制一个白色方框,同时清除label1显示的文本digitImage=newBitmap(pictureBox1.Width,pictureBox1.Height);Graphicsg=Graphics.FromImage(digitImage);g.Clear(Color.White);pictureBox1.Image=digitImage;label1.Text="";}privatevoidpictureBox1_MouseDown(objectsender,MouseEventArgse){//当鼠标左键被按下时,记录下需要绘制的线段的起始坐标startPoint=(e.Button==MouseButtons.Left)?e.Location:startPoint;}privatevoidpictureBox1_MouseMove(objectsender,MouseEventArgse){//当鼠标在移动,且当前处于绘制状态时,根据鼠标的实时位置与记录的起始坐标绘制线段,同时更新需要绘制的线段的起始坐标if(e.Button==MouseButtons.Left){Graphicsg=Graphics.FromImage(digitImage);PenmyPen=newPen(Color.Black,40);myPen.StartCap=LineCap.Round;myPen.EndCap=LineCap.Round;g.DrawLine(myPen,startPoint,e.Location);pictureBox1.Image=digitImage;g.Dispose();startPoint=e.Location;}}privatevoidpictureBox1_MouseUp(objectsender,MouseEventArgse){//当鼠标左键释放时//同时开始处理图片进行推理//暂时不处理这里的代码}}}

步骤二:把模型包装成一个类

将模型包装成一个 C# 是整个过程中比较麻烦的一步。所幸的是,Tools for AI 对此提供了很好的支持。进一步了解,可以看这里(https://github.com/Microsoft/vs-tools-for-ai/blob/master/docs/zh-hans/docs/model-inference.md)。

首先,我们在解决方案 MnistForm 下点击鼠标右键,选择添加->新建项目,在弹出的窗口里选择 AI Tools->Inference->模型推理类库,名称不妨叫做 MnistModel,点击确定,于是我们又多了一个项目。

然后自己配置好这个项目的名称、位置,点击确定。

然后弹出一个模型推理类库创建向导,这个时候就需要我们选择自己之前训练好的模型了~

首先在模型路径里选择保存的模型文件的路径。这里我们使用在AI应用开发实战 - 从零开始配置环境博客中训练并导出的模型

note:模型可在 /samples-for-ai/examples/tensorflow/MNIST 目录下找到,其中 output 文件夹保存了检查点文件,export 文件夹保存了模型文件。

对于TensorFlow,我们可以选择检查点的 .meta 文件,或者是保存的模型的 .pb 文件

这里我们选择在AI应用开发实战 - 从零开始配置环境这篇博客最后生成的 export 目录下的检查点的 SavedModel.pb 文件,这时程序将自动配置好配置推理接口,见下图:

类名可以自己定义,因为我们用的是 MNIST,那么类名就叫 Mnist 好了,然后点击确定。

这样,在解决方案资源管理器里,在解决方案 MnistForm 下,就多了一个 MnistModel:

双击 Mnist.cs,我们可以看到项目自动把模型进行了封装,生成了一个公开的 infer 函数。

然后我们在 MnistModel 上右击,再选择生成,等待一会,这个项目就可以使用了~

步骤三:连接两个部分

这一步差不多就是这么个感觉:

I have an apple , I have a pen. AH~ , Applepen

首先,我们来给 DrawDigit 添加引用,让它能使用 MnistModel。在 DrawDigit 项目的引用上点击鼠标右键,点击添加引用,在弹出的窗口中选择 MnistModel,点击确定。

然后,由于 MNIST 的模型的输入是一个 28×28 的白字黑底的灰度图,因此我们首先要对图片进行一些处理。

首先将图片转为 28×28 的大小。

然后将 RGB 图片转化为灰阶图,将灰阶标准化到 [-0.5,0.5] 区间内,转换为黑底白字。

最后将图片用 mnist 模型要求的格式包装起来,并传送给它进行推理。

于是,我们在 pictureBox1_MouseUp 中添加上这些代码,并且在文件最初添加上 using MnistModel;:

privatevoidpictureBox1_MouseUp(objectsender,MouseEventArgse){//当鼠标左键释放时//开始处理图片进行推理if(e.Button==MouseButtons.Left){BitmapdigitTmp=(Bitmap)digitImage.Clone();//复制digitImage//调整图片大小为Mnist模型可接收的大小:28×28using(Graphicsg=Graphics.FromImage(digitTmp)){g.InterpolationMode=InterpolationMode.HighQualityBicubic;g.DrawImage(digitTmp,0,0,MnistImageSize,MnistImageSize);}//将图片转为灰阶图,并将图片的像素信息保存在list中varimage=newList(MnistImageSize*MnistImageSize);for(varx=0;x< MnistImageSize; x++)                {                    for (var y = 0; y < MnistImageSize; y++)                    {                        var color = digitTmp.GetPixel(y, x);                        var a = (float)(0.5 - (color.R + color.G + color.B) / (3.0 * 255));                        image.Add(a);                    }                }                //将图片信息包装为mnist模型规定的输入格式                var batch = new List>();batch.Add(image);//将图片传送给mnist模型进行推理varresult=model.Infer(batch);//将推理结果输出label1.Text=result.First().First().ToString();}}

最后让我们尝试一下运行~

▌三.效果展示

现在我们就有了一个简单的小程序,可以识别手写的数字了。

赶紧试试效果怎么样~

▌注意

1.路径中不能有中文字符,否则可能找不到模型。

▌进阶

那么,如果要识别多个连写的数字,或支持字母该怎么做呢?大家多用用也会发现,如果数字写得很小,或者没写到正中,识别起来正确率也会不高。要解决这些问题,做成真正的产品,就不止这一个模型了。比如在多个数字识别中,可能要根据经验来切分图,或者训练另一个模型来检测并分割数字。要支持字母,则需要重新训练一个包含手写字母的模型,并准备更多的字母的数据。要解决字太小的问题,还要检测一下字的大小,做合适的放大等等。

我们可以看到,一个训练出来的模型本身到一个实际的应用之间还有不少的功能要实现。希望我们这一系列的介绍,能够帮助大家将机器学习的概念带入到传统的编程领域中,做出更聪明的产品。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • WINDOWS
    +关注

    关注

    3

    文章

    3438

    浏览量

    87140
  • AI
    AI
    +关注

    关注

    87

    文章

    26407

    浏览量

    264011
  • 机器学习
    +关注

    关注

    66

    文章

    8112

    浏览量

    130543

原文标题:一边吃瓜看球,一边完成AI应用实践——手写体识别入门

文章出处:【微信号:AI_Thinker,微信公众号:人工智能头条】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    一些简单资料

    一些简单资料,共享,希望大家共同进步!
    发表于 11-24 09:40

    学习嵌入式的一些心得!

    系统,对I/O口、串行通信、键盘、LED、LCD、SPI、I2C、PWM、A/D(包括一些传感器)、D/A等逐个实验理解,逐步实践。再通过自己做个实际的小系统,底层硬件基础就有了。各
    发表于 02-02 09:35

    一些简单的ARM资料

    一些简单的!!!!!!!!!...
    发表于 03-01 22:34

    求介绍一些简单的项目

    学51单片机已经个多月,简单的操作感觉还好。 想找一些简单的项目做下,在项目中学习,求介绍一些
    发表于 08-18 12:35

    FPGA的一些简单设计资料

    FPGA的一些简单设计资料
    发表于 06-10 11:04

    一些简单、实用的Protel元器件

    一些简单、实用的Protel元器件
    发表于 05-07 09:41

    了解labVIEW系统级的一些编程

    各位学友老师好:我想了解一些系统级的编程方法。最近我做了一些小模块的vi,现在我要把所有的模块vi组合到个大型的程序中。期间发觉自己不知道该学习什么了。以前学的都是
    发表于 09-21 09:17

    了解AI人工智能背后的科学?

    时间。 而且保留优质AI人才也是非常昂贵的。混合方法您可以采用混合方式,与您提供特定解决方案的公司合作,并随着时间的推移聘请AI专家。 如果您希望开始测试业务中的AI,进行一些
    发表于 09-25 10:03

    嵌入式开发中的一些硬件相关的概念哪些

    做嵌入式系统开发,经常要接触硬件。做嵌入式开发对数字电路和模拟电路要有定的了解。这样才能深入的研究下去。下面我们简单的介绍嵌入式开发中的一些
    发表于 02-24 08:56

    了解MOSFET的一些原理

    电机的驱动,如下图1所示,要做好驱动电路,必须得了解清楚MOSFET的一些原理,才不会出错。图1 H桥全桥驱
    发表于 09-13 08:14

    介绍PMIC硬件电路相关的一些知识

    PMIC 电源管理集成电路(Power Management IC)在之前项目中,驱动最小系统,对于PMIC这块儿很懵懂,故抽时间查看一些优秀博文及资料,加强对电源管理的理解。本文介绍 PMIC 硬件电路相关的一些知识,在此作一些
    发表于 11-17 07:24

    介绍一些MOV与ADD指令的简单例子

    因为嵌入式系统学习需要,开始学习汇编语言学习资料是B站的视频:汇编语言程序 P9目录一些简单的指令例子二、个练习
    发表于 01-07 06:39

    关于stm32的一些简单的介绍

    #序言本文章是关于stm的一些简单的介绍,全部都是个人学习的一些经验总结,分享给想要自学stm32的朋友们用于入门。其中部分内容借鉴于《stm32中文参考手册》和《cortex-m3权威指南》,对于
    发表于 02-24 06:30

    《RISC-V体系结构编程与实践》试读

    和应用。作者使用简洁明了的语言和图表,使得复杂的概念和原理变得易于理解,使读者能够快速掌握RISC-V的基本原理和指令集。书中提供了大量的实践案例和代码示例,让读者能够通过实践深入了解RISC-V
    发表于 04-03 15:15

    贝叶斯统计的一个实践案例让你更快的对贝叶斯算法有更多的了解

    为了大家可以对贝叶斯算法有更多的了解,为大家整理过一篇关于贝叶斯算法的文章。今天将为大家介绍利用贝叶斯统计的一个实践案例。通项目实践达到学以致用的目的,相信大家对贝叶斯统计的理解和掌握都可以
    的头像 发表于 07-16 17:15 1.4w次阅读