【机器学习】人人都可以做深度学习应用:入门篇(中)识别手写数字(MNIST)
发布日期:2021-06-29 14:29:43 浏览次数:3 分类:技术文章

本文共 5970 字,大约阅读时间需要 19 分钟。

本文承接上篇文章人人都可以做深度学习应用:入门篇(上),在本文会总结深度学习环境的搭建以及一个经典的demo:识别手写数字(MNIST)。

文章目录

学习心得

在几个月前,人工智能对我来说,只是一个高大上的概念。但是,经过一个多月的业余时间的认真学习,我发现还是能够学到一些东西,并且跑一些demo和应用出来的,下面是我的一个学习过程和总结。

1. 学习的提前准备

(1)部分数学内容的复习,高中数学、概率、线性代数等部分内容。(累计花费了10个小时,,挑了关键的点看了下,其实还是不太够,只能让自己看公式的时候,相对没有那么懵)

(2)Python基础语法学习。(花费了3个小时左右,我以前从未写过Python,因为后面Google的TensorFlow框架的使用是基于Python的)

(3)Google的TensorFlow深度学习开源框架。(花费了10多个小时去看)

数学基础好或者前期先不关注原理的同学,数学部分不看也可以开始做,全凭个人选择。

2. Google的TensorFlow开源深度学习框架

深度学习框架,我们可以粗略的理解为是一个“数学函数”集合和AI训练学习的执行框架。通过它,我们能够更好的将AI的模型运行和维护起来。

深度学习的框架有各种各样的版本(Caffe、Torch、Theano等等),我只接触了Google的TensorFlow,因此,后面的内容都是基于TensorFlow展开的,它的详细介绍这里不展开讲述,建议直接进入官网查看。非常令人庆幸的是TensorFlow比较早就有中文社区了,尽管里面的内容有一点老,搭建环境方面有一些坑,但是已经属于为数不多的中文文档了,大家且看且珍惜。下面是地址:

TensorFlow的中文社区:http://www.tensorfly.cn/TensorFlow的英文社区:https://www.tensorflow.org/

TensorFlow环境搭建

环境搭建本身并不复杂,主要解决相关的依赖。但是,基础库的依赖可以带来很多问题,因此,建议尽量一步到位,会简单很多。

1. 操作系统

我搭建环境使用的机器是腾讯云上的机器,软件环境如下:操作系统:CentOS 7.2 64位(GCC 4.8.5)

因为这个框架依赖于python2.7和glibc 2.17。比较旧的版本的CentOS一般都是python2.6以及版本比较低的glibc,会产生比较的多基础库依赖问题。而且,glibc作为Linux的底层库,牵一发动全身,直接对它升级是比较复杂,很可能会带来更多的环境异常问题。

2. 软件环境

我目前安装的Python版本是python-2.7.5,建议可以采用yum install python的方式安装相关的原来软件。然后,再安装 python内的组件包管理器pip,安装好pip之后,接下来的其他软件的安装就相对比较简单了。

例如安装TensorFlow,可通过如下一句命令完成(它会自动帮忙解决一些库依赖问题):pip install -U tensorflow

这里需要特别注意的是,不要按照TensorFlow的中文社区的指引去安装,因为它会安装一个非常老的版本(0.5.0),用这个版本跑很多demo都会遇到问题的。而实际上,目前通过上述提供的命令安装,是tensorflow (1.0.0)的版本了。

在这里插入图片描述

Python(2.7.5)下的其他需要安装的关键组件:

(1)  tensorflow (0.12.1),深度学习的核心框架(2) image (1.5.5),图像处理相关,部分例子会用到(3)PIL (1.1.7),图像处理相关,部分例子会用到

除此之后,当然还有另外的一些依赖组件,通过pip list命令可以查看我们安装的python组件:

在这里插入图片描述

按照上述提供的来搭建系统,可以规避不少的环境问题。

搭建环境的过程中,我遇到不少问题。例如:在跑官方的例子时的某个报,AttributeError: ‘module’ object has no attribute ‘gfile’,就是因为安装的TensorFlow的版本比较老,缺少gfile模块导致的。而且,还有各种各样的。

更详细的安装说明:https://www.tensorflow.org/install/install_linux

3. TensorFlow环境测试运行

测试是否安装成功,可以采用官方的提供的一个短小的例子,demo生成了一些三维数据, 然后用一个平面拟合它们(官网的例子采用的初始化变量的函数是initialize_all_variables,该函数在新版本里已经被废弃了):

在这里插入图片描述

运行的结果类似如下:

在这里插入图片描述

经过200次的训练,模型的参数逐渐逼近最佳拟合的结果(W: [[0.100 0.200]], b: [0.300]),另外,我们也可以从代码的“风格”中,了解到框架样本训练的基本运行方式。虽然,官方的教程后续会涉及越来越多更复杂的例子,但从整体上看,也是类似的模式。

在这里插入图片描述

步骤划分:

