0.教学资源

以下是本节课的微课,配合文档学习效果更佳喔。 4.mp4数字识别与机器学习.pptx

1.课前导入

1.1体验数字识别(点这

手机的输入法中有一项是手写输入,我们可以通过手写来输入数字或者文字。这就是图像处理中——数字识别和文字识别的一个运用。
在生活中,数字识别还有很多作用。比如:识别车牌号码,识别银行卡号,识别邮政编码等等……
image.png
图1.数字识别

2.知识准备

2.1该如何识别数字呢?

毕达哥拉斯说过:“万物皆数。”
要做到让计算机识别图像,首先需要将图像转化成数字。

2.2将图像转换成数字

对于一张55像素的图片3(如下图),一共有25个像素点,假设黑色像素用数字0表示,白色像素用数字1表示。
第四课.数字识别与机器学习 - 图3
图2.灰度图像中的灰度信息
那么我们就可以把这张图像用0和1表示出来:01111 00001 00111 00111 01111,至此一张图片成功的变成了一串数字。
我们可以用这串数字组成一个“向量”。向量就相当于空间中的一个点
在二维的平面直角坐标系中,两个坐标确定一个点(x,y);在三维的空间直角坐标系中,三个坐标确定一个点(x,y,z)。
如果在一个25维的坐标系中,把上面的那串数字存储起来。
变成(0,1,1,1,1,0,0,0,0,1,0,0,1,1,1,0,0,1,1,1,0,1,1,1,1)。
那么在这个25维的坐标系中,一个点就代表一个5
5像素的图像,任何5*5像素的图像都可以存储在这个坐标系中。

2.3比较3和7的区别

将图像变化成数字之后,我们比较不同数字的区别会变得容易很多。
第四课.数字识别与机器学习 - 图4
图3.3和7
很明显,对于上面的3和7来说:画面中心的像素也就是第13个像素,第14个像素不同,画面底部的像素也就是第22个像素,第23个像素,第24个像素不同。
但是同样的数字,不同的写法通常只有细微的区别。如下图,不同3的写法在大部分像素上是相同的。
第四课.数字识别与机器学习 - 图5第四课.数字识别与机器学习 - 图6
图4.不同3的写法
所以,当我们把所有不同写法的3和7画在我们的坐标系中的时候,我们发现会“3们”的聚在了一起,和“7们”之间有一条明显的分界线。现在,我们就需要想办法,把这个分界线用计算机找出来,之后计算机就可以轻易的区分3和7了。
image.png
图4.许多3和许多7在空间中

2.4找出分界线——机器学习

这个找出分界线的过程,就是人工智能中的很重要的概念——机器学习。为了简化理解,我画了一个二维直角坐标系。
image.png
图5
假设图5中粉色的点表示“3们”,蓝色的点表示“7们”。这时候,计算机开始“做题”。
题目很简单:数字是3还是7?
一开始的时候,计算机无法判断正确,但是它会根据做题的结果,来画出一条3和7的分割线(分割线上方是3,下方是7),最后慢慢地把3和7分类出来。
image.png
图6
比如根据几轮的试错,计算机画出了这样的分割线——y=5/8x+1(图6)。
这时题目问“点(3,3)是3还是7?”,
计算机想:“根据分割线判断,点(3,3)在上方,所以它是3。”
但是结果是错的,所以计算机这时会把分割线的斜率增加一点,使得点(3,3)在分割线的下方——得到y=3/4x+1(图7)。
image.png
图7
这时,3和7就被分割线完美的分开了,计算机能成功的判断出3和7两个数字。这就是机器学习的大致过程。
(PS:其实机器学习的过程远远没有那么简单,本篇讲的是基本原理。)

3.代码详解

3.1完整代码

在开始编程之前,需要将lenet.network文件存入OpenMV内存中。在工具-机器视觉-CNN模型库中可以找到。
image.png
图8.lenet.network位置

  1. import sensor, image, time, os, nn
  2. sensor.reset() # 初始化摄像头
  3. sensor.set_contrast(3)
  4. sensor.set_pixformat(sensor.GRAYSCALE) # 预处理图像,将其灰度化
  5. sensor.set_framesize(sensor.QVGA) # 设置分辨率为 QVGA (320x240)
  6. sensor.set_windowing((128, 128)) # 将摄像头窗口设置成(128x128)
  7. sensor.skip_frames(time=100)
  8. sensor.set_auto_gain(False)
  9. sensor.set_auto_exposure(False)
  10. net = nn.load('/lenet.network') #加载lenet机器学习模型
  11. labels = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
  12. clock = time.clock() # 创建时钟以监测
  13. while(True):
  14. clock.tick() # 开始计时,更新帧率
  15. img = sensor.snapshot() # 开启摄像头图像
  16. out = net.forward(img.copy().binary([(150, 255)], invert=True)) #输出图像和每一个数字的相似度
  17. max_idx = out.index(max(out))# 把相似度最大的数 赋值给max_idx
  18. score = int(out[max_idx]*100) #将相似度乘以100,赋值给score
  19. if (score > 70):
  20. score_str = "%s:%d%% "%(labels[max_idx], score) #score大于70则输出该数字
  21. else:
  22. score_str = "Not Found" #否则输出NotFound
  23. img.draw_string(0, 0, score_str,(0,0,0)) #在(0,0)处输出分数
  24. print("%s:%d%% "%(labels[max_idx], score))

其中net.forward表示的是将图像中的数字和所有数字进行比较,并输出它们的相似度。我们print一下out就明白了。
image.png
图9.print(out)的结果
在串行终端中,我们发现数组中第三个数是最大的(0.8705882),这表示了“图像是2”的概率。其余的数分别代表,图像是0的概率,图像是1的概率……图像是9的概率。

4.课后任务

课后观看卷积神经网络的视频,了解机器学习和神经网络的构建过程
电脑如何像人一样思考?人工智能(一)机器学习与神经网络
人脸识别啥原理?人工智能(二)卷积神经网络