13865247895
网站首页 关于我们
技术认证
产品中心
成功案例
新闻动态
在线留言
联系我们

新闻动态

人人都可以学的人工智能:TensorFlow 入门例子

发布时间:2019-07-31

  这是用 TensorFlow 来识别手写数字的官方经典入门例子,数据都是已经处理过准备好了的,但是只到计算准确度概率那就停了,缺少拿实际图片运用的例子,初学者看完之后难免发蒙。于是,本文第二段用一些实际图片来验证我们的模型。文中例子基于 TensorFlow 1.0.0,看过官方文档的直接跳到后面吧。

  第一部分,介绍了一些处理数据的基本知识,然后采用一个简单的模型,用一堆准确的数据去训练它,训练完之后拿另一堆数据去评估一下这个模型的准确率(这也是官方例子的内容)。搞清楚这个很重要,不然看完官方例子只会觉得很厉害,但是又不知道哪厉害。

  第二部分,我们会拿几个图片,告诉模型我们认为这个图片是几(当然,这个是随便说的),然后模型告诉我们它觉得的和我们认为的是否一致。

  因为这个例子是 TensorFlow 官方的例子,不会说的太详细,会加入了一点个人的理解,英文文档是最新的,中文文档是用 0.5 版本的 TensorFlow,在 1.0 版本跑不起来,建议中文文档和英文文档交叉着看,有助于理解。

  

  这里用来识别的手写图片大致是这样的,环亚娱乐平台,为了降低复杂度,每个图片是 28*28 大小。

  但是直接丢图片给我们的模型,模型是不认识的,所以必须要对图片进行一些处理。

  如果了解线性代数,大概知道图片的每个像素点其实可以表示为一个二维的矩阵,对图片做各种变换,比如翻转啊什么的就是对这个矩阵进行运算,于是我们的手写图片大概可以看成是这样的:

  这个矩阵展开成一个向量,长度是 28*28=784。我们还需要另一个东西用来告诉模型我们认为这个图片是几,也就是给图片打个 label。这个 label 也不是随便打的,这里用一个类似有 10 个元素的数组,其中只有一个是 1,其它都是 0,哪位为 1 表示对应的图片是几,例如表示数字 8 的标签值就是 ([0,0,0,0,0,0,0,0,1,0])。

  这些就是单张图片的数据处理,实际上为了高效的训练模型,会把图片数据和 label 数据分别打包到一起,也就是 MNIST 数据集了。

  MNIST 数据集是一个入门级的计算机视觉数据集,官网是Yann LeCuns website。 我们不需要手动去下载这个数据集, 1.0 的 TensorFlow 会自动下载。

  这个训练数据集有 55000 个图片数据,用张量的方式组织的,形状如 [55000,784],如下图:

  这个数据集里面除了有训练用的数据之外,还有 10000 个测试模型准确度的数据。

  Softmax 中文名叫归一化指数函数,这个模型可以用来给不同的对象分配概率。比如判断

  的时候可能认为有 80% 是 9,有 5% 认为可能是 8,因为上面都有个圈。

  我们对图片像素值进行加权求和。比如某个像素具有很强的证据说明这个图不是 1,则这个像素相应的权值为负数,相反,如果这个像素特别有利,则权值为正数。

  Softmax 回归模型的原理大概就是这样,更多的推导过程,可以查阅一下官方文档,有比较详细的内容。

  具体引入的一些包这里就不一一列出来,主要是两个,一个是 tensorflow 本身,另一个是官方例子里面用来输入数据用的方法。

  x 是从图片数据文件里面读来的,理解为一个常量,一个输入值,因为是 28*28 的图片,所以这里是 784;

  W 代表权重,因为有 784 个点,然后有 10 个数字的权重,所以是 [784, 10],模型运算过程中会不断调整这个值,可以理解为一个变量;

  b 代表偏置量,每个数字的偏置量都不同,所以这里是 10,模型运算过程中也会不断调整这个值,也是一个变量;

  关于交叉熵,举个例子,我们平常写代码的时候,一按编译,一切顺利,程序跑起来了,我们就没那么「惊讶」,因为我们的代码是那么的优秀;而如果一按编译,整个就 Crash 了,我们很「惊讶」,一脸蒙逼的想,这怎么可能。

  交叉熵感性的认识就是表达这个的,当输出的值和我们的期望是一致的时候,我们就「惊讶」值就比较低,当输出值不是我们期望的时候,「惊讶」值就比较高。

  这里就用了 TensorFlow 实现的 softmax 模型来计算交叉熵。 交叉熵,就是我们想要尽量优化的值,让结果符合预期,不要让我们太「惊讶」。

  TensorFlow 会自动使用反向传播算法(backpropagation algorithm)来有效的确定变量是如何影响你想最小化的交叉熵。然后 TensorFlow 会用你选择的优化算法来不断地修改变量以降低交叉熵。

  这里用了梯度下降算法(gradient descent algorithm)来优化交叉熵,这里是以 0.5 的速度来一点点的优化交叉熵。

  tf.argmax 给出某个tensor对象在某一维上的其数据最大值所在的索引值。因为我们的 label 只有一个 1,所以 tf.argmax(_y, 1) 就是 label 的索引,也就是表示图片是几。把计算值和预测值 equal 一下就可以得出模型算的是否准确。 下面的 accuracy 计算的是一个整体的精确度。

  最终结果,我的是 0.9151,91.51% 的准确度。官方说这个不太好,如果用一些更好的模型,比如多层卷积网络等,这个识别率可以到 99% 以上。

  官方的例子到这里就结束了,虽然说识别了几万张图片,但是我一张像样的图片都没看到,于是我决定想办法拿这个模型真正找几个图片测试一下。

  看下上面的例子,重点就是放测试数据进去这里,如果我们要拿图片测,需要先把图片变成相应格式的数据。

  可以看到,最后返回的都是是一个对象,而我们用的els} 就是从这来的,是一个 DataSet 对象。这个对象也在这个文件里面。

  这个对象很长,我就只挑重点了,主要看构造方法。一定要传入的有 images 和 labels。其实这里已经比较明朗了,我们只要把单张图片弄成 mnist 格式,分别传入到这个 DataSet 里面,就可以得到我们要的数据。

  网上查了下还真有,代码地址,对应的文章:,文章讲的有点不清楚,需要针对 TensorFlow 1.0 版本以及实际目录情况做点修改。

  这里读取图片依赖 PIL 这个库,由于 PIL 比较少维护了,可以用它的一个分支 Pillow 来代替。另外依赖 numpy 这个科学计算库,没装的要装一下。

  这里就是把图片读取,并按 mnist 格式化,label 是取图片文件名的第一个字,所以图片要用数字开头命名。

  如果懒得 PS 画或者手写的画,可以把测试数据集的数据给转回图片,实测成功,参考这篇文章:如何用python解析mnist图片

  新建一个文件夹叫 test_num,里面图片如下,这里命名就是 label 值,可以看到 label 和图片是对应的:

  这里用了 glob2 这个库来遍历以及过滤文件,需要安装,常规的遍历会把 Mac 上的 .DS_Store 文件也会遍历进去。

  例子中是每次都要走一遍训练流程,实际上是可以用 tf.train.Saver() 来保存训练好的模型的。这个入门例子完成之后能对 TensorFlow 有个感性认识。

  TensorFlow 没有那么神秘,没有我们想的那么复杂,也没有我们想的那么简单,并且还有很多数学知识要补充呢。

  记录一些所思所想,写写科技与人文,写写生活状态,写写读书心得,主要是扯淡和感悟。 欢迎关注,交流。