当前位置: 首页 > 新闻 > 信息荟萃
编号:2462
TensorFlow:实战Google深度学习框架.pdf
http://www.100md.com 2020年2月2日
第1页
第10页
第19页
第30页
第44页
第287页

    参见附件(10912KB,445页)。

     TensorFlow:实战Google深度学习框架,TensorFlow是一门新型技术学习框架,本书作者作为TensorFlow的新星人物,为读者们带来通俗易懂的学习内容。

    实战Google深度学习框架内容提要

    TensorFlow 是谷歌2015年开源的主流深度学习框架,目前已在谷歌、优步(Uber)、小米等科技公司广泛应用。《TensorFlow:实战Google深度学习框架》为使用TensorFlow 深度学习框架的入门参考书,旨在帮助读者以快速、有效的方式上手TensorFlow 和深度学习。书中省略了深度学习繁琐的数学模型推导,从实际应用问题出发,通过具体的TensorFlow 样例程序介绍如何了使用深度学习解决这些问题。《TensorFlow:实战Google深度学习框架》包了深度学习的入门知识和大量实践经验,是走进这个前沿、热门的人工智能领域的*参考书。读者对象:对人工智能、深度学习感兴趣的计算机相关从业人员,想要使用深度学习或TensorFlow 的数据科学家、工程师,希望了解深度学习的大数据平台工程师,对人工智能、机器学习感兴趣的在校学生,希望找深度学习相关岗位的求职人员,等等。

    实战Google深度学习框架作者信息

    郑泽宇,现为才云科技(Caicloud.io)联合创始人、首席大数据科学家。针对分布式TensorFlow上手难、管理难、监控难、上线难等问题,他带领团队成功开发国内成熟的分布式TensorFlow深度学习平台(TensorFlow as a Service)。基于此平台,才云大数据团队为安防、电商、金融、物流等多个行业提供有针对性的人工智能解决方案。归国创业之前,郑泽宇曾任美国谷歌高级工程师。从 2013 年加入谷歌,郑泽宇作为主要技术人员参与并领导了多个大数据项目。由他提出并主导的产品聚类项目用于衔接谷歌购物和谷歌知识图谱(Knowledge Graph)数据,使得知识卡片形式的广告逐步取代传统的产品列表广告,开启了谷歌购物广告在搜索页面投递的新纪元。郑泽宇于2011年5月获得北京大学计算机学士学位,并荣获北京大学信息科学技术学院十佳毕业论文、北京大学毕业生。2013年5月获得美国 Carnegie Mellon University(CMU)大学计算机硕士学位,并获得西贝尔奖学金 (Siebel Scholarship)。郑泽宇在机器学习、人工智能领域有多年研究经验,并在SIGIR、SIGKDD、ACL、ICDM、ICWSM等国际会议上发表多篇学术论文。

    实战Google深度学习框架目录

    第1章 深度学习简介

    第2章 TensorFlow环境搭建

    第3章 TensorFlow入门

    第4章 深层神经网络

    第5章 MNIST数字识别问题

    第6章 图像识别与卷积神经网络

    第7章 图像数据处理

    第8章 循环神经网络

    第9章 TensorBoard可视化

    第0章 TensorFlow计算加速

    实战Google深度学习框架特色

    作者为前谷歌专家,现Tensorflow创业新星,醉心深度学习研究。

    Tensorflow已从前瞻性黑科技成长为主流方案,本书旨在面向生产与商业场景,彻底贯通原理与实践。

    BAT一线团队与各大基于AI、ML的技术公司争相赞誉力荐,本书与Tensorflow一道走向事实标准。

    深入技术原理,走访主创团队,结合真实项目,倾力呈现一手资料,深度剖析一线实战

    TensorFlow:实战Google深度学习框架截图

    TensorFlow:实战Google深度学习框架

    才云科技Caicloud 郑泽宇 顾思宇 著

    电子工业出版社

    内容简介

    TensorFlow是谷歌2015年开源的主流深度学习框架,目前已在谷歌、优

    步(Uber)、京东、小米等科技公司广泛应用。本书为使用TensorFlow

    深度学习框架的入门参考书,旨在帮助读者以快速、有效的方式上手

    TensorFlow和深度学习。书中省略了深度学习繁琐的数学模型推导,从

    实际应用问题出发,通过具体的TensorFlow样例程序介绍如何了使用深

    度学习解决这些问题。书中包含了深度学习的入门知识和大量实践经

    验,是走进这个前沿、热门的人工智能领域的首选参考书。

    读者对象:对人工智能、深度学习感兴趣的计算机相关从业人员,想要

    使用深度学习或TensorFlow的数据科学家、工程师,希望了解深度学习

    的大数据平台工程师,对人工智能、机器学习感兴趣的在校学生,希望

    找深度学习相关岗位的求职人员,等等。

    未经许可,不得以任何方式复制或抄袭本书之部分或全部内容。

    版权所有,侵权必究。

    图书在版编目(CIP)数据

    TensorFlow:实战Google深度学习框架才云科技Caicloud,郑泽宇,顾

    思宇著.—北京:电子工业出版社,2017.3

    ISBN 978-7-121-30959-5

    Ⅰ.①T… Ⅱ.①才… ②郑… ③顾… Ⅲ.①人工智能—算法—

    研究 Ⅳ.①TP18中国版本图书馆CIP数据核字(2017)第029689号

    策划编辑:张春雨

    责任编辑:徐津平

    印 刷:三河市良远印务有限公司

    装 订:三河市良远印务有限公司

    出版发行:电子工业出版社

    北京市海淀区万寿路173信箱 邮编:100036

    开 本:787×980 116 印张:18.5 字数:380.95千字

    版 次:2017年3月第1版

    印 次:2017年9月第6次印刷

    定 价:79.00元

    凡所购买电子工业出版社图书有缺损问题,请向购买书店调换。若书店

    售缺,请与本社发行部联系,联系及邮购电话:(010)88254888,88258888。

    质量投诉请发邮件至zlts@phei.com.cn,盗版侵权举报请发邮件至

    dbqq@phei.com.cn。

    本书咨询联系方式:(010)51260888-819,faq@phei.com.cn。

    推荐序1

    “互联网+”的大潮催生了诸如“互联网+外卖”、“互联网+打车”、“互联网

    +家政”等众多商业模式的创新和创业佳话。而当“互联网+”已被写入教

    科书并成为传统行业都在积极践行的发展道路时,过去一年科技界的聚

    光灯却被人工智能和深度学习所创造的一个个奇迹所占据。从阿尔法狗

    肆虐围棋界,到人工智能创业大军的崛起,都预示着我们即将步入“AI+”的时代:“AI+教育”、“AI+媒体”、“AI+医学”、“AI+配

    送”、“AI+农业”,等等,将会层出不穷。

    AI在近期的爆发离不开数据“质”和“量”的提升,离不开高性能计算平台

    的发展,更离不开算法的进步,而深度学习则成为了推动算法进步中的

    一个主力军。TensorFlow作为谷歌开源的深度学习框架,包含了谷歌过

    去10年间对于人工智能的探索和成功的商业应用。谷歌的自驾车、搜

    索、购物、广告、云计算等产品,都无时无刻不在利用类似TensorFlow

    的深度学习算法将数据的价值最大化,从而创造巨大的商业价值。

    TensorFlow作为一个开源框架,在极短时间内迅速圈粉并已成为

    github.com上耀眼的明星。然而,掌握深度学习需要较强的理论功底,用好TensorFlow又需要足够的实践和解析。开源项目和代码本身固然重

    要,但更重要的是使用者的经验和领域知识,以及如何将底层技术或工

    具采用最佳实践和模式来解决现实问题。我与作者共事多年,浏览本书

    后深深体会到该作品是作者在谷歌多年分布式深度学习实践经验和其理

    论才学的浓缩,也相信这本从入门到高级实践的读物能够为每个读者带

    来一个精神盛宴,并帮助计算机技术从业者在各自的业务领域打开新的

    思路、插上新的翅膀。

    张鑫

    杭州才云科技有限公司联合创始人CEO、Carnegie Mellon University计

    算机博士

    推荐序2

    自2015年11月发布以来,TensorFlow在GitHub上迅速受到广泛关注。

    TensorFlow的一个突出特点,是它很好地兼顾了学术研究和工业生产的

    不同需求。一方面,TensorFlow的灵活性使得研究人员能够利用它快速

    实现最新的模型设计;另一方面,TensorFlow强大的分布式支持,对工

    业界在海量数据集上进行的模型训练也至关重要。

    以我供职的谷歌翻译组为例,在研发最新的神经网络翻译模型过程中,我们既需要快速灵活地尝试学术界各类最新的想法,又需要成熟、高效

    的分布式训练系统,以便在十亿句量级的训练数据上训练最终模型。

    TensorFlow的特性使我们只需维护一套代码,就能够高效兼顾这两方面的工作。模型训练完成之后,我们又借助TensorFlow搭建了一个高性

    能、低延迟的在线翻译服务。目前谷歌翻译每天完成大约千亿词量级的

    文字翻译任务,其中超过35%是通过TensorFlow进行的。

    TensorFlow还有着强大的可移植性,支持GPU、CPU、安卓、iOS等多

    种计算平台。受益于这一特性,开发者可以在移动平台上开发复杂的深

    度学习应用。仍以翻译为例,谷歌翻译应用中广受好评的图片即时翻译

    功能,就是依赖于移动平台上的TensorFlow,使用用户的手机本地完成

    计算的。这一功能可以帮助人们摆脱语言和手机网络的约束,更加自由

    地体验全球各地的风土人情。

    谷歌已经将TensorFlow大规模应用于数十项产品的研发中,而在谷歌以

    外,TensorFlow也逐渐得到广泛应用。从国内的小米、京东,到硅谷的

    Uber、Airbnb、Twitter等,都已经开始采用TensorFlow进行生产实践。

    多伦多大学、加州大学伯克利分校等著名高校,也已经将TensorFlow用

    于教学当中,斯坦福大学更是专门开设了“TensorFlow for Deep Learning

    Research”课程,帮助学生深入理解这一深度学习领域的重要工具。

    作者郑泽宇是我的多年好友,他对于机器学习的学术研究和工业应用方

    面都有着极为丰富的经验。这本教程从深入浅出,涵盖了深度学习中常

    见算法的理论基础和TensorFlow实现两方面内容。相信这本书能帮助读

    者在最短时间内理解深度学习并熟练应用TensorFlow,在这一当前极为

    活跃的领域展开工程实践。

    梁博文

    工程师,谷歌翻译团队

    推荐序3

    深度学习带来的技术革命波及甚广,学术界同样早已从中受益,将深度

    学习广泛应用到各个学科领域。深度学习源自“古老”的神经网络技术,既标志着传统神经网络的卷土重来,也藉由AlphaGo碾压人类围棋一

    役,开启了AI爆炸式发展的大幕。机器学习为人工智能指明道路,而深

    度学习则让机器学习真正落地。作为高等教育工作者,让学生了解和跟

    上最新技术发展的意义不言而喻。而深度学习的重要性,从近来国内外

    互联网巨擘对未来的展望中可见端倪——以深度学习照耀下的人工智能技术,毫无疑问是下一个时代的主角和支柱。

    然而,目前深度学习的相关资料,尤其是像TensorFlow这种引领未来趋

    势的新技术的学习资料,普遍存在明显缺憾。

    其一,中文资料非常少,而且信息零散、不成系统。这篇文章里讲一个

    算法,那个博客里介绍一个应用,很难让学生形成一个完整的、全局的

    概念体系。

    其二,已有的深度学习资料大多偏重理论,对概率、统计等数学功底有

    很高的要求,不易激发学生的兴趣。

    而这些现存问题,也正是我对泽宇这部著作寄予厚望的原因——这是一

    本非常适合高校学生走近深度学习的入门读物。因为它从实际问题出

    发,可以激发读者的兴趣,让读者可以快速而直观地享受到解决问题的

    成就感。同时,此书理论与实践并重,既介绍了深度学习的基本概念,为更加深入地研究深度学习奠定基础;又给出了具体的TensorFlow样例

    代码,让读者可以将学习成果直接运用到实践中。

    我非常相信也衷心希望,有志参与深度学习未来大潮的莘莘学子,能凭

    借此书更快速、更扎实地开启深度学习之旅,并通过TensorFlow来实现

    深度学习常用算法,从而登堂入室,最终成为AI的真正驾驭者。

    张铭

    北京大学信息学院教授

    前言

    “深度学习”这个词在过去的一年之中已经轰炸了媒体、技术博客甚至朋

    友圈。这也许正是你会读到本书的原因之一。数十年来,人工智能技术

    虽不断发展,但像深度学习这样在学术界和工业界皆具颠覆性的技术实

    在是十年难遇。可惜的是,理解和灵活运用深度学习并不容易,尤其是

    其复杂的数学模型,让不少感兴趣的同学“从入门到放弃”。更糟糕的

    是,因为深度学习技术的飞速发展,而写书、出版的过程又非常复杂,不论是英文还是中文,都很难找到从实战出发的深度学习参考书。关于

    当前最新最火的深度学习框架TensorFlow的书籍更是空缺。这正是作者在工作之余,熬夜写这本书的动力。作者本人作为一枚标准码农、创业

    党,希望这本书能够帮助码农和准码农们绕过深度学习复杂的数据公

    式,通过本书的大量样例代码快速上手深度学习,解决工作、学习中的

    实际问题。

    2016年初,作者和小伙伴们从美国谷歌辞职,回到祖国杭州联合创办了

    才云科技(Caicloud.io),为企业提供人工智能平台和解决方案,在作

    者回国之初,很多企业都展示出了对于TensorFlow浓厚的兴趣。然而在

    深度交流之后,作者发现虽然TensorFlow是一款非常容易上手的工具,但是深度学习的技术目前并不是每一个企业都掌握的。为了让更多的个

    人和企业可以享受到深度学习技术带来的福利,作者与电子工业出版社

    的张春雨主编一拍即合,开始了本书的撰写工作。

    使用TensorFlow实现深度学习是本书重点介绍的对象。本书将从

    TensorFlow的安装开始,逐一介绍TensorFlow的基本概念、使用

    TensorFlow实现全连接深层神经网络、卷积神经网络和循环神经网络等

    深度学习算法。在介绍使用TensorFlow实现不同的深度学习算法的同

    时,作者也深入浅出地介绍了这些深度学习算法背后的理论,并给出了

    这些算法可以解决的具体问题。在本书中,作者避开了枯燥复杂的数学

    公式,从实际问题出发,在实践中介绍深度学习的概念和TensorFlow的

    用法。在本书中,作者还介绍了TensorFlow并行化输入数据处理流程、TensorBoard可视化工具以及带GPU的分布式TensorFlow使用方法。

    TensorFlow是一个飞速发展的工具。本书在写作时最新的版本为0.9.0,然而到本书出版时,谷歌已经推出了TensorFlow 1.0.0。为了让广大读者

    更好地理解和试用书中的样例代码,我们提供了一个公开的GitHub代码

    库来维护不同TensorFlow版本的样例程序。该代码库的网址为

    https:github.comcaicloudtensorflow-tutorial。在Caicloud提供的

    TensorFlow镜像cargo.caicloud.iotensorflowtensorflow:0.12.0中也包含了

    本书的样例代码。作者衷心地希望各位读者能够从本书获益,这也是对

    我们最大的支持和鼓励。对于书中出现的任何错误或者不准确的地方,欢迎大家批评指正,并发送邮件至zeyu@caicloud.io。

    读者也可登录博文视点官网http:www.broadview.com.cn下载本书代码或

    提交勘误信息。一旦勘误信息被作者或编辑确认,即可获得博文视点奖

    励积分,可用于兑换电子书。读者可以随时浏览图书页面,查看已发布

    的勘误信息。致谢

    在此我特别感谢为此书做出贡献的每一个人。感谢每一位读者,希望书

    里的干货值得您宝贵的精力投入。要记得好评哦,亲!

    首先,我要感谢才云科技(Caicloud.io)小伙伴们对我的大力支持。在

    紧张的创业环境中,CEO张鑫给了我极大的支持和鼓励,让我有足够的

    时间投入到本书中。特别感谢为此书完成校验以及代码整理工作的数据

    工程师易明轩,为此书提出宝贵意见的大数据科学家何辉辉以及才云科

    技TensorFlow as a Service的产品开发者李恩华。

    然后,我要感谢我的妻子温苗苗。作为本书的第一读者和美国卡内基梅

    隆大学(Carnegie Mellon University)计算机专业博士,从最开始的内

    容安排到写作语言细节,与她的讨论给我带来很多灵感。

    我要感谢我的父母、岳父母,没有他们一直以来的支持和帮助,我不可

    能完成此书的写作。每当遇到困难的时候,长辈们的鼓励是我前进的最

    大动力。

    最后,我要感谢电子工业出版社的张春雨编辑。无论在该书的定位上还

    是在具体的文字细节上,张编辑都给了我非常多的建议。兵贵神速,写

    书亦是如此。没有张春雨精确的策划和及时的敦促,我也很难一鼓作气

    完成此书。

    郑泽宇

    2017年1月

    目录

    推荐序1

    推荐序2

    推荐序3

    前言第1章 深度学习简介

    1.1 人工智能、机器学习与深度学习

    1.2 深度学习的发展历程

    1.3 深度学习的应用

    1.3.1 计算机视觉

    1.3.2 语音识别

    1.3.3 自然语言处理

    1.3.4 人机博弈

    1.4 深度学习工具介绍和对比

    小结

    第2章 TensorFlow环境搭建

    2.1 TensorFlow的主要依赖包

    2.1.1 Protocol Buffer

    2.1.2 Bazel

    2.2 TensorFlow安装

    2.2.1 使用Docker安装

    2.2.2 使用pip安装

    2.2.3 从源代码编译安装

    2.3 TensorFlow测试样例

    小结第3章 TensorFlow入门

    3.1 TensorFlow计算模型——计算图

    3.1.1 计算图的概念

    3.1.2 计算图的使用

    3.2 TensorFlow数据模型——张量

    3.2.1 张量的概念

    3.2.2 张量的使用

    3.3 TensorFlow运行模型——会话

    3.4 TensorFlow实现神经网络

    3.4.1 TensorFlow游乐场及神经网络简介

    3.4.2 前向传播算法简介

    3.4.3 神经网络参数与TensorFlow变量

    3.4.4 通过TensorFlow训练神经网络模型

    3.4.5 完整神经网络样例程序

    小结

    第4章 深层神经网络

    4.1 深度学习与深层神经网络

    4.1.1 线性模型的局限性

    4.1.2 激活函数实现去线性化

    4.1.3 多层网络解决异或运算4.2 损失函数定义

    4.2.1 经典损失函数

    4.2.2 自定义损失函数

    4.3 神经网络优化算法

    4.4 神经网络进一步优化

    4.4.1 学习率的设置

    4.4.2 过拟合问题

    4.4.3 滑动平均模型

    小结

    第5章 MNIST数字识别问题

    5.1 MNIST数据处理

    5.2 神经网络模型训练及不同模型结果对比

    5.2.1 TensorFlow训练神经网络

    5.2.2 使用验证数据集判断模型效果

    5.2.3 不同模型效果比较

    5.3 变量管理

    5.4 TensorFlow模型持久化

    5.4.1 持久化代码实现

    5.4.2 持久化原理及数据格式

    5.5 TensorFlow最佳实践样例程序小结

    第6章 图像识别与卷积神经网络

    6.1 图像识别问题简介及经典数据集

    6.2 卷积神经网络简介

    6.3 卷积神经网络常用结构

    6.3.1 卷积层

    6.3.2 池化层

    6.4 经典卷积网络模型

    6.4.1 LeNet-5模型

    6.4.2 Inception-v3模型

    6.5 卷积神经网络迁移学习

    6.5.1 迁移学习介绍

    6.5.2 TensorFlow实现迁移学习

    小结

    第7章 图像数据处理

    7.1 TFRecord输入数据格式

    7.1.1 TFRecord格式介绍

    7.1.2 TFRecord样例程序

    7.2 图像数据处理

    7.2.1 TensorFlow图像处理函数7.2.2 图像预处理完整样例

    7.3 多线程输入数据处理框架

    7.3.1 队列与多线程

    7.3.2 输入文件队列

    7.3.3 组合训练数据(batching)

    7.3.4 输入数据处理框架

    小结

    第8章 循环神经网络

    8.1 循环神经网络简介

    8.2 长短时记忆网络(LSTM)结构

    8.3 循环神经网络的变种

    8.3.1 双向循环神经网络和深层循环神经网络

    8.3.2 循环神经网络的dropout

    8.4 循环神经网络样例应用

    8.4.1 自然语言建模

    8.4.2 时间序列预测

    小结

    第9章 TensorBoard可视化

    9.1 TensorBoard简介

    9.2 TensorFlow计算图可视化9.2.1 命名空间与TensorBoard图上节点

    9.2.2 节点信息

    9.3 监控指标可视化

    小结

    第10章 TensorFlow计算加速

    10.1 TensorFlow使用GPU

    10.2 深度学习训练并行模式

    10.3 多GPU并行

    10.4 分布式TensorFlow

    10.4.1 分布式TensorFlow原理

    10.4.2 分布式TensorFlow模型训练

    10.4.3 使用Caicloud运行分布式TensorFlow

    小结

    第1章 深度学习简介

    随着AlphaGo战胜李世石,人工智能和深度学习这些概念已经成为一个

    非常火的话题。谷歌(Google)、脸书(Facebook)、百度、阿里巴巴

    等一系列国内外大公司纷纷对外公开宣布了人工智能将作为他们下一个

    战略重心。在类似AlphaGo、无人驾驶汽车等最新技术的背后,深度学

    习是推动这些技术发展的核心力量。“深度学习”是本书的核心概念。通

    过阅读本章,读者将从多个角度了解这一概念。人工智能、机器学习与

    深度学习这几个关键词时常出现在媒体新闻中,并错误地被认为是等同

    的概念。1.1节将介绍人工智能、机器学习以及深度学习的概念,并着

    重解析它们之间的关系。这一节将从不同领域需要解决的问题入手,依

    次介绍这些领域的基本概念以及解决领域内问题的主要思路。在介绍完深度学习基本的概念之后,1.2节将完整地介绍深度学习发展史。虽

    然“深度学习”这个名词是在最近几年才提出,但深度学习基于的神经网

    络算法却早在20世纪40年代就出现了。这一节将会介绍神经网络发展过

    程中的重大事件,并介绍深度学习研究领域的发展历程。

    接着,1.3节将从计算机视觉、语音识别、自然语言处理和人机博弈四

    个不同的方向介绍目前深度学习的应用。从2012年深度学习被成功应用

    于图像识别问题以来,研究人员一直在扩展它的应用范围和影响力。这

    一节既会介绍在不同方向上深度学习在学术界取得的成就,也会介绍工

    业界成功应用深度学习的案例。最后,1.4节将引出本书的重点——

    TensorFlow。TensorFlow是谷歌开源的一个计算框架,该计算框架可以

    很好地实现各种深度学习算法。这一节将简单介绍TensorFlow的特性以

    及它目前的应用场景。也将对比不同的开源深度学习工具,并通过具体

    的数字来说明TensorFlow相比其他工具的优势以及作者将TensorFlow作

    为本书介绍对象的原因。

    1.1 人工智能、机器学习与深度学习

    (1)

    从计算机发明之初,人们就希望它能够帮助甚至代替人类完成重复性劳

    作。利用巨大的存储空间和超高的运算速度,计算机已经可以非常轻易

    地完成一些对于人类非常困难,但对计算机相对简单的问题。比如,统

    计一本书中不同单词出现的次数,存储一个图书馆中所有的藏书,或是

    计算非常复杂的数学公式,都可以轻松通过计算机解决。然而,一些人

    类通过直觉可以很快解决的问题,目前却很难通过计算机解决。这些问

    题包括自然语言理解、图像识别、语音识别,等等。而它们就是人工智

    能需要解决的问题。

    计算机要像人类一样完成更多智能的工作,需要掌握关于这个世界海量

    的知识。比如要实现汽车自动驾驶,计算机至少需要能够判断哪里是

    路,哪里是障碍物。这个对人类非常直观的东西,但对计算机却是相当

    困难的。路有水泥的、沥青的,也有石子的甚至土路。这些不同材质铺

    成的路在计算机看来差距非常大。如何让计算机掌握这些人类看起来非

    常直观的常识,对于人工智能的发展是一个巨大的挑战。很多早期的人

    工智能系统只能成功应用于相对特定的环境(specific domain),在这

    些特定环境下,计算机需要了解的知识很容易被严格并且完整地定义。例如,IBM的深蓝(Deep Blue)在1997年打败了国际象棋冠军卡斯帕罗

    夫。设计出下象棋软件是人工智能史上的重大成就,但其主要挑战不在

    于让计算机掌握国际象棋中的规则。国际象棋是一个特定的环境,在这

    个环境中,计算机只需要了解每一个棋子规定的行动范围和行动方法即

    可。虽然计算机早在1997年就可以击败国际象棋的世界冠军,但是直到

    20年后的今天,让计算机实现大部分成年人都可以完成的汽车驾驶却仍

    然依旧十分困难。

    为了使计算机更多地掌握开放环境(open domain)下的知识,研究人员

    进行了很多尝试。其中一个影响力非常大的领域是知识图库(Ontology

    (2))。WordNet是在开放环境中建立的一个较大且有影响力的知识图

    库。WordNet是由普林斯顿大学(Princeton University)的George

    Armitage Miller教授和Christiane Fellbaum教授带领开发的,它将155287

    个单词整理为了117659个近义词集(synsets)。基于这些近义词集,WordNet进一步定义了近义词集之间的关系。比如同义词集“狗”属于同

    义词集“犬科动物”,他们之间存在种属关系(hypernymshyponyms (3))。除了WordNet,也有不少研究人员尝试将Wikipedia中的知识整理成

    知识图库。谷歌的知识图库就是基于Wikipedia创建的。

    虽然使用知识图库可以让计算机很好地掌握人工定义的知识,但建立知

    识图库一方面需要花费大量的人力物力,另一方面可以通过知识图库方

    式明确定义的知识有限,不是所有的知识都可以明确地定义成计算机可

    以理解的固定格式。很大一部分无法明确定义的知识,就是人类的经

    验。比如我们需要判断一封邮件是否为垃圾邮件,会综合考虑邮件发出

    的地址、邮件的标题、邮件的内容以及邮件收件人的长度,等等。这是

    收到无数垃圾邮件骚扰之后总结出来的经验。这个经验很难以固定的方

    式表达出来,而且不同人对垃圾邮件的判断也会不一样。如何让计算机

    可以跟人类一样从历史的经验中获取新的知识呢?这就是机器学习需要

    解决的问题。

    卡内基梅隆大学(Carnegie Mellon University)的Tom Michael Mitchell

    教授在1997年出版的书籍Machine Learning (4)

    中对机器学习进行过非常专

    业的定义,这个定义在学术界内被多次引用。在这本书中对机器学习的

    定义为“如果一个程序可以在任务T上,随着经验E的增加,效果P也可

    以随之增加,则称这个程序可以从经验中学习”。通过垃圾邮件分类的

    问题来解释机器学习的定义。在垃圾邮件分类问题中,“一个程序”指的

    是需要用到的机器学习算法,比如逻辑回归算法;“任务T”是指区分垃圾邮件的任务;“经验E”为已经区分过是否为垃圾邮件的历史邮件,在

    监督式机器学习问题中,这也被称之为训练数据;“效果P”为机器学习

    算法在区分是否为垃圾邮件任务上的正确率。

    在使用逻辑回归算法解决垃圾邮件分类问题时,会先从每一封邮件中抽

    取对分类结果可能有影响的因素,比如说上文提到的发邮件的地址、邮

    件的标题及收件人的长度,等等。每一个因素被称之为一个特征

    (feature)。逻辑回归算法可以从训练数据中计算出每个特征和预测结

    果的相关度。比如在垃圾邮件分类问题中,可能会发现如果一个邮件的

    收件人越多,那么邮件为垃圾邮件的概率也就越高。在对一封未知的邮

    件做判断时,逻辑回归算法会根据从这封邮件中抽取得到的每一个特征

    以及这些特征和垃圾邮件的相关度来判断这封邮件是否为垃圾邮件。

    在大部分情况下,在训练数据达到一定数量之前,越多的训练数据可以

    使逻辑回归算法对未知邮件做出的判断越精准。也就是说逻辑回归算法

    可以根据训练数据(经验E)提高在垃圾邮件分类问题(任务T)上的

    正确率(效果P)。之所以说在大部分情况下,是因为逻辑回归算法的

    效果除了依赖于训练数据,也依赖于从数据中提取的特征。假设从邮件

    中抽取的特征只有邮件发送的时间,那么即使有再多的训练数据,逻辑

    回归算法也无法很好地利用。这是因为邮件发送的时间和邮件是否为垃

    圾邮件之间的关联不大,而逻辑回归算法无法从数据中习得更好的特征

    表达。这也是很多传统机器学习算法的一个共同的问题。

    类似从邮件中提取特征,如何数字化地表达现实世界中的实体,一直是

    计算机科学中一个非常重要问题。如果将图书馆中的图书名称储存为结

    构化的数据,比如储存在Excel表格中,那么可以非常容易地通过书名

    查询一本书是否在图书馆中。如果图书的书名都是存在非结构化的图片

    中,那么要完成书名查找任务的难度将大大增加。类似的道理,如何从

    实体中提取特征,对于很多传统机器学习算法的性能有巨大影响。图1-

    1展示了一个简单的例子。如果通过笛卡尔坐标系(cartesian

    coordinates)来表示数据,那么不同颜色的结点无法被一条直线划分。

    如果将这些点映射到极角坐标系(polar coordinates),那么使用直线划

    分就很容易了。同样的数据使用不同的表达方式会极大地影响解决问题

    的难度。一旦解决了数据表达和特征提取,很多人工智能任务也就解决

    了90%。 笛卡尔坐标系 极角坐标系

    图1-1 不同的数据表达对使用直线划分不同颜色结点的难度影响

    然而,对许多机器学习问题来说,特征提取不是一件简单的事情。在一

    些复杂问题上,要通过人工的方式设计有效的特征集合,需要很多的时

    间和精力,有时甚至需要整个领域数十年的研究投入。例如,假设想从

    很多照片中识别汽车。现在已知的是汽车有轮子,所以希望在图片中抽

    取“图片中是否出现了轮子”这个特征。但实际上,要从图片的像素中描

    述一个轮子的模式是非常难的。虽然车轮的形状很简单,但在实际图片

    中,车轮上可能会有来自车身的阴影、金属车轴的反光,周围物品也可

    能会部分遮挡车轮。实际图片中各种不确定的因素让我们很难直接抽取

    这样的特征。

    既然人工的方式无法很好地抽取实体中的特征,那么是否有自动的方式

    呢?答案是肯定的。深度学习解决的核心问题之一就是自动地将简单的

    特征组合成更加复杂的特征,并使用这些组合特征解决问题。深度学习

    是机器学习的一个分支,它除了可以学习特征和任务之间的关联以外,还能自动从简单特征中提取更加复杂的特征。图1-2中展示了深度学习

    和传统机器学习在流程上的差异。如图1-2所示,深度学习算法可以从

    数据中学习更加复杂的特征表达,使得最后一步权重学习变得更加简单

    且有效。在图1-3中,展示了通过深度学习解决图像分类问题的具体样

    例。深度学习可以一层一层地将简单特征逐步转化成更加复杂的特征,从而使得不同类别的图像更加可分。比如图1-3中展示了深度学习算法

    可以从图像的像素特征中逐渐组合出线条、边、角、简单形状、复杂形状等更加有效的复杂特征。

    图1-2 传统机器学习和深度学习流程对比

    图1-3 深度学习在图像分类问题上的算法流程样例

    早期的深度学习受到了神经科学的启发,它们之间有非常密切的联系。

    科学家们在神经科学上的发现使得我们相信深度学习可以胜任很多人工

    智能的任务。神经科学家发现,如果将小白鼠的视觉神经连接到听觉中

    枢,一段时间之后小鼠可以习得使用听觉中枢“看”世界。这说明虽然哺

    乳动物大脑分为了很多区域,但这些区域的学习机制却是相似的。在这

    一假想得到验证之前,机器学习的研究者们通常会为不同的任务设计不

    同的算法。而且直到今天,学术机构的机器学习领域也被分为了自然语

    言处理、计算机视觉和语音识别等不同的实验室。因为深度学习的通用

    性,深度学习的研究者往往可以跨越多个研究方向甚至同时活跃于所有

    的研究方向。下面的1.3节将具体介绍深度学习在不同方向的应用。

    虽然深度学习领域的研究人员相比其他机器学习领域更多地受到了大脑

    工作原理的启发,而且媒体界也经常强调深度学习算法和大脑工作原理

    的相似性,但现代深度学习的发展并不拘泥于模拟人脑神经元和人脑的工作机理。模拟人类大脑也不再是深度学习研究的主导方向。我们不应

    该认为深度学习是在试图模仿人类大脑。目前科学家对人类大脑学习机

    制的理解还不足以为当下的深度学习模型提供指导。

    现代的深度学习已经超越了神经科学观点,它可以更广泛地适用于各种

    并不是由神经网络启发而来的机器学习框架。值得注意的是,有一个领

    域的研究者试图从算法层理解大脑的工作机制,它不同于深度学习的领

    域,被称为“计算神经学”(computational neuroscience)。深度学习领域

    主要关注如何搭建智能的计算机系统,解决人工智能中遇到的问题。计

    算神经学则主要关注如何建立更准确的模型来模拟人类大脑的工作。

    总的来说,人工智能、机器学习和深度学习是非常相关的几个领域。图

    1-4总结了它们之间的关系。人工智能是一类非常广泛的问题,机器学

    习是解决这类问题的一个重要手段。深度学习则是机器学习的一个分

    支。在很多人工智能问题上,深度学习的方法突破了传统机器学习方法

    的瓶颈,推动了人工智能领域的发展。图1-4 人工智能、机器学习以及深度学习之间的关系图

    1.2 深度学习的发展历程

    很多读者可能会认为深度学习是一门新技术,所以听到“深度学习的历

    史”也许会有些惊讶。事实上,目前大家所熟知的“深度学习”基本上是

    深层神经网络的一个代名词,而神经网络技术可以追溯到1943年。深度

    学习之所以看起来像是一门新技术,一个很重要的原因是它在21世纪初

    期并不流行。神经网络的发展史大致可以分为三个阶段,在本节中,我

    们将简单介绍神经网络发展历史上的这三个阶段。

    早期的神经网络模型类似于仿生机器学习,它试图模仿大脑的学习机

    理。最早的神经网络数学模型是由Warren McCulloch 教授和 Walter Pitts

    教授于1943年在论文A logical calculus of the ideas immanent in nervous

    activity (5)

    中提出的。在论文中,Warren McCulloch 教授和 Walter Pitts教

    授模拟人类大脑神经元的结构提出了McCulloch-Pitts Neuron的计算结

    构。图1-5对比了人类神经元结构和McCulloch-Pitts Neuron结构。

    McCulloch-Pitts Neuron结构大致模拟了人类神经元的工作原理,它们都

    有一些输入,然后将输入进行一些变换后得到输出结果。虽然人类神经

    元处理输入信号的原理目前还对我们来说还不是完全清晰,但

    McCulloch-Pitts Neuron结构使用了简单的线性加权和的方式来模拟这个

    变换。将n个输入值提供给McCulloch-Pitts Neuron结构后,McCulloch-

    Pitts Neuron结构会通过n 个权重 来计

    算这n 个输入的加权和,然后用这个加权和经过一个阈值函数得到一个

    0或1的输出。 (a)人类神经元结构 (b)McCulloch-Pitts Neuron结构

    图1-5 人类神经元结构和McCulloch-Pitts Neuron结构对比图

    举一个具体的例子来说明McCulloch-Pitts Neuron结构是如何解决实际问

    题的。假设需要解决的问题是判断邮件是否为垃圾邮件,那么首先可以

    将从邮件里提取的n 个特征值作为输入传入McCulloch-Pitts Neuron结

    构。McCulloch-Pitts Neuron结构经过加权和及阈值函数处理可以得到一

    个0或者1的输出。如果这个输出为0,那么相应的邮件为垃圾邮件;相

    反,如果这个输出为1,那么相应的邮件不是垃圾邮件。

    为了使这种方法可以精确地判断垃圾邮件,我们需要对McCulloch-Pitts

    Neuron结构中的权重进行特殊的设置。手动设置这些权重自然是一种选

    择,但通过人类经验设置权重的方式既麻烦又很难达到最优的效果。为

    了让计算机能够更加自动且更加合理地设置权重大小,Frank Rosenblatt

    教授于1958年提出了感知机模型(perceptron)。感知机是首个可以根

    据样例数据来学习特征权重的模型。虽然McCulloch-Pitts Neuron结构和

    感知机模型极大地影响了现代机器学习,但是它们也存在非常大的局限

    性。

    1969年由Marvin Minsky教授和Seymour Papert教授出版的Perceptrons:

    An Introduction to Computational Geometry 一书中,证明了感知机模型只

    能解决线性可分问题,第4章中将会更加详细地介绍线性模型、线性可

    分问题。并明确指出了感知机无法解决异或问题。而且书中也指出在当

    时的计算能力下,实现多层的神经网络是不可能的事情。这些局限性导

    致了整个学术界对生物启发的机器学习模型的抨击。在书中,Marvin

    Minsky教授和Seymour Papert教授甚至做出了“基于感知机的研究注定将

    失败”的结论。这导致了神经网络的第一次重大低潮期,在之后的十多

    年内,基于神经网络的研究几乎处于停滞状态。

    直到20世纪80年代末,第二波神经网络研究因分布式知识表达

    (distributed representation)和神经网络反向传播算法的提出而兴起。分

    布式的知识表达的核心思想是现实世界中的知识和概念应该通过多个神

    经元(neuron)来表达,而模型中的每一个神经元也应该参与表达多个

    概念。例如,假设要设计一个系统来识别不同颜色不同型号的汽车,那

    么可以有两种方法。第一种方法是设计一个模型使得模型中每一个神经

    元对应一种颜色和汽车型号的组合,比如“白色的小轿车”。如果有n 种

    颜色,m 种型号,那么这样的表达方式需要n×m 个神经元。另一种方法是使用一些神经元专门表达颜色,比如“白色”,另外一些神经元专门表

    达汽车型号,比如“小轿车”。这样“白色的小轿车”的概念可以通过这两

    个神经元的组合来表达。这种方式只需要n×m 个神经元就可以表达所有

    概念。而且即使在训练数据中没有出现概念“红色的卡车”,只要模型能

    够习得“红色”和“卡车”的概念,它也可以推广到概念“红色的卡车”。分

    布式知识表达大大加强了模型的表达能力,让神经网络从宽度的方向走

    向了深度的方向。这为之后的深度学习奠定了基础。在第4章中将通过

    具体的样例来说明深层的神经网络是可以很好地解决类似异或问题等线

    性不可分问题的。

    除了解决了线性不可分问题,在20世纪80年代末,研究人员在降低训练

    神经网络的计算复杂度上也取得了突破性成就。David Everett Rumelhart

    教授、Geoffrey Everest Hinton教授和Ronald J. Williams教授于1986年在

    自然杂志上发表的Learning Representations by Back-propagating errors 文

    章中首次提出了反向传播的算法(back propagation),此算法大幅降低

    了训练神经网络所需要的时间。直到今天,反向传播算法仍然是训练神

    经网络的主要方法。在神经网络训练算法改进的同时,计算机的飞速发

    展也使得80年代末的计算能力相比70年代有了突飞猛进的增长。于是神

    经网络在80年末到90年代初又迎来了发展的高峰期。如今使用得比较多

    的一些神经网络结构,比如卷积神经网络和循环神经网络,在这段时间

    都得到了很好的发展。Sepp Hochreiter教授和Juergen Schmidhuber教授

    于1991年提出的LSTM模型(long short-term memory)可以有效地对较

    长的序列进行建模,比如一句话或者一段文章。直到今天,LSTM都是

    解决很多自然语言处理、机器翻译、语音识别、时序预测等问题最有效

    的方法。在第8章中将更加详细地介绍循环神经网络和LSTM模型。

    然而,在神经网络发展的同时,传统的机器学习算法也有了突破性的进

    展,并在90年代末逐步超越了神经网络,成为当时机器学习领域最常用

    的方法。以手写体识别为例,在1998年,使用支持向量机(support

    vector machine)的算法可以把错误率降低到0.8%。这样的精确度是当

    时的神经网络无法达到的。导致这种情况主要有两个原因。首先,虽然

    训练神经网络的算法得到了改进,但在当时的计算资源下,要训练深层

    的神经网络仍然是非常困难的。其次,当时的数据量比较小,无法满足

    训练深层神经网络的需求。

    随着计算机性能的进一步提高,以及云计算、GPU的出现,到2010年左

    右,计算量已经不再是阻碍神经网络发展的问题。与此同时,随着互联网+的发展,获取海量数据也不再困难。这让神经网络所面临的几个最

    大问题都得到解决,于是神经网络的发展也迎来了新的高潮。在2012年

    ImageNet举办的图像分类竞赛(ImageNet Large Scale Visual Recognition

    Challenge,ILSVRC)中,由Alex Krizhevsky教授实现的深度学习系统

    AlexNet赢得了冠军。自此之后,深度学习(deep learning)作为深层神

    经网络的代名词被大家所熟知。深度学习的发展也开启了一个AI的新时

    代。图1-6展示了“deep learning”这个词在最近十年谷歌搜索的热度趋

    势。从图中可以看出,从2012年之后,深度学习的热度呈指数级上升,到2016年时,深度学习已经成为了谷歌上最热门的搜索词。在2013年,深度学习被麻省理工(MIT)评为了年度十大科技突破之一 (6)。如今,深度学习已经从最初的图像识别领域扩展到了机器学习的各个领域。下

    面的1.3节将具体介绍目前深度学习在一些主要人工智能领域的应用。

    图1-6 “deep learning”最近十年在谷歌搜索的热度趋势

    (此图片基于于谷歌趋势:https:www.google.comtrends,词汇的热度按0-100分为100个等

    级:

    0表示最低的热度,100表示最流行的搜索词)

    1.3 深度学习的应用

    深度学习最早兴起于图像识别,但是在短短几年时间内,深度学习推广

    到了机器学习的各个领域。如今,深度学习在很多机器学习领域都有非

    常出色的表现,在图像识别、语音识别、音频处理、自然语言处理、机

    器人、生物信息处理、化学、电脑游戏、搜索引擎、网络广告投放、医

    学自动诊断和金融等各大领域均有应用。本节将选取几个深度学习应用比较广泛的领域进行详细的介绍。但深度学习的应用不仅限于本节中所

    介绍的领域,在每个领域中的应用也不限于列举出的几个方面。

    1.3.1 计算机视觉

    计算机视觉是深度学习技术最早实现突破性成就的领域。在1.2节中介

    绍过,随着2012年深度学习算法AlexNet赢得图像分类比赛

    ILSVRC(ImageNet Large Scale Visual Recognition Challenge)冠军,深

    度学习开始受到学术界广泛的关注。ILSVRC是基于ImageNet图像数据

    集举办的图像识别技术比赛,这个比赛在计算机视觉领域有极高的影响

    力。

    图1-7展示了历年ILSVRC比赛的情况。从图1-7中可以看到,在深度学

    习被使用之前,传统计算机视觉的方法在ImageNet数据集上最低的Top5

    错误率为26% (7)。从2010年到2011年,基于传统机器学习的算法并没有

    带来正确率的大幅提升。在2012年时,Geoffrey Everest Hinton教授的研

    究小组利用深度学习技术将ImageNet图像分类的错误率大幅下降到了

    16%。而且,AlexNet深度学习模型只是一个开始,在2013年的比赛

    中,排名前20的算法都使用了深度学习。从2013年之后,ILSVRC上基

    本就只有深度学习算法参赛了。

    从2012年到2015年间,通过对深度学习算法的不断研究,ImageNet图像

    分类的错误率以每年4%的速度递减。这说明深度学习完全打破了传统

    机器学习算法在图像分类上的瓶颈,让图像分类问题得到了更好的解

    决。如图1-7所示,到2015年时,深度学习算法的错误率为4%,已经成

    功超越了人工标注的错误率(5%),实现了计算机视觉研究领域的一

    个突破。

    在ImageNet数据集上,深度学习不仅突破了图像分类的技术瓶颈,同时

    也突破了物体识别的技术瓶颈。物体识别的难度比图像分类更高。图像

    分类问题只需判断图片中包含哪一种物体。但在物体识别问题中,需要

    给出所包含物体的具体位置。而且一张图片中可能出现多个需要识别的

    物体。图1-8展示了ILSVRC2013物体识别数据集中的样例图片。每一张

    图片中所有可以被识别的物体都被不同颜色的方框标注了出来。在2013

    年时,使用传统机器学习算法可以达到的MAP(mean average

    precision) (8)

    值为0.23。2016年时,使用了6种不同深度学习模型的集成

    算法(ensemble algorithm)成功将MAP提高到了0.66。 (9)图1-7 历年ILSVRC图像分类比赛最佳算法的错误率

    图1-8 ILSVRC2013物体识别数据集中的样例图片 (10)

    在技术革新的同时,工业界也将图像分类、物体识别应用于各种产品中

    了。在谷歌,图像分类、物体识别技术已经被广泛应用于谷歌无人驾驶

    车、YouTube、谷歌地图、谷歌图像搜索等产品中。图1-9中展示了使用

    谷歌图像搜索来辨别动物。谷歌通过图像处理技术可以归纳出图片中的

    主要内容并实现以图搜图的功能。这些技术在国内的百度、阿里、腾讯

    等科技公司也已经得到了广泛的应用。(a)在谷歌图片搜索中提供一张哈士奇(一种狗)的图片,得到的结果为“husky with blue

    eyes(蓝色眼睛的哈士奇)”。虽然从图片中无法确认眼睛是否为蓝色,但是谷歌可以非常精确

    的识别出狗的品种。

    (b)在谷歌图片搜索中提供一张狼的图片,得到的结果为“wolf public domain(旷野上的

    狼)”。虽然这张图片和(a)中哈士奇的图片非常接近,但是谷歌可以非常精确的识别动物的

    种类。

    图1-9 通过谷歌图像搜索识别动物

    在物体识别问题中,人脸识别是一类应用非常广泛的技术。它既可以应

    用于娱乐行业,也可以应用于安防、风控行业。在娱乐行业中,基于人

    脸识别的相机自动对焦、自动美颜基本已经成为每一款自拍软件的必备

    功能。在安防、风控领域,人脸识别应用更是大大提高了工作效率并节

    省了人力成本。比如在互联网金融行业,为了控制贷款风险,在用户注

    册或者贷款发放时需要验证本人信息。个人信息验证中一个很重要的步

    骤是验证用户提供的证件和用户是同一个人。通过人脸识别技术,这个

    过程可以被更加高效地实现。在深度学习得到广泛应用之前,基于传统的机器学习技术并不能很好地

    满足人脸识别的精度要求。人脸识别的最大挑战在于不同人脸的差异较

    小,有时同一个人在不同光照条件、姿态或者表情下脸部的差异甚至会

    比不同人脸之间的差异更大。传统的机器学习算法很难抽象出足够有效

    的特征,使得学习模型既可以区分不同的个体,又可以尽量减少相同个

    体在不同环境中的变化。深度学习技术通过从海量数据中自动习得更加

    有效的人脸特征表达,可以很好地解决这个问题。在人脸识别数据集

    LFW (11)

    (Labeled Faces in the Wild)上,基于深度学习算法的系统

    DeepID2可以达到99.47%的识别率。

    在计算机视觉领域,光学字符识别(optical character recognition,OCR)也是使用深度学习较早的领域之一。所谓光学字符识别,就是使

    用计算机程序将计算机无法理解的图片中的字符,比如数字、字母、汉

    字等符号,转化为计算机可以理解的文本格式。早在1989年,Yann

    LeCun教授发表的论文Backpropagation Applied to Handwritten Zip Code

    Recognition 将卷积神经网络成功应用到了识别手写邮政编码的问题上,达到了接近95%的正确率。在MNIST手写体数字识别数据集上,最新的

    深度学习算法可以达到99.77%的正确率,这也超过了人类的表现。第5

    章将更加详细地介绍MNIST手写体数字识别数据集。

    光学字符识别在工业界的应用也十分广泛。在21世纪初期,Yann LeCun

    教授将基于卷积神经网络的手写体数字识别系统应用于银行支票的数额

    识别,这个系统在2000年左右已经处理了美国全部支票数量的

    10%~20% (12)。谷歌也将数字识别技术用在了谷歌地图的开发中。谷歌实

    现的数字识别系统可以从谷歌街景图中识别任意长度的数字,并在

    SVHN数据集 (13)

    上可以达到96%的正确率 (14)。到2013年为止,这个系统已

    经帮助谷歌抽取了超过1亿个门牌号码,大大加速了谷歌地图的制作过

    程并节省了巨额的人力成本。而且,光学字符识别技术在谷歌的应用也

    不仅限于数字识别。谷歌图书通过文字识别技术将扫描的图书数字化,从而实现图书内容的搜索功能。

    1.3.2 语音识别

    深度学习在语音识别领域取得的成绩也是突破性的。2009年深度学习的

    概念被引入语音识别领域,并对该领域产生了巨大的影响。在短短几年

    时间内,深度学习的方法在TIMIT数据集 (15)

    上将基于传统的混合高斯模型(gaussian mixture model,GMM)的错误率从21.7%降低到了使用深

    度学习模型的17.9%。如此大的提高幅度很快引起了学术界和工业界的

    广泛关注。从2010年到2014年间,在语音识别领域的两大学术会议

    IEEE-ICASSP和Interspeech上,深度学习的文章呈现出逐年递增的趋

    势。在工业界,包括谷歌、苹果、微软、IBM、百度等在内的国内外大

    型IT公司提供的语音相关产品,比如谷歌的Google Now、苹果的Siri、微软的Xbox和Skype等,都是基于深度学习算法。

    在2009年谷歌启动语音识别应用时,使用的是在学术界已经研究了30年

    的混合高斯模型。到2012年时,深度学习的语音识别模型已经取代了混

    合高斯模型,并成功将谷歌语音识别的错误率降低了20%,这个改进幅

    度超过了过去很多年的总和。微软的研究人员通过大量实验得出,使用

    深度学习的算法比使用混合高斯模型的算法更能够从海量数据中获益。

    随着数据量的加大,使用深度学习模型无论在正确率的增长数值上还是

    在增长比率上都要优于使用混合高斯模型的算法 (16)。这样的增长在语音

    识别的历史上是从未出现过的,而深度学习之所以能完成这样的技术突

    破,最主要的原因是它可以自动地从海量数据中提取更加复杂且有效的

    特征,而不是如高斯混合模型中需要人工提取特征。

    基于深度学习的语音识别已经被应用到了各个领域,其中最被大家所熟

    知的应该是苹果公司推出的Siri系统。Siri系统可以根据用户的语音输入

    完成相应的操作功能,这大大方便了用户的使用。目前,Siri已经支持

    包括中文在内的20种不同语言。与Siri类似,谷歌也在安卓(Android)

    系统上推出了谷歌语音搜索(Google Voice Search)。另外一个成功应

    用语音识别的系统是微软的同声传译系统。在2012年的微软亚洲研究院

    (Microsoft Research Asia,MSRA)二十一世纪计算大会(21st Century

    Computing)上,微软高级副总裁Richard Rashid现场演示了微软开发的

    从英语到汉语的同声传译系统 (17)。该演讲受到了非常广泛的关注,在

    YouTube网站上已经有超过一百万次的播放量。同声传译系统不仅要求

    计算机能够对输入的语音进行识别,它还要求计算机将识别出来的结果

    翻译成另外一门语言,并将翻译好的结果通过语音合成的方式输出。在

    没有深度学习之前,要完成同声传译系统中的任意一个部分都是非常困

    难的。而随着深度学习的发展,语音识别、机器翻译以及语音合成都实

    现了巨大的技术突破。如今,微软研发的同声传译系统已经被成功地应

    用到了Skype网络电话中。1.3.3 自然语言处理

    深度学习在自然语言处理领域的应用也同样广泛。在过去的几年中,深

    度学习已经在语言模型(language modeling)、机器翻译、词性标注

    (part-of-speech tagging)、实体识别(named entity recognition,NER)、情感分析(sentiment analysis)、广告推荐以及搜索排序等方

    向上取得了突出成就。与深度学习在计算机视觉和语音识别等领域的突

    破类似,深度学习在自然语言处理问题上的突破也是能够更加智能、自

    动地提取复杂特征。在自然语言处理领域,使用深度学习实现智能特征

    提取的一个非常重要的技术是单词向量(word embedding)。单词向量

    是深度学习解决很多上述自然语言处理问题的基础 (18) (19)。

    在自然语言处理领域,一个非常棘手的问题在于自然语言中有很多词表

    达了相近的意思,比如“狗”和“犬”就几乎表达了同样的意思。然

    而“狗”和“犬”的编码在计算机中可能差别很大,所以计算机就无法很好

    地理解自然语言所表达的语义。为了解决这个问题,研究人员人工建立

    了大量的语料库。通过这些语料库,可以大致刻画自然语言中单词之间

    的关系。在建立好的语料库中,WordNet

    (20)

    、ConceptNet

    (21)

    和FrameNet

    (22)

    是其中影响力比较大的几个。然而语料库的建立需要花费很多人力物

    力,而且扩展能力有限。单词向量提供了一种更加灵活的方式来刻画单

    词的语义。

    单词向量会将每一个单词表示成一个相对较低维度的向量(比如100维

    或200维)。对于语义相近的单词,其对应的单词向量在空间中的距离

    也应该接近。于是单词语义上的相似度可以通过空间中的距离来描述。

    单词向量不需要通过人工的方式设定,它可以从互联网上海量非标注文

    本中学习得到。使用斯坦福大学开源的GloVe (23)

    单词向量可以得到与单

    词“frog(青蛙)”所对应的单词向量最相似的5个单词分别是“frogs(青

    蛙复数)”、“toad(蟾蜍)”、“litoria(雨滨蛙

    属)”、“leptodactylidae(细趾蟾科)”和“rana(中国林蛙)”。从这个样

    例可以看出,单词向量可以非常有效地刻画单词的语义。通过单词向量

    还可以进行单词之间的运算。比如用单词“king”所代表的向量减去单

    词“man”所代表的向量得到的结果向量和单词“queen”减去“woman”得到

    的结果向量相似。这说明在单词向量中,已经隐含了表达性别的概念。

    通过对自然语言中单词更好地抽象与表达,深度学习在自然语言处理的很多核心问题上都有突破性的进展。机器翻译就是其中的一个例子。图

    1-10展示了谷歌翻译提供的传统算法和深度学习算法翻译不同语言对的

    质量对比图。从图1-10可以看出,在所有的语言对上,深度学习算法都

    可以大幅度提高翻译的质量。根据谷歌的实验结果,在主要的语言对

    上,使用深度学习可以将机器翻译算法的质量提高55%到85%。表1-1对

    比了不同算法翻译同一句话的结果。从表中可以直观地看到深度学习算

    法带来翻译质量的提高。在2016年9月,谷歌正式上线了基于深度学习

    的中译英软件。现在在谷歌翻译产品中,已经有8种语言是由基于深度

    学习的翻译算法完成的。

    图1-10 不同翻译算法在不同语言上的翻译质量 (24)

    (其中0表示最低的质量,6表示最好的质

    量)

    表1-1 不同翻译算法的翻译效果对比表 (25)

    中文原句

    李克强此行将启动中加总理年度对话

    机制,与加拿大总理杜鲁多举行两国总理

    首次年度对话。

    基于传统机器学习算法

    的翻译结果

    Li Keqiang premier added this line to

    start the annual dialogue mechanism with the

    Canadian Prime Minister Trudeau two primeministers held its first annual session.

    基于深度学习算法的翻

    译结果

    Li Keqiang will start the annual dialogue

    mechanism with Prime Minister Trudeau of

    Canada and hold the first annual dialogue

    between the two premiers.

    人工翻译结果

    Li Keqiang will initiate the annual

    dialogue mechanism between premiers of

    China and Canada during this visit, and hold

    the first annual dialogue with Premier

    Trudeau of Canada.

    情感分析是自然语言处理问题中另外一个非常经典的应用。情感分析最

    核心的问题就是从一段自然语言中判断作者对评价的主体是好评还是差

    评。情感分析在工业界有着非常广泛的应用。随着互联网的发展,用户

    会在各种不同的地方表达对于不同产品的看法。对于服务行业或者制造

    业,及时掌握用户对其产品或者服务的评价是提高用户满意度非常有效

    的途径。在金融行业,通过分析用户对不同产品和公司的态度可以对投

    资选择提供帮助。Derwent Capital Markets于2012年5月正式上线,它是

    世界首家通过对社交网络Twitter上推文进行情感分析来指导证券交易 (26)

    的对冲基金公司。在同年8月的一份调查中显示,该公司的平均收益率

    1.85%远远超过了平均0.76%的收益率。类似的,也有研究表明,在政治

    选举中,通过对Twitter上推文情感分析得出的结果和通过传统的调查、投票等方法得出的结果高度一致 (27)。在情感分析问题上,深度学习也可

    以大幅提高算法的准确率。在斯坦福大学开源的Sentiment Treebank数据

    集上 (28)

    ,使用深度学习的算法可以将语句层面的情感分析正确率从80%

    提高到85.4%。在短语层面上,使用深度学习的算法可以将正确率从

    71%提高到80.7% (29)。

    1.3.4 人机博弈

    如果说深度学习在图像识别领域上的突破掀起了学术界的研究浪潮,那

    么深度学习在人机博弈上的突破使得这个概念被全社会所熟悉。在北京

    时间2016年3月15日的下午,谷歌开发的围棋人工智能系统AlphaGo以总

    比分4:1战胜了韩国棋手李世石,成为第一个在19×19棋盘上战胜人类

    围棋冠军的智能系统。虽然AlphaGo不是第一个战胜人类世界冠军的系

    统,但AlphaGo的胜利绝对是人工智能历史上的一座里程碑。在1997年IBM的智能国际象棋系统深蓝(deep blue)击败世界冠军卡斯帕罗夫

    时,所依赖的更多是计算机的计算资源,是通过暴力搜索(brute-

    force)的方式尝试更多的下棋方法从而战胜人类。然而这种方式在围棋

    上是完全不适用的,因为搜索围棋下子方法的复杂度为10 172

    ,而国际象

    棋只有10 46。

    为了战胜人类围棋世界冠军,AlphaGo需要使用更加智能的方式。深度

    学习技术为这种方式提供了可能。AlphaGo主要是由三个部分组成,他

    们分别是蒙特卡罗树搜索(Monte Carlo tree search,MCTS)、估值网

    络(value network)和走棋网络(policy network)。蒙特卡罗树搜索算

    法实现了对不同落子点的搜索,不过和之前的纯暴力搜索不同,AlphaGo中使用的蒙特卡罗树会根据估值网络和走棋网络对落子后局势

    的评判结果来更加智能地寻找最佳落子点。

    AlphaGo背后真正的大脑是估值网络和走棋网络,而这两个组件都是通

    过深度学习实现的。走棋网络解决的问题是给定当前棋盘,预测下一步

    应该在哪落子。通过在大量人类围棋高手对弈的棋谱获取的训练数据,走棋网络能够以57%的准确率预测人类围棋高手下一步的落子点。然

    而,仅仅预测人类高手的落子方法是不够的,为了能够战胜人类冠军,走棋网络还通过自己跟自己对弈的方式来进一步提高落子水平。

    AlphaGo的另外一个大脑是估值网络,它解决的问题是给定当前的棋

    盘,判断黑棋赢的概率。训练估值网络所使用的数据就是落子网络自己

    和自己对弈时产生的。通过蒙特卡罗树搜索的方法将走棋网络和估值网

    络这两个大脑有机地结合,AlphaGo才最终以悬殊的比分战胜了人类的

    围棋世界冠军。

    AlphaGo战胜人类世界冠军不是人机博弈的终点,相反,这只是一个开

    始。AlphaGo的开发团队DeepMind最近又宣布了他们的下一个目标——

    星际争霸2 (30)。星际争霸2是暴雪公司(Blizzard)开发的一款即时战略

    游戏。在游戏中,玩家需要采集资源、建造建筑、生产战斗单位来消灭

    对方玩家。相比围棋,星际争霸2对于人工智能系统设计的难度又有指

    数级的提高。首先,围棋的落子方式虽然多,但也是有限的。而人工智

    能操作星际争霸2时,在任意一个时刻,人工智能系统需要同时(几乎

    同时)操作多个不同单位,而且操作的方式是完全开放的,几乎没有限

    制,所以确定这些操作很难通过搜索完成。其次,星际争霸2是一个信

    息不对称的系统。下围棋时对弈双方看到的棋盘都是一样的,而星际争

    霸2中每个玩家只能看到自己的地盘,这要求人工智能系统对“局势”做出判断。第三,星际争霸2是即时对战游戏,需要计算机在很短的时间

    内做出判断,这对人工智能系统的计算速度有很高的要求。如今暴雪公

    司已经正式开始了与DeepMind团队的合作,并将在不久之后开放专门

    为人工智能研究设计的星际争霸2的API。在星际争霸2上,人工智能何

    时能战胜人类,我们将拭目以待。

    1.4 深度学习工具介绍和对比

    在上面的章节中已经介绍了深度学习的概念以及历史,并给出了不少成

    功应用深度学习的样例。然而,要将深度学习更快且更便捷地应用于新

    的问题中,选择一款深度学习工具是必不可少的步骤。这一节将介绍深

    度学习工具TensorFlow的主要功能和特点,并将对比TensorFlow和其他

    主流的开源深度学习工具,给出本书选择TensorFlow作为主要介绍对象

    的依据。TensorFlow是谷歌于2015年11月9日正式开源的计算框架。

    TensorFlow计算框架可以很好地支持深度学习的各种算法,但它的应用

    也不限于深度学习。因为本书的重点是介绍使用TensorFlow实现深度学

    习算法,所以本书中将略去TensorFlow对于其他算法的支持,感兴趣的

    读者可以在TensorFlow的官方教程https:www.tensorflow.orgtutorials上

    找到更多通过TensorFlow实现非深度学习算法的样例。

    TensorFlow是由Jeff Dean领头的谷歌大脑团队基于谷歌内部第一代深度

    学习系统DistBelief改进而来的通用计算框架。DistBelief是谷歌2011年

    开发的内部深度学习工具,这个工具在谷歌内部已经获得了巨大的成

    功。基于DistBelief的ImageNet图像分类系统Inception模型赢得了

    ImageNet2014年的比赛(ILSVRC) (31)。通过DistBelief,谷歌在海量的

    非标注YouTube视屏中习得了“猫”的概念,并在谷歌图片中开创了图片

    搜索的功能。使用DistBelief训练的语音识别模型成功将语音识别的错误

    率降低了25%。在一次BBC采访中,当时的谷歌首席执行官Eric Schmidt

    表示这个提高比率相当于之前十年的总和 (32)。

    虽然DistBelief已经被谷歌内部很多产品所使用,但是DistBelief过于依

    赖谷歌内部的系统架构,很难对外开源。为了将这样一个在谷歌内部已

    经获得了巨大成功的系统开源,谷歌大脑团队对DistBelief进行了改进,并于2015年11月正式公布了基于Apache 2.0开源协议的计算框架

    TensorFlow。相比DistBelief,TensorFlow的计算模型更加通用、计算速

    度更快、支持的计算平台更多、支持的深度学习算法更广而且系统的稳

    定性也更高。在本书后面的章节中,我们将重点介绍TensorFlow的使用,关于TensorFlow平台本身的技术细节可以参考谷歌的论文

    TensorFlow: Large-Scale Machine Learning on Heterogeneous Distributed

    Systems (33)。

    如今在谷歌内部,TensorFlow已经得到了广泛的应用。在2015年10月26

    日,谷歌正式宣布通过TensorFlow实现的排序系统RankBrain上线。相比

    一些传统的排序算法,使用RankBrain的排序结果更能满足用户需求。

    在2015年彭博(Bloomberg)的报道中 (34)

    ,谷歌透露了在谷歌上千种排

    序算法中,RankBrain是第三重要的排序算法。基于TensorFlow的系统

    RankBrain能在谷歌的核心网页搜索业务中占据如此重要的地位,可见

    TensorFlow在谷歌内部的重要性。包括网页搜索在内,TensorFlow已经

    被成功应用到了谷歌的各款产品之中。如今,在谷歌的语音搜索、广

    告、电商、图片、街景图、翻译、YouTube等众多产品之中都可以看到

    基于TensorFlow的系统 (35)。在经过半年的尝试和思考之后,谷歌的

    DeepMind团队也正式宣布其之后所有的研究都将使用TensorFlow (36)

    作为

    实现深度学习算法的工具。

    除了在谷歌内部大规模使用之外,TensorFlow也受到了工业界和学术界

    的广泛关注。在Google IO 2016的大会上,Jeff Dean提到已经有1500多

    个GitHub的代码库中提到了TensorFlow,而只有5个是谷歌官方提供

    的。如今,包括优步(Uber)、Snapchat、Twitter、京东、小米等国内

    外科技公司也纷纷加入了使用TensorFlow的行列。正如谷歌在

    TensorFlow开源原因中所提到的一样,TensorFlow正在建立一个标准,使得学术界可以更方便地交流学术研究成果,工业界可以更快地将机器

    学习应用于生产之中。

    除了TensorFlow,目前还有一些主流的深度学习开源工具。表1-2中总结

    了这些工具的主要情况。每款工具都有各自的特点,由于篇幅所限,在

    本书中不再一一介绍每一个工具目前的优缺点,感兴趣的读者可以参考

    脚注中每种工具的官方网站给出的信息。

    表1-2 主流的深度学习开源工具总结表 (37)

    工具名称

    主要维护人员(或团

    体)

    支持语言 支持系统 Caffe (38)

    加州大学伯克利分校

    视觉与学习中心

    C++、Python、MATLAB

    Linux、Mac

    OS X、Windows

    Deeplearning4j (39) Skymind

    Java、Scala、Clojure

    Linux、Windows、Mac OS X、Android

    Microsoft

    Cognitive

    Toolkit(CNTK)

    (40)

    微软研究院

    Python、C++、BrainScript

    Linux、Windows

    MXNet (41)

    分布式机器学习社区

    (DMLC)

    C++、Python、Julia、Matlab、Go、R、Scala

    Linux、Mac

    OS X、Windows、Android、iOS

    PaddlePaddle (42) 百度

    C++、Python

    Linux、Mac

    OS X

    TensorFlow 谷歌

    C++、Python

    Linux、Mac

    OS X、Android、iOS

    Theano (43) 蒙特利尔大学 Python

    Linux、Mac

    OS X、Windows

    Torch (44)

    Ronan Collobert、Soumith

    Chintala(Fackbook)

    Clement

    Farabet(Twitter)

    Koray

    Kavukcuoglu(Google)

    Lua、LuaJIT、C

    Linux、Mac

    OS X、Windows、Android、iOS 作者认为,不同的深度学习工具都在发展之中,比较当前的性能、功能

    固然是选择工具的一种方法,但更加重要的是比较不同工具的发展趋

    势。深度学习本身就是一个处于蓬勃发展阶段的领域,所以对深度学习

    工具的选择,作者认为应该更加看重工具在开源社区的活跃程度。只有

    社区活跃度更高的工具,才有可能跟上深度学习本身的发展速度,从而

    在未来不会面临被淘汰的风险。

    图1-11对比了不同深度学习工具在GitHub上活跃程度的一些指标。图1-

    11(a)中比较了不同工具在GitHub上受关注的程度。从图中可以看

    出,无论是在获得的星数(star)还是在仓库被复制的次数上,TensorFlow都要远远超过其他的深度学习工具。如果说图1-11(a)只能

    代表不同深度学习工具在社区受关注程度,那么图1-11(b)对比了不

    同深度学习工具社区参与度。图1-11(b)中展示了不同深度学习工具

    在GitHub上最近一个月的活跃讨论贴和代码提交请求数量。活跃讨论帖

    越多,可以说明真正使用这个工具的人也就越多;提交代码请求数量越

    多,可以说明参与到开发这个工具的人也就越多。从图1-11(b)中可

    以看出,无论从哪个指标,TensorFlow都要远远超过其他深度学习工

    具。大量的活跃开发者再加上谷歌的全力支持,作者相信TensorFlow在

    未来将有更大的潜力,这也是本书将TensorFlow作为介绍对象的重要依

    据。

    (a)不同深度学习工具社区流行度指标比较 (45)(b)不同深度学习工具社区参与度指标比较 (46)

    图1-11 不同深度学习工具在GitHub上活跃程度对比图

    小结

    本章对深度学习做了全方位的介绍。首先1.1节介绍了人工智能、机器

    学习以及深度学习的概念,并解释了这些概念之间的差异。人工智能是

    一类非常广泛的问题,它旨在通过计算机实现类似人类的智能。机器学

    习是解决人工智能问题的一个重要方法。深度学习则是机器学习的一个

    分支,它在很多领域突破了传统机器学习的瓶颈,将人工智能推向了一

    个新的高潮。然而,这样一个突破性的技术并不是最近几年凭空创造

    的,它所基于的人工神经网络(artificial neural network,ANN)技术已

    经发展了大半个世纪。不过神经网络的发展不是一帆风顺,1.2节完整

    的介绍了它发展的三个起落。

    受到人类大脑结构的启发,人工神经网络的计算模型于1943年首次提

    出。之后感知机的发明使得人工神经网络成为真正可以从数据中“学

    习”的模型。但由于感知机的网络结构过于简单,导致无法解决线性不

    可分问题。再加上人工神经网络所需要的计算量太大,当时的计算机无

    法满足计算需求,使得人工神经网络的研究进入了第一个寒冬。到20世

    纪80年代,深层神经网络和反向传播算法的提出很好地解决了这些问

    题,让人工神经网络进入第二个快速发展期。不过,在这一时期中,以

    支持向量机为主的传统机器学习算法也在飞速发展。在90年代中期,在

    很多机器学习任务上,传统机器学习算法超越了人工神经网络的精确

    度,使得人工神经网络领域再次进入寒冬。直到2012年前后,随着云计

    算和海量数据的普及,人工神经网络以“深度学习”的名字再次进入大家

    的视野。在短短几年时间内,深度学习在很多研究领域突破了传统机器学习的瓶颈,推动了人工智能的发展。

    人类大脑的结构分为了很多神经中枢,不同的神经中枢处理不同类型的

    输入。在很长一段时间,神经学家认为人类大脑不同的神经中枢有不同

    的处理逻辑。类似的,机器学习领域也一直分为计算机视觉、语音、自

    然语言处理等多个领域,而且不同领域使用的算法也有很大区别。然

    而,神经学家后来发现人类大脑不同神经中枢的学习算法是一致的。这

    使得人们看到了深度学习可以应用在多个领域的理论可能性。在实践

    中,深度学习也确实突破了很多领域的技术瓶颈。1.3节介绍了深度学

    习在计算机视觉、语音、自然语言处理、人机博弈等多个领域上的突破

    性进展。在ImageNet图像分类的问题上,深度学习成功将错误率从26%

    降低到了3.5%。在语音识别问题上,谷歌通过深度学习将错误率降低了

    25%,这一改进幅度是过去十年的总和。在自然语言处理上,基于深度

    学习的机器翻译、搜索排序、情感分析、自然语言建模等应用都已经在

    国内外各大科技公司内广泛使用。由谷歌DeepMind团队开发的围棋人

    机博弈系统AlphaGo更是激起了全社会对深度学习研究的热情。如今,深度学习已经渗透到了工业界和学术界的每一个领域。

    要利用好深度学习所带来的福利,选择一款好的深度学习工具必不可

    少。1.4节介绍了谷歌开源的深度学习工具TensorFlow的特性和在谷歌内

    部的应用,并将其和目前其他主流的开源深度学习工具做了比较。在谷

    歌内部,TensorFlow已经被成功应用到语音搜索、广告、电商、图片、街景图、翻译、YouTube等众多产品之中。基于TensorFlow开发的

    RankBrain排序算法在谷歌上千排序算法中排在第三重要的位置,由此

    可见TensorFlow在谷歌的重要地位。而且,对于TensorFlow的支持不仅

    仅来自谷歌。1.4节对比了不同开源深度学习工具的社区活跃度。在各

    种指标上,TensorFlow的活跃程度都要远远超过其他工具。所以,本书

    选择TensorFlow作为介绍的工具。在后面的章节中将具体介绍如何通过

    TensorFlow实现各种不同的深度学习算法,以及使用TensorFlow时的一

    些最佳实践。

    ————————————————————

    (1) 本节部分内容参见:Goodfellow I, Bengio Y, Courville A. Deep learning [M]. The MIT

    Press,2016.

    (2) 知识图库Ontology有时又被称为Knowledge Graph。Knowledge Graph更多的是指代谷歌内部

    建立的知识图库,而Ontology更多指代的是知识图库这个学术领域。(3) 更多关于WordNet的信息可以参考其官方网站:https:wordnet.princeton.edu。

    (4) Mitchell T M, Carbonell J G, Michalski R S. Machine Learning [M]. McGraw-Hill, 2003.

    (5) McCulloch W, Pitts W. A Logical Calculus of the Ideas Immanent in Nervous Activity [J]. Bulletin

    of Mathematical Biophysics Vol 5, 1943.

    (6) 具体报道参见:https:www.technologyreview.comliststechnologies2013。

    (7) 在ImageNet图像分类问题上,大部分研究都使用Top5错误率来评价模型优劣。第6章将更加

    详细地介绍ImageNet数据集。

    (8) http:image-net.orgchallengesLSVRC2013indextask 中有更多关于ILSVRC2013物体识别数

    据集的介绍。

    (9) 数字出自ILSVRC官网:http:image-net.orgchallengesLSVRC2016results 。

    (10) 图片来自于ILSVRC官网 :http:image-net.orgchallengesLSVRC2013。

    (11) 更多关于人脸识别数据集LFW的信息可以参考其官方网站:http:vis-

    www.cs.umass.edulfw。

    (12) 数字出自Yann LeCun教授在CERN研讨会上的报告 Deep Learning and the Future of AI 。报

    告资料可以参考:https:indico.cern.chevent510372。

    (13) SVHN数据集是斯坦福大学开源的数据集,更多关于该数据的信息可以参考其官方网站:

    http:ufldl.stanford.eduhousenumbers。

    (14) 数字参见:Goodfellow I J, Bulatov Y, Ibarz J, et al. Multi-digit Number Recognition from Street

    View Imagery using Deep Convolutional Neural Networks [J]. Computer Science, 2013.

    (15) 更多关于TIMIT数据集的信息可以参考其官方网站:https:catalog.ldc.upenn.eduldc93s1。

    (16) 参见:Li D. Achievements and Challenges of Deep Learning [J]. Apsipa Transactions on Signal

    Information Processing, 2015.

    (17) 演讲视频地址为http:v.youku.comv_showid_XNDcyOTUwNjMy.html。

    (18) 参见:Mikolov T, Sutskever I, Chen K, et al. Distributed Representations of Words and Phrases

    and their Compositionality [J]. Advances in Neural Information Processing Systems, 2013, 26.

    (19) 参见:Collobert R, Weston J, Bottou L, et al. Natural Language Processing (Almost) fromScratch [J]. Journal of Machine Learning Research, 2011.

    (20) 更多关于WordNet的资料可以参考其官方网站:https:wordnet.princeton.edu。

    (21) 更多关于ConceptNet的资料可以参考其官方网站:http:conceptnet5.media.mit.edu。

    (22) 更多关于FrameNet的资料可以参考其官方网站:https:framenet.icsi.berkeley.edufndrupal。

    (23) 具体关于GloVe的介绍可以参考其官方网站:http:nlp.stanford.eduprojectsglove。

    (24) 数字出自谷歌技术博客:https:research.googleblog.com201609a-neural-network-for-

    machine.html。

    (25) 此表中数据出自谷歌技术博客:https:research.googleblog.com201609a-neural-network-

    for-machine.html。

    (26) 参见:Bollen J, Mao H, Zeng X. Twitter mood predicts the stock market [J]. Journal of

    Computational Science , 2010.

    (27) 参见:O'Connor B, Balasubramanyan R, Routledge B R, et al. From Tweets to Polls: Linking

    Text Sentiment to Public Opinion Time Series [C] International Conference on Weblogs and Social

    Media, ICWSM 2010, Washington, Dc, Usa, May. DBLP, 2010.

    (28) http:nlp.stanford.edusentiment中给出了更多关于Sentiment Treebank的信息。

    (29) Socher R, Perelygin A, Wu J Y, et al. Recursive deep models for semantic compositionality over

    a sentiment treebank[J]. 2013.

    (30) 具体报道参见:https:deepmind.comblogdeepmind-and-blizzard-release-starcraft-ii-ai-

    research-environment。

    (31) 在第6章中将具体介绍ILSVRC比赛以及Inception模型。

    (32) 此数字来源于:http:www.csmonitor.comTechnology20150914Google-chairman-We-re-

    making-real-progress- on-artificial-intelligence。

    (33) 参见:Abadi M, Agarwal A, Barham P, et al. TensorFlow: Large-Scale Machine Learning on

    Heterogeneous Distributed Systems [J]. 2016.

    (34) 具体报道参见:https:www.bloomberg.comnewsarticles2015-10-26google-turning-its-

    lucrative-web-search-over- to-ai-machines。(35) TensorFlow官方网站:https:www.tensorflow.orgversionsr0.9resourcesuses.html上列出了

    一些使用TensorFlow的样例项目。

    (36) 具体报道参见谷歌官方技术博客:https:research.googleblog.com201604deepmind-moves-

    to-tensorflow.html。

    (37) 表中工具根据字母序排列。

    (38) Caffe官方网站:http:caffe.berkeleyvision.org。

    (39) Deeplearning4j 官方网站:https:deeplearning4j.org。

    (40) Microsoft Cognitive Toolkit官方网站:https:www.microsoft.comen-

    usresearchproductcognitive-toolkit。

    (41) MXNet官方网站:http:mxnet.io。

    (42) PaddlePaddle官方网站:http:www.paddlepaddle.org。

    (43) Theano官方网站:http:deeplearning.netsoftwaretheano。

    (44) Torch官方网站:http:torch.ch。

    (45) 图中数据获取的时间为2016年11月17日。

    (46) 图中数据来自于Github上2016年10月15日至2016年11月15日的统计数据。

    第2章 TensorFlow环境搭建

    本章将介绍如何安装TensorFlow环境以及在安装好的环境中运行简单的

    TensorFlow样例程序。在介绍如何安装TensorFlow之前,2.1节将首先介

    绍TensorFlow依赖的一些主要工具包。然后2.2节将介绍TensorFlow的不

    同安装方式以及这些安装方式所适用的不同的场景。最后2.3节将给出

    一个用TensorFlow完成向量加法的样例。通过这个样例程序,读者可以

    测试安装好的TensorFlow环境,同时也可以对TensorFlow有一个直观的

    认识。

    2.1 TensorFlow的主要依赖包本节将介绍TensorFlow依赖的两个最主要的工具包——Protocol Buffer和

    Bazel。虽然TensorFlow依赖的工具包不仅限于此节中列出来的两个,但

    Protocol Buffer和Bazel是作者认为相对比较重要的,在使用TensorFlow

    的过程中很有可能会接触到。因为本书的重点是介绍TensorFlow,所以

    在本节对列出来的工具包只进行大致的介绍,主要目的是为了不妨碍读

    者对TensorFlow的使用和理解。这些工具的详细介绍可以参考脚注。在

    以下的每个小节将介绍一个工具包的主要功能并给出简单的样例。

    2.1.1 Protocol Buffer

    Protocot Buffer

    (1)

    是谷歌开发的处理结构化数据的工具。何为处理结构化

    数据?这里我们给出一个例子。假设要记录一些用户信息,每个用户的

    信息包括用户的名字、ID和E-mail地址。那么一个用户的信息可以表示

    为以下的形式。

    name:张三

    id:12345

    email: zhangsan@abc.com

    上面的用户信息就是一个结构化的数据。注意本节中介绍的结构化数据

    和大数据中的结构化数据的概念不同,本节中介绍的结构化数据指的是

    拥有多种属性的数据。比如上述的用户信息中包含名字、ID和E-mail地

    址3种不同属性,那么它就是一个结构化数据。当要将这些结构化的用

    户信息持久化或者进行网络传输时,就需要先将它们序列化。所谓序列

    化,是将结构化的数据变成数据流的格式,简单地说就是变为一个字符

    串。如何将结构化的数据序列化,并从序列化之后的数据流中还原出原

    来的结构化数据,统称为处理结构化数据,这就是Protocol Buffer解决

    的主要问题。

    除Protocol Buffer之外, XML和JSON是两种比较常用的结构化数据处理

    工具。比如将上面的用户信息使用XML格式表达,那么数据的格式

    为:

    张三

    12345

    zhangsan@abc.com

    同样的数据,使用JSON的格式为:

    {

    name: 张三,id: 12345,email: “zhangsan@abc.com”,}

    Protocol Buffer格式的数据和XML或者JSON格式的数据有比较大的区

    别。首先,Protocol Buffer序列化之后得到的数据不是可读的字符串,而是二进制流。其次,XML或JSON格式的数据信息都包含在了序列化

    之后的数据中,不需要任何其他信息就能还原序列化之后的数据。但使

    用Protocol Buffer时需要先定义数据的格式(schema) (2)。还原一个序列

    化之后的数据将需要使用到这个定义好的数据格式。以下代码给出了上

    述用户信息样例的数据格式定义文件。因为这样的差别,Protocol

    Buffer序列化出来的数据要比XML格式的数据小3到10倍,解析时间要

    快20到100倍。

    message user{

    optional string name = 1;

    required int32 id = 2; repeated string email = 3;

    }

    Protocol Buffer定义数据格式的文件一般保存在.proto文件中。每一个

    message代表了一类结构化的数据,比如这里的用户信息。message里面

    定义了每一个属性的类型和名字。Protocol Buffer里属性的类型可以是

    像布尔型、整数型、实数型、字符型这样的基本类型,也可以是另外一

    个message。这样大大增加了Protocol Buffer的灵活性。在message中,Protocol Buffer也定义了一个属性是必须的(required)还是可选的

    (optional),或者是可重复的(repeated)。如果一个属性是必须的

    (required),那么所有这个message的实例都需要有这个属性 (3);如果

    一个属性是可选的(optional),那么这个属性的取值可以为空;如果

    一个属性是可重复的(repeated),那么这个属性的取值可以是一个列

    表。还是以用户信息为例,所有用户都需要有ID,所以ID这个属性是必

    须的;不是所有用户都填写了姓名,所以姓名这个属性是可选的;一个

    用户可能有多个E-mail地址,所以E-mail地址是可重复的。

    Protocol Buffur是TensorFlow系统中使用到的重要工具,TensorFlow中的

    数据基本都是通过Protocol Buffer来组织的。在后面的章节中将看到

    Protocol Buffer是如何被使用的。分布式TensorFlow的通信协议gRPC也

    是以Protocol Buffer作为基础的。

    2.1.2 Bazel

    Bazel

    (4)

    是从谷歌开源的自动化构建工具,谷歌内部绝大部分的应用都是

    通过它来编译的。相比传统的Makefile、Ant或者Maven,Bazel在速度、可伸缩性、灵活性以及对不同程序语言和平台的支持上都要更加出色。

    TensorFlow本身以及谷歌给出的很多官方样例都是通过Bazel来编译的。

    这一小节将简单介绍Bazel是怎样工作的。

    项目空间(workspace)是Bazel的一个基本概念 (5)。一个项目空间可以简

    单地理解为一个文件夹,在这个文件夹中包含了编译一个软件所需要的

    源代码以及输出编译结果的软连接(symbolic link)地址。一个项目空

    间内可以只包含一个应用(比如TensorFlow),这种情况在2.2.3小节中

    将会用于从源码安装TensorFlow。一个项目空间也可以包含多个应用。一个项目空间所对应的文件夹是这个项目的根目录,在这个根目录中需

    要有一个WORKSPACE文件,此文件定义了对外部资源的依赖关系。空

    文件也是一个合法的WORKSPACE文件。

    在一个项目空间内,Bazel通过BUILD文件来找到需要编译的目标 (6)。

    BUILD文件采用一种类似于Python的语法来指定每一个编译目标的输

    入、输出以及编译方式。与Makefile这种比较开放式的编译工具不同,Bazel的编译方式是事先定义好的。因为TensorFlow主要使用Python语

    言,所以这里都以编译Python程序为例。Bazel对Python支持的编译方式

    只有三种:py_binary、py_library和py_test

    (7)。其中py_binary将Python程

    序编译为可执行文件,py_test编译Python测试程序,py_library将Python

    程序编译成库函数供其他py_binary或py_test调用。下面给出了一个简单

    的样例来说明Bazel是如何工作的。如下所示,在样例项目空间中有4个

    文件:WORKSPACE、BUILD、hello_main.py 和hello_lib.py。

    -rw-rw-r-- root root 208 BUILD

    -rw-rw-r-- root root 48 hello_lib.py

    -rw-rw-r-- root root 47 hello_main.py

    -rw-rw-r-- root root 0 WORKSPACE

    WORKSPACE给出此项目的外部依赖关系。为了简单起见,这里使用一

    个空文件,标明这个项目没有对外部的依赖。hello_lib.py完成打

    印“Hello World”的简单功能,它的代码如下:

    def print_hello_world:

    print(Hello World)

    hello_main.py通过调用hello_lib.py中定义的函数来完成输出,它的代码

    如下: import hello_lib

    hello_lib.print_hello_world

    在BUILD文件中定义了两个编译目标:

    py_library(

    name = hello_lib,srcs = [

    hello_lib.py,])

    py_binary(

    name = hello_main,srcs = [

    hello_main.py,],deps = [

    :hello_lib,],)

    从这个样例中可以看出,BUILD文件是由一系列编译目标组成的。定义

    编译目标的先后顺序不会影响编译的结果。在每一个编译目标的第一行

    要指定编译方式,在这个样例中就是py_library或者py_binary。在每一

    个编译目标中的主体需要给出编译的具体信息。编译的具体信息是通过

    定义name,srcs,deps等属性完成的。name是一个编译目标的名字,这个名字将被用来指代这一条编译目标。srcs给出了编译所需要的源代

    码,这一项可以是一个列表。deps给出了编译所需要的依赖关系,比如

    样例中hello_main.py需要调用hello_lib.py中的函数,所以hello_main的编

    译目标中将hello_lib作为依赖关系。在这个项目空间中运行编译操作

    bazel build :hello_main将得到类似以下的结果:

    从上面的结果可以看到,在原来4个文件的基础上,Bazel生成了其他一

    些文件夹。这些新生成的文件夹就是编译的结果,它们都是通过软连接

    的形式放在当前的项目空间里。实际的编译结果文件都会保存到

    ~.cachebazel目录下,这是可以通过output_user_root或者output_base参

    数来改变的 (8)。在这些编译出来的结果当中,bazel-bin目录下存放了编

    译产生的二进制文件以及运行该二进制文件所需要的所有依赖关系。在

    当前目录下运行bazel-binhello_main就会在屏幕输出“Hello World”。其

    他编译结果在本书中使用较少,这里就不再赘述。

    2.2 TensorFlow安装

    TensorFlow提供了多种不同的安装方式,本小节将逐一介绍通过Docker

    安装、通过pip安装以及从源码安装。

    2.2.1 使用Docker安装

    Docker

    (9)

    是新一代的虚拟化技术,它可以将TensorFlow以及TensorFlow

    的所有依赖关系统一封装到Docker镜像当中,从而大大简化了安装过

    程。通过Docker运行应用时需要先安装Docker。Docker支持大部分的操

    作系统,下面列出了最主要的一些。

    Linux系统:Ubuntu、CentOS、Debian、红帽企业版(Red Hat

    Enterprise Linux)等。

    Mac OS X :10.10.3 Yosemite或以上。

    Windows :Windows 7或以上。如何安装使用Docker不是本书重点,这里就不再介绍在不同操作系统

    下如何安装Docker

    (10)。当Docker安装完成后,只需要使用一个打包好的

    Docker镜像。对于TensorFlow发布的每一个版本,谷歌都提供了4个官

    方镜像。表2-1给出了这些镜像的名称以及镜像中的包含的内容。

    表2-1 TensorFlow官方Docker镜像列表

    镜像名称 是否支持GPU 是否含有源码

    tensorflowtensorflow:0.9.0 否 否

    tensorflowtensorflow:0.9.0-

    devel

    否 是

    tensorflowtensorflow:0.9.0-

    gpu

    是 否

    tensorflowtensorflow:0.9.0-

    devel-gpu

    是 是

    镜像的标签(冒号后面的部分)给出了TensorFlow的版本。本书的绝大

    部分代码将统一使用版本0.9.0 (11)。才云科技也提供了TensorFlow的相关

    镜像cargo.caicloud.iotensorflow tensorflow:0.12.0 (12)。与官方镜像类似,0.12.0表示TensorFlow版本。如果TensorFlow推出更新的版本,此版本号

    可以被替换为更新的版本号。在官方镜像的基础上,才云科技提供的镜

    像进一步整合了其他机器学习工具包以及TensorFlow可视化工具

    TensorBoard (13)

    ,使用起来可以更加方便。才云科技即将上线TensorFlow

    的公有云平台caicloud.io,在此平台上可以直接运行TensorFlow程序,从而省去了安装的过程。

    当Docker安装完成之后,可以通过以下命令来启动一个TensorFlow容器 (14)。在第一次运行的时候,Docker会自动下载镜像。

    docker run -it -p 8888:8888 –p 6006:6006 cargo.caicloud.iotensorflow tensorflow:0.12.0在这个命令中,-p 8888:8888 将容器内运行的Jupyter

    (15)

    服务映射到本地

    机器,这样在浏览器中打开localhost:8888就能看到类似下图的Jupyter界

    面。在此镜像中运行的Jupyter是一个网页版的代码编辑器,它支持创

    建、上传、修改和运行Python程序。通过Jupyter,才云科技提供了本书

    所有的样例程序,如图2-1所示。

    图2-1 才云科技提供的TensorFlow镜像Jupyter页面示意图

    -p 6006:6006将容器内运行的TensorFlow可视化工具TensorBoard映射到

    本地机器,通过在浏览器中打开localhost:6006就可以将TensorFlow在训

    练时的状态、图片数据以及神经网络结构等信息全部展示出来。此镜像

    会将所有输出到log目录底下的日志全部可视化。具体如何使用

    TensorBoard将在第9章中详细介绍。

    虽然支持GPU的Docker镜像,但是要运行这些镜像需要安装最新的

    Nvidia驱动以及nvidia-docker

    (16)。在安装完成nvidia-docker之后,可以通

    过以下的命令运行支持GPU的TensorFlow镜像。在镜像启动之后可以通

    过和上面类似的方式使用TensorFlow。

    nvidia-docker run -it -p 8888:8888 –p 6006:6006 cargo.caicloud.iotensorflowtensorflow:0.12.0-gpu

    2.2.2 使用pip安装pip是一个安装、管理Python软件包的工具 (17)

    ,通过pip可以安装已经打

    包好的TensorFlow以及TensorFlow所需要的依赖关系。目前TensorFlow

    只提供了部分操作系统下打包好的安装文件,在其他操作系统下安装或

    者需要安装定制化代码的TensorFlow请参考2.2.3小节。通过pip安装可以

    分为以下三步。

    第一步:安装pip

    在UbuntuLinux 64-bit环境下安装。

    sudo apt-get install python-pip python-dev

    在Mac OS X环境下安装。

    sudo easy_install pip

    sudo easy_install --upgrade six

    第二步:找到合适的安装包URL

    仅支持CPU的TensorFlow安装包有:

    UbuntuLinux 64-bit, Python 2.7环境。

    export TF_BINARY_URL=https:storage.googleapis.comtensorflowlinux cputensorflow-

    0.9.0-cp27-none-linux_x86_64.whl

    UbuntuLinux 64-bit, Python 3.4环境。

    export TF_BINARY_URL=https:storage.googleapis.comtensorflowlinux cputensorflow-

    0.9.0-cp34-cp34m-linux_x86_64.whl

    UbuntuLinux 64-bit, CPU only, Python 3.5环境。 export TF_BINARY_URL=https:storage.googleapis.comtensorflowlinux cputensorflow-

    0.9.0-cp35-cp35m-linux_x86_64.whl

    Mac OS X, Python 2.7环境。

    export TF_BINARY_URL=https:storage.googleapis.comtensorflowmac tensorflow-

    0.9.0-py2-none-any.whl

    Mac OS X, Python 3.4 or 3.5环境。

    export TF_BINARY_URL=https:storage.googleapis.comtensorflowmac tensorflow-

    0.9.0-py3-none-any.whl

    目前只有在安装了CUDA toolkit 7.5和CuDNN v4的64位Ubuntu下可以通

    过pip安装支持GPU的TensorFlow,对于其他系统或者其他

    CUDACuDNN版本的用户,则需要从源码进行安装来支持GPU使用。

    如何从源码进行安装将在2.2.3小节中详述。下面给出了支持GPU的

    TensorFlow pip安装包的URL:

    Python 2.7 环境

    export TF_BINARY_URL=https:storage.googleapis.comtensorflowlinux gputensorflow-

    0.9.0-cp27-none-linux_x86_64.whl

    Python 3.4环境

    export TF_BINARY_URL=https:storage.googleapis.comtensorflowlinux gputensorflow-

    0.9.0-cp34-cp34m-linux_x86_64.whl

    Python 3.5环境

    export TF_BINARY_URL=https:storage.googleapis.comtensorflowlinux gputensorflow-

    0.9.0-cp35-cp35m-linux_x86_64.whl第三步:通过pip安装TensorFlow

    Python 2环境

    sudo pip install --upgrade TF_BINARY_URL

    Python 3环境

    sudo pip3 install --upgrade TF_BINARY_URL

    通过这三步,TensorFlow环境就安装完成了。

    2.2.3 从源代码编译安装

    从源代码安装TensorFlow的过程主要就是将TensorFlow源代码编译成pip

    安装包的过程。将TensorFlow的源代码编译为pip所使用的wheel文件之

    后,通过2.2.2小节中介绍的pip install的方法就可以完成安装。在编译

    TensorFlow源代码之前需要先安装TensorFlow所依赖的其他工具包。不

    同操作系统下需要安装的工具包略微有一些差别,而且在不同操作系统

    下安装这些工具包的方法也不大一样,这一小节将以Ubuntu 14.04和

    Mac OS X为例来介绍如何安装TensorFlow依赖的工具包 (18)。

    在Ubuntu 14.04下安装依赖的工具包

    首先需要安装2.1.2小节中介绍的编译工具Bazel。安装Bazel,首先要安

    装JDK8。以下代码给出了安装JDK8的方法。

    sudo apt-get install software-properties-common

    sudo add-apt-repository ppa:webupd8teamjava

    sudo apt-get update

    sudo apt-get install oracle-java8-installer然后安装Bazel的其他依赖的工具包:

    sudo apt-get install pkg-config zip g++ zlib1g-dev unzip

    接着在Bazel的GitHub发布页面下载安装包

    (https:github.combazelbuildbazelreleasestag0.3.1)。其中0.3.1为

    Bazel的版本号。如果有更新的版本,可以相应的替换上面连接中的版

    本号。在这个页面中下载安装包bazel-0.3.1-jdk7-installer-linux-

    x86_64.sh,然后就可以通过这个安装包来安装Bazel。以下代码实现了

    Bazel的安装过程。

    chmod +x bazel-0.3.1-jdk7-installer-linux-x86_64.sh

    .bazel-0.3.1-jdk7-installer-linux-x86_64.sh –user (19)

    export PATH=PATH:HOMEbin

    Bazel安装完成后还需要通过以下代码来安装TensorFlow的依赖的其他工

    具包。

    Python 2.7环境

    sudo apt-get install python-numpy swig python-dev python-

    wheel

    Python 3.x环境

    sudo apt-get install python3-numpy swig python3-

    dev python3-wheel

    如果要支持GPU,那么还需要安装Nvidia的Cuda Toolkit(版本需要大于

    或等于7.0)和cuDNN(版本需要大于或等于v2)。而且TensorFlow只支持Nvidia计算能力(compute capability)大于3.0的GPU。比如Nvidia

    Titan、Nvidia Titan X、Nvidia K20、Nvidia K40等都满足要求 (20)。

    Cuda Toolkit的安装包以及安装方法可登录

    https:developer.nvidia.comcuda-downloads获得。在根据引导填写完操

    作系统相关参数之后,该网站将提供Cuda 7.5的安装包及详细安装方

    法。登录https:developer.nvidia.comcudnn可下载cuDNN的安装包。在

    下载之前需要先注册,但注册是完全免费的。注册完成后可以下载

    cuDNN v4 Library for Linux,其中v4可以替换成更新的版本。下载完成

    后,需要通过以下命令把下载下来的安装包复制到Cuda的目录(这里假

    设是usrlocalcuda):

    tar xvzf cudnn-7.5-linux-x64-v4.tgz

    sudo cp cudnn-7.5-linux-x64-

    v4cudnn.h usrlocalcudainclude

    sudo cp cudnn-7.5-linux-x64-

    v4libcudnn usrlocalcudalib64

    sudo chmod a+r usrlocalcudaincludecudnn.h usrlocalcudalib64 libcudnn

    在Mac OS X下安装依赖工具包

    Homebrew是Mac OS X下一个软件安装工具 (21)

    ,通过这个工具可以很方

    便地安装比如Bazel,SWIG等TensorFlow的依赖工具。Homebrew自己的

    安装过程也很简单,以下代码给出了它的安装方法:

    usrbinruby -e (curl -fsSL https:raw.githubusercontent.comHomebrewinstallmasterinstall)

    安装完Homebrew后就可以通过brew来安装Bazel和SWIG: brew install bazel swig

    然后可以通过easy_install来安装Python相关的依赖工具:

    sudo easy_install -U six

    sudo easy_install -U numpy

    sudo easy_install wheel

    sudo easy_install ipython

    如果需要支持GPU,在安装Cuda Toolkit和cuDNN之前,还需要通过

    Homebrew安装GNU coreutils:

    brew install coreutils

    和Ubuntu 14.04类似,https:developer.nvidia.comcuda-downloads网站提

    供了安装最新Cuda Toolkit的安装包与安装方法。但在Mac OS X下可以

    通过Homebrew Cask来直接安装:

    brew tap caskroomcask

    brew cask install cuda

    Cuda Toolkit安装完成之后需要将环境变量加入到~.bash_profile文件

    中:

    export CUDA_HOME=usrlocalcuda export DYLD_LIBRARY_PATH=DYLD_LIBRARY_PATH:CUDA_HOMElib

    export PATH=CUDA_HOMEbin:PATH

    https:developer.nvidia.comcudnn网站提供了cuDNN的安装包。在下载

    之前这个网站需要先注册,注册是完全免费的。注册完成后可以下载

    cuDNN v4 Library for OS X,其中v4可以替换成更新的版本。下载完成

    后需要将文件解压并放到Cuda Toolkit的目录下。以下代码完成了这个

    过程:

    sudo mv includecudnn.h DeveloperNVIDIACUDA-7.5include

    sudo mv liblibcudnn DeveloperNVIDIACUDA-7.5lib

    sudo ln -s DeveloperNVIDIACUDA-

    7.5liblibcudnn usrlocalcudalib

    配置TensorFlow编译环境

    在所有依赖的工具包都安装完成之后就可以开始从源码来安装

    TensorFlow了。无论在哪个操作系统下,要从源代码开始安装,首先需

    要下载源代码。通过以下命令可以下载最新的TensorFlow源代码:

    git clone https:github.comtensorflowtensorflow

    使用以上命令将下载TensorFlow最新的代码。如果需要下载之前发布的

    版本,可以在上述命令中加入-b 参数。其中

    可以是r0.7、r0.8、r0.9等。如果安装r0.8或者更老的版本,还需要在上

    述命令中加入--recurse-submodules参数来拉取TensorFlow依赖的其他工

    具。源码下载完成之后,需要运行configure脚本来配置环境信息:

    cd tensorflow

    .configure 配置Python的路径。

    Please specify the location of python. [Default is usrbinpython]:

    配置是否支持谷歌云平台。

    Do you wish to build TensorFlow with Google Cloud Platform support? [yN]N

    No Google Cloud Platform support will be enabled for TensorFlow

    配置是否支持GPU。

    Do you wish to build TensorFlow with GPU support? [yN] y

    GPU support will be enabled for TensorFlow

    配置GPU。

    Please specify which gcc nvcc should use as the host compiler. [Default is usrbingcc]:

    配置Cuda SDK版本。

    Please specify the Cuda SDK version you want to use, e.g. 7.0. [Leave empty to use system default]: 7.5

    配置CUDA toolkit目录。

    Please specify the location where CUDA 7.5 toolkit is installed. Refer to README.md for more details. [Default is usrlocalcuda]:

    配置Cudnn版本。

    Please specify the Cudnn version you want to use. [Leave empty to use system default]: 4

    配置cuDNN目录。

    Please specify the location where cuDNN 4 library is installed. Refer to README.md for more details. [Default is usrlocalcuda]:

    配置GPU计算能力。

    Please specify a list of comma-

    separated Cuda compute capabilities you want to build with.

    You can find the compute capability of your device at: https:developer. nvidia.comcuda-

    gpus.

    Please note that each additional compute capability significantly increases your build time and binary size.

    Setting up Cuda include

    Setting up Cuda lib

    Setting up Cuda bin

    Setting up Cuda nvvm

    Setting up CUPTI include

    Setting up CUPTI lib64

    Configuration finished

    当环境配置完成之后通过Bazel来编译pip的安装包,然后通过pip安装:

    bazel build -c opt --config=cuda tensorflowtoolspip_package:build_ pip_package

    bazel-bintensorflowtoolspip_packagebuild_pip_package tmptensorflow_ pkg

    sudo pip install tmptensorflow_pkgtensorflow-0.9.0-py2-

    none-any.whl

    第一个命令中--config=cuda参数为对GPU的支持。如果不需要支持

    GPU,就不需要这个参数了。最后一行中wheel安装包的名字

    (tensorflow-0.9.0-py2-none-any.whl)和系统环境有关,使用pip安装之

    前可以先通过ls命令来确认安装包的名字。

    2.3 TensorFlow测试样例

    通过2.2节中介绍的方法安装好TensorFlow后,在这一节中将给出一个简

    单的TensorFlow样例程序来实现两个向量求和。TensorFlow支持C、C++和Python三种语言,但是它对Python的支持是最全面的,所以本书

    中所有的样例都会使用Python语言。通过本节给出来的简单样例,读者可以测试安装好的TensorFlow环境,同时也可以对TensorFlow有一个直

    观的认识。这一节将直接使用Python自带的交互界面来演示这个简单样

    例:

    在进入Python交互界面之后,先通过import操作加载TensorFlow:

    上图显示TensorFlow已经成功加载了。Python可以通过重命名来使引用

    更加方便,在本书中都会将“tensorflow”简写为“tf”。然后定义两个向

    量,a和b:

    在这里将a和b定义为了两个常量(tf.constant),一个为[1.0,2.0],另一个

    为[2.0,3.0]。在两个加数定义好之后,将这两个向量加起来:

    熟悉NumPy (22)

    的读者会发现,在TensorFlow之中,向量的加法也是可以

    直接通过加号(+)来完成的。最后输出相加得到的结果:

    要输出相加得到的结果,不能简单地直接输出result,而需要先生成一

    个会话(session),并通过一个这个会话(session)来计算结果。到

    此,就实现了一个非常简单的TensorFlow模型。第3章将更加深入地介

    绍TensorFlow的基本概念,并将TensorFlow的计算模型和神经网络模型

    结合起来。

    小结

    在本章中首先介绍了TensorFlow主要依赖的两个工具——Protocol Buffer和Bazel。Protocol Buffer是一个结构数据序列化的工具,在TensorFlow

    中大部分数据结构都是通过Protocol Buffer的形式存储的。Bazel是一个

    谷歌开源的编译工具,在2.2节中讲解了如何通过Bazel编译TensorFlow

    的源代码。谷歌官方给出的大部分样例程序也是通过Bazel编译的。

    在介绍完TensorFlow所依赖的工具之后,2.2节讲解了TensorFlow的不同

    安装方式,以及不同安装方式适用的不同场景。2.2.1小节中介绍的

    Docker是可移植性最强的一种安装方式,它支持大部分的操作系统(比

    如Windows,Linux和Mac OS)。但Docker目前对GPU的支持有限,而

    且Docker对本地开发环境的支持也不够友好。在本地最方便的安装方式

    是使用pip。使用pip可以将已经打包好的安装包安装到本地。谷歌官方

    提供了不同版本TensorFlow的pip安装包。这种方式比较适合在本地开发

    TensorFlow的应用程序,但无法修改TensorFlow本身。最后一种方法就

    是从源码安装,这种方式最灵活,但比较烦琐。一般只有需要修改

    TensorFlow本身或者需要支持比较特殊的GPU时才会被用到。

    在本章的最后一节中给出了一个非常简短的TensorFlow测试样例。这个

    样例程序完成了两个向量加法的功能。通过这个样例可以测试安装好的

    TensorFlow环境,同时也可以对TensorFlow有一个直观的感受。在第3章

    中将更加详细地介绍TensorFlow中的基本概念,并讲解如何通过

    TensorFlow来实现一个简单神经网络的训练过程。

    ————————————————————

    (1) https:developers.google.comprotocol-buffersdocsoverview中给出了更多关于Protocol Buffer

    的介绍。

    (2) https:developers.google.comprotocol-buffersdocsencoding 中给出了Protocol Buffer的具体编

    码方式。

    (3) 在最新的Protocol Buffer3中已经不再支持required类型。

    (4) http:www.bazel.io 中给出了关于Bazel的更多介绍。

    (5) http:www.bazel.iodocsbeworkspace.html 中给出了项目空间的完整文档和开发手册。

    (6) http:www.bazel.iodocsbeoverview.html 中给出了BUILD文件的完整文档和开发手册。

    (7) http:www.bazel.iodocstest-encyclopedia.html 中给出了更多关于测试目标的介绍。(8) http:www.bazel.iodocsoutput_directories.html 中详细介绍了编译结果的目录结构。

    (9) https:www.docker.comwhat-docker 中详细介绍了Docker的基本概念。

    (10) https:docs.docker.comengineinstallation 中介绍了在不同操作系统下如何安装Docker。

    (11) 因为0.9.0对循环神经网络支持不是特别友好,所以第8章部分代码使用了版本0.10.0。在本

    书中,使用了其他版本的样例代码都给出了明确的注释。

    (12) 才云科技只提供0.12.0及以上版本的TensorFlow镜像。

    (13) 第9章将更加详细地介绍如何使用TensorFlow可视化工具TensorBoard。

    (14) https:docs.docker.comenginereferencecommandlinecli 中给出了Docker命令的文档。

    (15) http:jupyter.org 中给出了对Jupyter更加详细的介绍。

    (16) https:github.comNVIDIAnvidia-docker 中介绍了nvidia-docker的基本原理和安装说明。

    (17) https:pip.pypa.io 中给出pip的文档。

    (18) 其他版本的Linux可以参考Ubuntu 14.04下的安装方法。 目前TensorFlow没有比较好的支持

    在Windows下从源码安装,Windows用户可以通过2.2.1节中介绍的Docker来使用TensorFlow。

    (19) 具体下载地址参考官方网站https:bazel.buildversionsmasterdocsinstall.html。

    (20) https:developer.nvidia.comcuda-gpus中列出了所有GPU的计算能力。

    (21) http:brew.sh 中介绍Homebrew的功能。

    (22) NumPy是一个科学计算的Python工具包,http:www.numpy.org 中给出了更多关于NumPy的

    介绍。

    第3章 TensorFlow入门

    在第2章中介绍了如何安装TensorFlow,并且在安装好的TensorFlow中运

    行了一个简单的向量相加的样例。本章将详细地介绍TensorFlow基本概

    念。在本章的前3节中,将分别介绍TensorFlow的计算模型、数据模型

    和运行模型。通过这三个角度对TensorFlow的介绍,读者可以对TensorFlow的工作原理有一个大致的了解。在本章的最后一节中,将简

    单介绍神经网络的主要计算流程,并介绍如何通过TensorFlow实现这些

    计算。

    3.1 TensorFlow计算模型——计算图

    计算图是TensorFlow中最基本的一个概念,TensorFlow中的所有计算都

    会被转化为计算图上的节点。3.1.1小节将详细介绍TensorFlow中计算图

    的基本概念,然后在3.1.2小节中将通过一些简单的样例程序说明

    TensorFlow计算图的使用方法。

    3.1.1 计算图的概念

    TensorFlow的名字中已经说明了它最重要的两个概念——Tensor和

    Flow。Tensor就是张量。张量这个概念在数学或者物理学中可以有不同

    的解释,但在本书中并不强调它本身的含义。在TensorFlow中,张量可

    以被简单地理解为多维数组,在3.2节中将对张量做更加详细的介绍。

    如果说TensorFlow的第一个词Tensor表明了它的数据结构,那么Flow则

    体现了它的计算模型。Flow翻译成中文就是“流”,它直观地表达了张量

    之间通过计算相互转化的过程。TensorFlow是一个通过计算图的形式来

    表述计算的编程系统。TensorFlow中的每一个计算都是计算图上的一个

    节点,而节点之间的边描述了计算之间的依赖关系。图3-1展示了通过

    TensorBoard (1)

    画出来的第2章中两个向量相加样例的计算图。

    图3-1 通过TensorBoard可视化向量相加的计算图

    图3-1中的每一个节点都是一个运算,而每一条边代表了计算之间的依

    赖关系。如果一个运算的输入依赖于另一个运算的输出,那么这两个运算有依赖关系。在图3-1中,a和b这两个常量不依赖任何其他计算 (2)。而

    add计算则依赖读取两个常量的取值。于是在图3-1中可以看到有一条从

    a到add的边和一条从b到add的边。在图3-1中,没有任何计算依赖add的

    结果,于是代表加法的节点add没有任何指向其他节点的边。所有

    TensorFlow的程序都可以通过类似图3-1所示的计算图的形式来表示,这

    就是TensorFlow的基本计算模型。

    3.1.2 计算图的使用

    一个阶段需要定义计算图中所有的计算。比如在第2章的向量加法样例

    程序中首先定义了两个输入,然后定义了一个计算来得到它们的和。第

    二个阶段为执行计算,这个阶段将在3.3节中介绍。以下代码给出了计

    算定义阶段的样例。

    import tensorflow as tf

    a = tf.constant([1.0, 2.0], name=a)

    b = tf.constant([2.0, 3.0], name=b)

    result = a + b

    在Python中一般会采用“import tensorflow as tf”的形式来载入

    TensorFlow,这样可以使用“tf”来代替“tensorflow”作为模块名称,使得

    整个程序更加简洁。这是TensorFlow中非常常用的技巧,在本书后面的

    章节中将会全部采用这种加载方式。在这个过程中,TensorFlow会自动

    将定义的计算转化为计算图上的节点。在TensorFlow程序中,系统会自

    动维护一个默认的计算图,通过tf.get_default_graph函数可以获取当前默

    认的计算图。以下代码示意了如何获取默认计算图以及如何查看一个运

    算所属的计算图。

    通过a.graph可以查看张量所属的计算图。因为没有特意指定,所以这个计算图

    应该等于

    当前默认的计算图。所以下面这个操作输出值为True。 print(a.graph is tf.get_default_graph)

    除了使用默认的计算图,TensorFlow支持通过tf.Graph函数来生成新的计

    算图。不同计算图上的张量和运算都不会共享。以下代码示意了如何在

    不同计算图上定义和使用变量 (3)。

    import tensorflow as tf

    g1 = tf.Graph

    with g1.as_default:

    在计算图g1中定义变量“v”,并设置初始值为0。

    v = tf.get_variable(

    v, initializer=tf.zeros_initializer(shape=[1]))

    g2 = tf.Graph

    with g2.as_default:

    在计算图g2中定义变量“v”,并设置初始值为1。

    v = tf.get_variable(

    v, initializer=tf.ones_initializer(shape=[1]))

    在计算图g1中读取变量“v”的取值。

    with tf.Session(graph=g1) as sess:

    tf.initialize_all_variables.run

    with tf.variable_scope(, reuse=True): 在计算图g1中,变量“v”的取值应该为0,所以下面这行会输出

    [0.]。

    print(sess.run(tf.get_variable(v)))

    在计算图g2中读取变量“v”的取值。

    with tf.Session(graph=g2) as sess:

    tf.initialize_all_variables.run

    with tf.variable_scope(, reuse=True):

    在计算图g2中,变量“v”的取值应该为1,所以下面这行会输出

    [1.]。

    print(sess.run(tf.get_variable(v)))

    上面的代码产生了两个计算图,每个计算图中定义了一个名字为“v”的

    变量。在计算图g1中,将v初始化为0;在计算图g2中,将v初始化为1。

    可以看到当运行不同计算图时,变量v的值也是不一样的。TensorFlow

    中的计算图不仅仅可以用来隔离张量和计算,它还提供了管理张量和计

    算的机制。计算图可以通过tf.Graph.device函数来指定运行计算的设

    备。这为TensorFlow使用GPU提供了机制。下面的程序可以将加法计算

    跑在GPU上。

    g = tf.Graph

    指定计算运行的设备。

    with g.device('gpu:0'):

    result = a + b

    具体使用GPU的方法将在第10章详述。有效地整理TensorFlow程序中的

    资源也是计算图的一个重要功能。在一个计算图中,可以通过集合

    (collection)来管理不同类别的资源。比如通过tf.add_to_collection函数

    可以将资源加入一个或多个集合中,然后通过tf.get_collection获取一个集合里面的所有资源。这里的资源可以是张量、变量或者运行

    TensorFlow程序所需要的队列资源,等等。为了方便使用,TensorFlow

    也自动管理了一些最常用的集合,表3-1总结了最常用的几个自动维护

    的集合。

    表3-1 TensorFlow中维护的集合列表

    集合名称 集合内容 使用场景

    tf.GraphKeys.VARIABLES 所有变量

    持久化

    TensorFlow

    模型

    tf.GraphKeys.TRAINABLE_VARIABLES

    可学习的变

    量(一般指神

    经网络中的参

    数)

    模型训

    练、生成模

    型可视化内

    容

    tf.GraphKeys.SUMMARIES

    日志生成相

    关的张量

    TensorFlow

    计算可视

    化

    tf.GraphKeys.QUEUE_RUNNERS

    处理输入的

    QueueRunner

    输入处理

    tf.GraphKeys.MOVING_AVERAGE_VARIABLES

    所有计算了

    滑动平均值的

    变量

    计算变量

    的滑动平均

    值

    3.2 TensorFlow数据模型——张量

    3.1节介绍了使用计算图的模型来描述TensorFlow中的计算。这一节将介

    绍TensorFlow中另外一个基础概念——张量。张量是TensorFlow管理数

    据的形式,在3.2.1小节中将介绍张量的一些基本属性。然后在3.2.2小节

    中将介绍如何通过张量来保存和获取TensorFlow计算的结果。

    3.2.1 张量的概念从TensorFlow的名字就可以看出张量(tensor)是一个很重要的概念。

    在TensorFlow程序中,所有的数据都通过张量的形式来表示。从功能的

    角度上看,张量可以被简单理解为多维数组。其中零阶张量表示标量

    (scalar),也就是一个数 (4);第一阶张量为向量(vector),也就是一

    个一维数组;第n 阶张量可以理解为一个n 维数组。但张量在

    TensorFlow中的实现并不是直接采用数组的形式,它只是对TensorFlow

    中运算结果的引用。在张量中并没有真正保存数字,它保存的是如何得

    到这些数字的计算过程。还是以向量加法为例,当运行如下代码时,并

    不会得到加法的结果,而会得到对结果的一个引用。

    import tensorflow as tf

    tf.constant是一个计算,这个计算的结果为一个张量,保存在变量a中。

    a = tf.constant([1.0, 2.0], name=a)

    b = tf.constant([2.0, 3.0], name=b)

    result = tf.add(a, b, name=add)

    print result

    '''

    输出:

    Tensor(add:0, shape=(2,), dtype=float32)

    '''

    从上面的代码可以看出TensorFlow中的张量和NumPy中的数组不同,TensorFlow计算的结果不是一个具体的数字,而且一个张量的结构。从

    上面代码的运行结果可以看出,一个张量中主要保存了三个属性:名字

    (name)、维度(shape)和类型(type)。

    张量的第一个属性名字不仅是一个张量的唯一标识符,它同样也给出了

    这个张量是如何计算出来的。在3.1.2小节中介绍了TensorFlow的计算都

    可以通过计算图的模型来建立,而计算图上的每一个节点代表了一个计

    算,计算的结果就保存在张量之中。所以张量和计算图上节点所代表的计算结果是对应的。这样张量的命名就可以通过“node:src_output”的形

    式来给出。其中node为节点的名称,src_output表示当前张量来自节点的

    第几个输出。比如上面代码打出来的“add:0”就说明了result这个张量是

    计算节点“add”输出的第一个结果(编号从0开始)。

    张量的第二个属性是张量的维度(shape)。这个属性描述了一个张量

    的维度信息。比如上面样例中shape=(2,)说明了张量result是一个一维数

    组,这个数组的长度为2。维度是张量一个很重要的属性,围绕张量的

    维度TensorFlow也给出了很多有用的运算,在这里先不一一列举,在后

    面的章节中将使用到部分运算。

    张量的第三个属性是类型(type),每一个张量会有一个唯一的类型。

    TensorFlow会对参与运算的所有张量进行类型的检查,当发现类型不匹

    配时会报错。比如运行下面这段程序时就会得到类型不匹配的错误:

    import tensorflow as tf

    a = tf.constant([1, 2], name=a)

    b = tf.constant([2.0, 3.0], name=b)

    result = a + b

    这段程序和上面的样例基本一模一样,唯一不同的是把其中一个加数的

    小数点去掉了。这会使得加数a的类型为整数而加数b的类型为实数,这

    样程序会报类型不匹配的错误:

    ValueError: Tensor conversion requested dtype int32 for Tensor with dtype float32: 'Tensor(b:0, shape=

    (2,), dtype=float32)'

    如果将第一个加数指定成实数类型“a = tf.constant([1, 2], name=a,dtype=tf.float32)”,那么两个加数的类型相同就不会报错了。如果不指

    定类型,TensorFlow会给出默认的类型,比如不带小数点的数会被默认

    为int32,带小数点的会默认为float32。因为使用默认类型有可能会导致

    潜在的类型不匹配问题,所以一般建议通过指定dtype来明确指出变量或者常量的类型。TensorFlow支持14种不同的类型,主要包括了实数

    (tf.float32、 tf.float64)、整数(tf.int8、 tf.int16、tf.int32、tf.int64、tf.uint8)、布尔型(tf.bool)和复数(tf.complex64、tf.complex128)。

    3.2.2 张量的使用

    和TensorFlow的计算模型相比,TensorFlow的数据模型相对比较简单。

    张量使用主要可以总结为两大类。

    第一类用途是对中间计算结果的引用。当一个计算包含很多中间结果

    时,使用张量可以大大提高代码的可读性。以下为使用张量和不使用张

    量记录中间结果来完成向量相加的功能的代码对比。

    使用张量记录中间结果

    a = tf.constant([1.0, 2.0], name=a)

    b = tf.constant([2.0, 3.0], name=b)

    result = a + b

    直接计算向量的和,这样可读性会比较差。

    result = tf.constant([1.0, 2.0], name=a) +

    tf.constant([2.0, 3.0], name=b)

    从上面的样例程序可以看到a和b其实就是对常量生成这个运算结果的引

    用,这样在做加法时就可以直接使用这两个变量,而不需要再去生成这

    些常量。当计算的复杂度增加时(比如在构建深层神经网络时)通过张

    量来引用计算的中间结果可以使代码的可阅读性大大提升。同时通过张

    量来存储中间结果,这样可以方便获取中间结果。比如在卷积神经网络

    中 (5)

    ,卷积层或者池化层有可能改变张量的维度,通过result.get_shape函

    数来获取结果张量的维度信息可以免去人工计算的麻烦。

    使用张量的第二类情况是当计算图构造完成之后,张量可以用来获得计

    算结果,也就是得到真实的数字。虽然张量本身没有存储具体的数字,但是通过下面3.3小节中介绍的会话(session),就可以得到这些具体的

    数字。比如在上述代码中,可以使用tf.Session.run(result)语句来得

    到计算结果。

    3.3 TensorFlow运行模型——会话

    前面的两节介绍了TensorFlow是如何组织数据和运算的。本节将介绍如

    何使用TensorFlow中的会话(session)来执行定义好的运算。会话拥有

    并管理TensorFlow程序运行时的所有资源。当所有计算完成之后需要关

    闭会话来帮助系统回收资源,否则就可能出现资源泄漏的问题。

    TensorFlow中使用会话的模式一般有两种,第一种模式需要明确调用会

    话生成函数和关闭会话函数,这种模式的代码流程如下。

    创建一个会话。

    sess = tf.Session

    使用这个创建好的会话来得到关心的运算的结果。比如可以调用

    sess.run(result), 来得到3.1节样例中张量result的取值。

    sess.run(...)

    关闭会话使得本次运行中使用到的资源可以被释放。

    sess.close

    使用这种模式时,在所有计算完成之后,需要明确调用Session.close函

    数来关闭会话并释放资源。然而,当程序因为异常而退出时,关闭会话

    的函数可能就不会被执行从而导致资源泄漏。为了解决异常退出时资源

    释放的问题,TensorFlow可以通过Python的上下文管理器来使用会话。

    以下代码展示了如何使用这种模式。 ......

您现在查看是摘要介绍页, 详见PDF附件(10912KB,445页)