(1)  准备数据:获得有标签的样本数据(带标签的训练数据称为有监督学习);(2) 设置模型:先构建好需要使用的训练模型,可供选择的机器学习方法其实也挺多的,换而言之就是一堆数学函数的集合;(3)损失函数和优化方式:衡量模型计算结果和真实标签值的差距;(4)真实训练运算:训练之前构造好的模型,让程序通过循环训练和学习,获得最终我们需要的结果“参数”;(5)验证结果:采用之前模型没有训练过的测试集数据,去验证模型的准确率。

其中,TensorFlow为了基于python实现高效的数学计算,通常会使用到一些基础的函数库,例如Numpy(采用外部底层语言实现),但是,从外部计算切回到python也是存在开销的,尤其是在几万几十万次的训练过程。因此,Tensorflow不单独地运行单一的函数计算,而是先用图描述一系列可交互的计算操作流程,然后全部一次性提交到外部运行(在其他机器学习的库里,也是类似的实现)。所以,上述流程图中,蓝色部分都只是设置了“计算操作流程”,而绿色部分开始才是真正的提交数据给到底层库进行实际运算,而且,每次训练一般是批量执行一批数据的。

经典入门demo:识别手写数字(MNIST)

常规的编程入门有“Hello world”程序,而深度学习的入门程序则是MNIST,一个识别28*28像素的图片中的手写数字的程序。

在这里插入图片描述

MNIST的数据和官网:MNIST handwritten digit database, Yann LeCun, Corinna Cortes and Chris Burges

深度学习的内容,其背后会涉及比较多的数学原理,作为一个初学者,受限于我个人的数学和技术水平,也许并不足以准确讲述相关的数学原理,因此,本文会更多的关注“应用层面”,不对背后的数学原理进行展开,感谢谅解。

1. 加载数据

程序执行的第一步当然是加载数据,根据我们之前获得的数据集主要包括两部分:60000的训练数据集(mnist.train)和10000的测试数据集(mnist.test)。里面每一行,是一个2828=784的数组,数组的本质就是将2828像素的图片,转化成对应的像素点阵。

例如手写字1的图片转换出来的对应矩阵表示如下:

在这里插入图片描述

之前我们经常听说,图片方面的深度学习需要大量的计算能力,甚至需要采用昂贵、专业的GPU(Nvidia的GPU),从上述转化的案例我们就已经可以获得一些答案了。一张784像素的图片,对学习模型来说,就有784个特征,而我们实际的相片和图片动辄几十万、百万级别,则对应的基础特征数也是这个数量级,基于这样数量级的数组进行大规模运算,没有强大的计算能力支持,确实寸步难行。当然,这个入门的MNIST的demo还是可以比较快速的跑完。

Demo中的关键代码(读取并且加载数据到数组对象中,方便后面使用):

在这里插入图片描述

2. 构建模型

MNIST的每一张图片都表示一个数字,从0到9。而模型最终期望获得的是:给定一张图片,获得代表每个数字的概率。比如说,模型可能推测一张数字9的图片代表数字9的概率是80%但是判断它是8的概率是5%(因为8和9都有上半部分的小圆),然后给予它代表其他数字的概率更小的值。

在这里插入图片描述

MNIST的入门例子,采用的是softmax回归(softmax regression),softmax模型可以用来给不同的对象分配概率。

为了得到一张给定图片属于某个特定数字类的证据(evidence),我们对图片的784个特征(点阵里的各个像素值)进行加权求和。如果某个特征(像素值)具有很强的证据说明这张图片不属于该类,那么相应的权重值为负数,相反如果某个特征(像素值)拥有有利的证据支持这张图片属于这个类,那么权重值是正数。类似前面提到的房价估算例子,对每一个像素点作出了一个权重分配。

假设我们获得一张图片,需要计算它是8的概率,转化成数学公式则如下:

在这里插入图片描述

公式中的i代表需要预测的数字(8),代表预测数字为8的情况下,784个特征的不同权重值,代表8的偏置量(bias),X则是该图片784个特征的值。通过上述计算,我们则可以获得证明该图片是8的证据(evidence)的总和,softmax函数可以把这些证据转换成概率 y。(softmax的数学原理,辛苦各位查询相关资料哈)

将前面的过程概括成一张图(来自官方)则如下:

在这里插入图片描述

不同的特征x和对应不同数字的权重进行相乘和求和,则获得在各个数字的分布概率,取概率最大的值,则认为是我们的图片预测结果。

将上述过程写成一个等式,则如下:

在这里插入图片描述

该等式在矩阵乘法里可以非常简单地表示,则等价为:

在这里插入图片描述

不展开里面的具体数值,则可以简化为:

在这里插入图片描述

如果我们对线性代数中矩阵相关内容有适当学习,其实,就会明白矩阵表达在一些问题上,更易于理解。如果对矩阵内容不太记得了,也没有关系,后面我会附加上线性代数的视频

