大牛教你如何用 TensorFlow 亲手搭建一套图像识别模块 | AI 研习社

这里给出了一个简单的 TensorFlow 的 Hello World 的程序,实现了一个简单的向量加法的操作。首先 import 了 TensorFlow ,然后定义了 a、b 两个向量,包括 name 属性,接着把它们加起来。这里 TensorFlow 采用了这样的一个惰性计算模型,输出的并不是加法的结果,而是结果的一个引用。另外,要运行整个 result 运算,就必须定义一个 session ,session 会掌握所有 TensorFlow 的运算资源,然后通过 session 运行相关操作。

这里只是简单介绍了一个 TensorFlow 的简单用法,由于时间有限,也无法深入地去详细介绍。我们关注的是如何用 TensorFlow 实现一个神经网络的全连接,也就是加权和,加上激活函数的模型。

加权和可以通过矩阵乘法的方式实现。如上图代码所示,这里通过 placeholder 的方法定义了一个 input ,其中类型是必须的,其他的诸如 shape 等参数则可以等使用的时候再赋值。之后定义了权重 w 和偏移量 b,这里是通过 Variable 方法定义的,这样等最后优化的时候,TensorFlow 会针对这些 Variable 展开优化。最后通过乘法和加法操作,也就是通过 output = tf.nn.relu(tf.matmul(x, w) + b) 这一行代码就实现了神经网络的基本结构。

这里是通过基础的 TensorFlow API 实现的,如果通过 Keras 等更高层的封装来实现会更加简单。这里我们是从基础的 API 入手来进行讲解,如果大家对高层封装感兴趣,可以自己学习。需要指出的是,其实高层封装和基础 API 的主要区别是实现上的区别,他们整体上的过程是基本一样的。

下面我们来看一下如何用 TensorFlow 实现一个具体的图像识别模块,即从 MNIST 数据集中识别手写数字。(完整代码见下文链接)


可以看到,TensorFlow 通过 read_data_sets 方法对引用数据进行了一个非常好的封装,后续可以通过非常简单的方式读取这些划分好的数据集,例如通过 train、validation、test 等关键词就可以读取训练和测试数据集等。

如下图所示,然后是通过 next_batch 来获取一小批的训练数据。我们刚刚提到,在利用梯度下降算法时需要在所有的训练数据上计算梯度,但是计算量太大了,因此这里通过 next_batch 方法,相当于我们在所有的训练数据集中筛选一部分,随机选取一部分训练数据集,提供到神经网络的输入层,然后通过反向迭代方法去优化这个神经网络。

这里 xx 设置等于 100,也就是我们得到了 xs 和 ys 两个矩阵,xs 代表输入数组,相当于把一个 28×28 的手写图像展开成一个长度为 748 的一维数组。ys 相当于我们的结果,也就是 0-9 这 10 种可能值。

如上图,完了之后是一个前向传播的一个大致过程的程序截图。这个过程就相当于是定义一层一层的神经网络结构,这里 inference 函数中的 input_tensor 相当于输入矩阵,后面的 reqularizer 就相当于一个正则化的东西。我们可以看到,当输入来了之后,程序开始进行一层一层的推导,定义一层一层的权重和偏移量,算出每一层的结果,传入下一层,进入下一层的计算。

其实通过这个前项传播的定义我们可以看到,无论是全连接层还是卷积神经网络,甚至是循环神经网络,它的大致流程都是一样的,给定输入,然后通过一层一层的传递就可以得到最后的输出。

如上图,下面我们看一下主程序。其实主程序就是调用了 train 的过程,这个 train 的过程其实也是比较简单的。第一部分是定义输入,也就是怎样来提供这个训练数据的接口,也就是通过 placeholder 的方式导入,输入这里是 x ,输出是 y_ 。然后通过调用 inference 函数来进行一个前向传播的计算。然后定义了滑动平均和损失函数。

这里的过程其实是就相当于是:我通过输入一个训练数据集,然后得到在当前数据集下的推导结果,然后再通过这个推导结果和正确答案对比,就知道跟正确答案的差别在哪。下一步可以看到我们定义了 loss ,它相当于评估当前模型好坏的一个指标。这里其实就相当于是评价 cross_entropy 加上正则化,这里正则化是为了避免过耦合的。

完了之后,下一行是通过 GradientDescentOptimizer 函数优化。TensorFlow 提供了大概 5-7 中不同的优化函数可供选择,它们针对不同的应用场景,各具特点,大家可以灵活选择。这里我认为,对于那些不搞学术研究的同学,其实没有必要去从数学的角度推导每一个优化函数具体是怎么优化的,从应用层的角度来看,大部分用户只需要提供学习率和目标函数,并且了解这些优化函数的优劣就可以了,这个相对来说还是比较方便。