虽然前面讲述了这么多,其实关键代码就四行:

在这里插入图片描述

上述代码都是类似变量占位符,先设置好模型计算方式,在真实训练流程中,需要批量读取源数据,不断给它们填充数据,模型计算才会真实跑起来。tf.zeros则表示,先给它们统一赋值为0占位。X数据是从数据文件中读取的,而w、b是在训练过程中不断变化和更新的,y则是基于前面的数据进行计算得到。

3. 损失函数和优化设置

为了训练我们的模型,我们首先需要定义一个指标来衡量这个模型是好还是坏。这个指标称为成本(cost)或损失(loss),然后尽量最小化这个指标。简单的说,就是我们需要最小化loss的值,loss的值越小,则我们的模型越逼近标签的真实结果。

Demo中使用的损失函数是“交叉熵”(cross-entropy),它的公式如下:

在这里插入图片描述

y 是我们预测的概率分布, y’ 是实际的分布(我们输入的),交叉熵是用来衡量我们的预测结果的不准确性。TensorFlow拥有一张描述各个计算单元的图,也就是整个模型的计算流程,它可以自动地使用反向传播算法(backpropagation algorithm),来确定我们的权重等变量是如何影响我们想要最小化的那个loss值的。然后,TensorFlow会用我们设定好的优化算法来不断修改变量以降低loss值。

其中,demo采用梯度下降算法(gradient descent algorithm)以0.01的学习速率最小化交叉熵。梯度下降算法是一个简单的学习过程,TensorFlow只需将每个变量一点点地往使loss值不断降低的方向更新。

对应的关键代码如下:

在这里插入图片描述

备注内容:

交叉熵:Visual Information Theory

反向传播:Calculus on Computational Graphs: Backpropagation

在代码中会看见one-hot vector的概念和变量名,其实这个是个非常简单的东西,就是设置一个10个元素的数组,其中只有一个是1,其他都是0,以此表示数字的标签结果。例如表示数字3的标签值:[0,0,0,1,0,0,0,0,0,0]

4. 训练运算和模型准确度测试

通过前面的实现,我们已经设置好了整个模型的计算“流程图”,它们都成为TensorFlow框架的一部分。于是,我们就可以启动我们的训练程序,下面的代码的含义是,循环训练我们的模型500次,每次批量取50个训练样本。

在这里插入图片描述

其训练过程,其实就是TensorFlow框架的启动训练过程,在这个过程中,python批量地将数据交给底层库进行处理。

我在官方的demo里追加了两行代码,每隔50次则额外计算一次当前模型的识别准确率。它并非必要的代码,仅仅用于方便观察整个模型的识别准确率逐步变化的过程。

在这里插入图片描述

当然,里面涉及的accuracy(预测准确率)等变量,需要在前面的地方定义占位:

在这里插入图片描述

当我们训练完毕,则到了验证我们的模型准确率的时候,和前面相同:

在这里插入图片描述

我的demo跑出来的结果如下(softmax回归的例子运行速度还是比较快的),当前的准确率是0.9252:

在这里插入图片描述

5. 实时查看参数的数值的方法

刚开始跑官方的demo的时候,我们总想将相关变量的值打印出来看看,是怎样一种格式和状态。从demo的代码中,我们可以看见很多的Tensor变量对象,而实际上这些变量对象都是无法直接输出查看,粗略地理解,有些只是占位符,直接输出的话,会获得类似如下的一个对象:

在这里插入图片描述

既然它是占位符,那么我们就必须喂一些数据给它,它才能将真实内容展示出来。因此,正确的方法是,在打印时通常需要加上当前的输入数据给它。

例如,查看y的概率数据:

在这里插入图片描述

部分非占位符的变量还可以这样输出来:

在这里插入图片描述

总的来说,92%的识别准确率是比较令人失望,因此,官方的MNIST其实也有多种模型的不同版本,其中比较适合图片处理的CNN(卷积神经网络)的版本,可以获得99%以上的准确率,当然,它的执行耗时也是比较长的。

(备注:cnn_mnist.py就是卷积神经网络版本的,后面有附带的下载url,在环境已经搭建完毕的情况下,执行里面的run.py即可)

前馈神经网络(feed-forward neural network)版本的MNIST,可达到97%

在这里插入图片描述

这篇文章到这里,在下篇文章中我们会讲一个和业务场景结合的demo:预测用户是否是QQ超级会员身份

cnn_mnist.py下载地址:https://github.com/wlmnzf/tensorflow-train/blob/master/mnist/cnn_mnist.py

学如逆水行舟,不进则退

转载地址:https://chocolate.blog.csdn.net/article/details/104165471 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:【机器学习】人人都可以做深度学习应用:入门篇(下)CIFAR-10识别图片分类
下一篇:【机器学习】人人都可以做深度学习应用:入门篇(上)深度学习技术

发表评论

最新留言

网站不错 人气很旺了 加油
[***.192.178.218]2024年04月04日 18时30分19秒