在把所有的这些计算方式都定义好了之后,下面就是生成 TensorFlow 的计算图,以及生成 session。定义好 session 之后,下面训练的过程就比较简单了,其实就是写了一个循环,每次选取一小部分训练数据,然后去做训练,隔一段时间再打印一下训练结果,整个过程就完成了。

所以说整个用 Tensorflow 来实现一个神经网络的过程,相对还是比较简单的。需要注意的是,这里我介绍的只是原生态的 TensorFlow,如果大家要去使用 TFLearn,或者 Keras 这些高级封装去实现 MNIST 问题的话,可能会更加简单,大概只需要 2-3 行代码就可以解决了。

这里我们基本上把通过原生态的 Tensorflow 生成神经网络的过程为大家介绍了一下。其实后面还有个 evaluate 评估的部分(代码如上图所示),因为时间关系我就不对着代码详细讲了,感兴趣的同学可以自己下去研究(源码见下文链接)。

下面我再跟大家再介绍一下循环卷积神经网络。

刚刚大家看到的这个结构是一个全链接的神经网络,在图像处理的过程中,使用全连接神经网络最大的一个问题就是它的参数太多了,这个问题可能会导致模型最终训练不好。

例如,经常发生的,当你的训练数据不足的时候,参数又太多,你就可能训练不出来。一个非常简单的例子,大家可以想象 N 元的一个方程组,然后我们假设只有 N 个数据,并且这些数据是完全可分的,也就是我们是可以完全求解。但完全求解可能会导致过拟合,因为训练数据在真实环境下都是有噪音的,也就是没有办法做到完全避免随机因素的影响。在这种情况下如果你过于贴合训练数据,那么就有可能没有办法去收敛到未知的数据。

所以这就是参数过多可能引发的问题,即过拟合和训练不出来。那怎样去解决这两个问题呢?卷积神经网络就是一个很好的方法。

卷积神经网络就相当于是采用一个内核,即一个规模较小的矩阵,去处理一个比较小的区域,然后去通过移动这个小矩阵,去处理不同的这个块。这种方式一个直观的一个意义就是:一般的图像上相邻区域的内容是相似的。然后通过这样的一个潜在的东西,就可以去把一个浅层的表达变成一个更深层的表达。也就是相当于自动从图像中去提取特征。

例如上图所示,第一层可能可以从图像中提取一些线条和斑点,第二层提取一些更复杂的性状。第三层和第四层,层数越多,提取的特征就会越复杂。然后通过最后提取出来的这样一些特征,我们再去做一个全连接的分类,最后这个分类的效果也就会更好。

然后这里给出了一个简单的 LeNet5 的模型,我们可以看到他的大致结构就是从输入层,经过不断地卷积池化,再经过 1 到 3 层不等的全连接层,最后得到输出层。其实现在很多的卷积神经网络基本上也都保留了这样的一种结构。

除了这种模型之外,另一种比较特殊的模型是 Google Inception 模型,这里因为时间关系我也不去做过多的介绍了。

然后我在这里给出了一个简单的用 TensorFlow 的程序来实现卷积层。通过代码其实大家也可以看到,在这个框架里面,无论是全连接的神经网络也好,还是卷积神经网络也好,甚至循环神经网络也好。它们的训练过程,以及前面的准备过程其实基本上都是差不多的,你基本上只要去修改,怎么样去从输入得到输出就可以了。

从代码也可以看到,开始是定义这个卷积层中的权重和偏移量,完了之后 TensorFlow 会对这个卷积层有一个封装,然后通过 conv2d 函数得到一个 2D 的卷积层,然后再把偏移量、激活函数加上去。大家可以看到整个的过程还是比较简单的,同样的,如果用 Keras 等更高级的封装来实现的化会更加简单。

最后我要推荐一下《TensorFlow:实战Google深度学习框架》这本书,今天讲的内容,包括一些略去的内容,基本上全部在这本书里都有非常详细的介绍。

另外,前面提到的代码地址如下:

https://github.com/caicloud/tensorflow-tutorial

代码库里包含了书中所有的样例代码,此外还包括了才云科技提供的 TensorFlow as a Service (TaaS) 深度学习平台的一些教程和代码,包括后面我们做的一些图像分类和图像识别的样例代码,后面也都会陆陆续续添加进去。大家有兴趣的化可以关注一下这个代码库。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,657评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,662评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,143评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,732评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,837评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,036评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,126评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,868评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,315评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,641评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,773评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,470评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,126评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,859评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,095评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,584评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,676评论 2 351

推荐阅读更多精彩内容