当前位置: 首页 > 新闻 > 信息荟萃
编号:4014
深度学习原理与TensorFlow实践.pdf
http://www.100md.com 2020年3月25日
第1页
第9页
第19页
第26页
第37页
第135页

    参见附件(6948KB,304页)。

     深度学习原理与TensorFlow实践是关于TensorFlow系统的书籍,主要讲述了TensorFlow开发机器的方法技巧和步骤,损失函数与优化算法等等相关的深度学习的内容。

    内容简介

    《深度学习原理与TensorFlow实践》主要介绍了深度学习的基础原理和TensorFlow系统基本使用方法。TensorFlow是目前机器学习、深度学习领域最优秀的计算系统之一,《深度学习原理与TensorFlow实践》结合实例介绍了使用TensorFlow开发机器学习应用的详细方法和步骤。同时,《深度学习原理与TensorFlow实践》着重讲解了用于图像识别的卷积神经网络和用于自然语言处理的循环神经网络的理论知识及其TensorFlow实现方法,并结合实际场景和例子描述了深度学习技术的应用范围与效果。

    《深度学习原理与TensorFlow实践》非常适合对机器学习、深度学习感兴趣的读者,或是对深度学习理论有所了解,希望尝试更多工程实践的读者,抑或是对工程产品有较多经验,希望学习深度学习理论的读者。

    作者资料

    喻俨,百纳信息(海豚浏览器)研发副总裁。2007年加入微软亚洲工程院,2011年加入百纳信息负责海外业务线,从0到1做过多个项目,现致力于AI和大数据产品的研究与应用。

    莫瑜,先后任职于微软和海豚浏览器,从事搜索引擎、音乐检索/哼唱搜索、内容分发推荐算法和对话机器人技术研发。长期以来持续关注和实践大规模数据算法性能优化、搜索引擎、推荐系统和人工智能技术。

    王琛,英国爱丁堡大学人工智能专业硕士,现为百纳信息技术有限公司人工智能方向负责人。早年参加过信息学奥林匹克竞赛获得河北省第一名、全国三等奖,并保送进入中山大学。大学期间,在ACM竞赛上也屡获佳绩。硕士毕业后就职于百度基础架构部,参与大数据平台研发工作,对大数据分析处理、分布式系统架构等方面都有比较深刻的理解。2014年加入百纳,负责多个项目的研发,自2016年起负责人工智能方向的探索。

    胡振邦,拥有博士学位,百纳信息技术有限公司高级算法研究员,毕业于中国地质大学计算机学院地学信息工程专业。读博期间,参与了关于遥感卫星图像识别分析的863项目,并且是主要的研发人员。毕业以来,一直从事图像识别方面的算法研发工作,主要方向包括目标检测、图文检索、图像分类与验证等,在图像处理、计算机视觉等方面都有深厚的积累和经验。

    高杰,是一位1980年出生于苏北的“爱学习、能折腾、有情怀”的大叔。毕业于扬州中学特招班,1998年入学华中科技大学机械系,兼修管理、会计,自学计算机,2003年考入南京大学软件学院,曾任德国西门子内部SAP咨询师,还在中银国际TMT投行、金山软件集团投资部任过职,2015年与合伙人联合创立了图灵科技集团,与华尔街顶尖交易团队一起致力于量化交易、算法模型和人工智能在金融领域的应用,目前这家公司管理着超过20亿元的资产,是细分市场的领先公司。

    章节预览

    1 深度学习简介

    1.1深度学习介绍

    1.2深度学习的趋势

    1.3参考资料

    2 TensorFlow系统介绍

    2.1TensorFlow诞生的动机

    2.2TensorFlow系统简介

    2.3TensorFlow基础概念

    2.3.1计算图

    2.3.2Session会话

    2.4系统架构

    2.5源码结构

    2.5.1后端执行引擎

    2.5.2前端语言接口

    2.6小结

    2.7参考资料

    3.1 环境准备

    3.1.1Mac OS安装

    3.1.2Linux GPU服务器安装

    3.1.3常用Python库

    3.2Titanic题目实战

    3.2.1Kaggle平台介绍

    3.2.2Titanic题目介绍

    3.2.3数据读入及预处理

    3.2.4构建计算图

    3.2.5构建训练迭代过程

    3.2.6执行训练

    3.2.7存储和加载模型参数

    3.2.8预测测试数据结果

    3.3数据挖掘的技巧

    3.3.1数据可视化

    3.3.2特征工程

    3.3.3多种算法模型

    3.4TensorBoard可视化

    3.4.1记录事件数据

    3.4.2启动TensorBorad服务

    3.5数据读取

    3.5.1 数据文件格式

    3.6SkFlow、TFLearn与

    3.7小结

    3.8参考资料

    4 CNN“看懂”世界

    4.1图像识别的难题

    4.2CNNs的基本原理

    4.2.1卷积的数学意义

    4.2.2卷积滤波

    4.2.3CNNs中的卷积层

    4.2.4池化(Pooling)

    4.2.6多层卷积

    4.3经典CNN模型

    4.3.3GoogLeNet &

    4.4图像风格转换

    4.4.1量化的风格

    4.4.2 风格的滤镜

    4.5 小结

    4.6参考资料

    5 RNN“能说会道”

    5.1文本理解和文本生成问题

    5.2标准RNN模型

    5.2.1RNN模型介绍

    5.2.2BPTT算法

    5.2.3灵活的RNN结构

    5.2.4TensorFlow实现正弦序列预测

    5.3LSTM模型

    5.3.1长期依赖的难题

    5.3.2LSTM基本原理

    5.3.3 TensorFlow构建LSTM模型

    5.4更多RNN的变体

    5.5语言模型

    5.5.1NGram语言模型

    5.5.2神经网络语言模型

    5.5.3循环神经网络语言模型

    5.5.4语言模型也能写代码

    5.5.5改进方向

    5.6对话机器人

    5.6.1对话机器人的发展

    5.6.2基于seq2seq的对话机器人

    5.7小结

    5.8参考资料

    6 CNN LSTM看图说话

    6.1CNN LSTM网络模型与图像检测问题

    6.1.1OverFeat和Faster R-CNN图像检测算法介绍

    6.1.2遮挡目标图像检测方法

    6.1.3ReInspect算法实现及模块说明

    6.1.4 ReInspect算法的实验数据与结论

    6.2 CNN LSTM网络模型与图像摘要问题

    6.2.1 图像摘要问题

    6.2.2 NIC图像摘要生成算法

    6.2.3 NIC图像摘要生成算法实现说明

    6.2.4 NIC算法的实验数据与结论

    6.3 小结

    6.4 参考资料

    7 损失函数与优化算法

    7.1目标函数优化策略

    7.1.1梯度下降算法

    7.1.2RMSProp优化算法

    7.1.3Adam优化算法

    7.1.4目标函数优化算法小结

    7.2类别采样(Candidate Sampling)损失函数

    7.2.1softmax类别采样损失函数

    7.2.2噪声对比估计类别采样损失函数

    7.2.3负样本估计类别采样损失函数

    7.2.4类别采样logistic损失函数

    深度学习原理与TensorFlow实践截图

    内 容 简 介

    本书主要介绍了深度学习的基础原理和TensorFlow系统基本使用方法。 TensorFlow

    是目前机器学习、深度学习领域最优秀的计算系统之一,本书结合实例介绍了使用

    TensorFlow 开发机器学习应用的详细方法和步骤。同时,本书着重讲解了用于图像识

    别的卷积神经网络和用于自然语言处理的循环神经网络的理论知识及其 TensorFlow 实

    现方法,并结合实际场景和例子描述了深度学习技术的应用范围与效果。

    本书非常适合对机器学习、深度学习感兴趣的读者,或是对深度学习理论有所了

    解,希望尝试更多工程实践的读者,抑或是对工程产品有较多经验,希望学习深度学

    习理论的读者。

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

    版权所有,侵权必究。

    图书在版编目(CIP)数据

    深度学习原理与TensorFlow 实践 喻俨,莫瑜主编;王琛,胡振邦,高杰著. —北京:电

    子工业出版社,2017.6

    ISBN 978-7-121-31298-4

    Ⅰ. ①深… Ⅱ. ①喻… ②莫… ③王… ④胡… ⑤高… Ⅲ. ①人工智能-算法-研究

    Ⅳ. ①TP18

    中国版本图书馆CIP数据核字(2017)第071463号

    策划编辑:刘 皎

    责任编辑:刘 皎

    特约编辑:顾慧芳

    印 刷:北京季蜂印刷厂

    装 订:北京季蜂印刷厂

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

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

    开 本:720×1000 116 印张:19 字数:364.8千字

    版 次:2017年6月第1版

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

    定 价:79.00元

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

    社发行部联系,联系及邮购电话:(010)88254888,88258888。

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

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

    好评袭来

    可能有的人还没有觉察到,当前正是新的一场技术革命爆发的起始点。人工智能

    时代从“即将来临”已经变成了“正在来临”。推动这场技术革命的正是深度学习技

    术的发展,Google 的围棋算法 AlphaGo 战胜了李世石,Google 的深度学习框架

    TensorFlow也迅速风靡业界,一跃成为最活跃的深度学习框架。

    本书基于作者们使用 TensorFlow的一手实践, 由浅入深地介绍了 TensorFlow 架

    构和其上的各种深度神经网络算法实现,并给出实际的例子,非常适合 AI 爱好者学

    习,可以较全面地掌握深度学习的知识,并具备实战的能力。未来的 AI 时代里,深

    度学习技术将成为程序员重要的基础能力,向所有意识到这一点的人推荐此书!

    ——爱因互动创始人CTO 洪强宁

    TensorFlow 的出现和成熟,改变了深度学习的入门和深造路径。今天我们完全

    有可能从具体需求出发,以实践主导,比较容易地入门这一前沿人工智能技术。但是

    要超越写写例子、做做 Demo的层次,创造性地解决新问题,必须在理论上达到一定

    的理解高度。本书就是沿着这样一个思路展开的,本书作者开辟了一条由实践主导、兼顾理论的深度学习成功之路,而且语言生动,行文细腻,交代清晰,对后来的学习

    者是一份难得的指南。

    ——AI100联合创始人 孟岩 深度学习原理与TensorFlow 实践

    IV

    本书深入浅出地介绍了 TensorFlow 的技术架构以及深度学习领域常见的网络结

    构和相关理论,并结合图像、文本分析处理等多个实用的具体实例演示了如何使用

    TensorFlow 实战深度学习开发,是一本内容翔实的 TensorFlow 开发指导书,强烈推

    荐!

    ——东方网力科技股份有限公司 CTO 蒋宗文

    随着深度学习在语音、图像和自然语言理解等领域取得了巨大的技术进步,对于

    初学者而言,一本深入浅出、通俗易懂、融合基础理论和实战的入门书非常重要。

    近年来,TensorFlow 广受业界追捧。因此,本书以此平台作为介绍深度学习的

    媒介,有利于读者快速地运用所学知识,融合到工程实践、科研或系统研发任务中去。

    另外,本书的一个主要特点还在于理论和实践的有机结合。本书较全面地介绍了

    深度学习的基础理论知识,还通过丰富的实例及代码为读者提供了在 TensorFlow 平

    台上进行实践的机会——这大大增加了培养读者学习兴趣和实战经验的可能性。 书中

    给出的实例涉及图像处理、自然语言理解、对话系统、看图说话等。

    本书不仅适合广大本科同学以及研究生入门学习使用,也可以作为经验丰富的工

    程师或者研究人员的案头参考。

    衷心祝愿此书能够成为深度学习爱好者的良师益友!

    ——徐金安 博士

    毫无疑问,深度学习是近年来人工智能和机器学习领域最热门的技术,在很多应

    用领域发挥着革命性的作用。同样毫无疑问,深度学习得以广泛应用的重要原因之一,是很多公司与学术机构推出了高效可用的深度学习开源框架,使人人都能够快速构建

    自己的深度学习模型。在众多深度学习框架中,TensorFlow 出自深度学习重要推手

    的 Google公司,甫一问世就得到大家密切关注。经过 Google的几次密级改版,现在

    TensorFlow 已经快速成长为深度学习的首选开发平台。本书系统介绍了深度学习的

    基本思想和 TensorFlow的实现方法,是深度学习快速上手和入门的好书。

    ——清华大学计算机系助理教授 刘知远

    作者简介

    V ?

    作者简介

    喻俨,百纳信息(海豚浏览器)研发副总裁。2007年加入微软亚洲工程院,2011

    年加入百纳信息负责海外业务线,从 0到 1做过多个项目,现致力于 AI和大数据产

    品的研究与应用。

    莫瑜,先后任职于微软和海豚浏览器,从事搜索引擎、音乐检索哼唱搜索、内

    容分发推荐算法和对话机器人技术研发。 长期以来持续关注和实践大规模数据算法性

    能优化、搜索引擎、推荐系统和人工智能技术。

    王琛,英国爱丁堡大学人工智能专业硕士,现为百纳信息技术有限公司人工智能

    方向负责人。早年参加过信息学奥林匹克竞赛获得河北省第一名、全国三等奖,并保

    送进入中山大学。大学期间,在 ACM竞赛上也屡获佳绩。硕士毕业后就职于百度基

    础架构部,参与大数据平台研发工作,对大数据分析处理、分布式系统架构等方面都

    有比较深刻的理解。2014年加入百纳,负责多个项目的研发,自 2016年起负责人工

    智能方向的探索。

    深度学习原理与TensorFlow 实践

    VI

    胡振邦,拥有博士学位,百纳信息技术有限公司高级算法研究员,毕业于中国地

    质大学计算机学院地学信息工程专业。读博期间,参与了关于遥感卫星图像识别分析

    的 863项目,并且是主要的研发人员。毕业以来,一直从事图像识别方面的算法研发

    工作,主要方向包括目标检测、图文检索、图像分类与验证等,在图像处理、计算机

    视觉等方面都有深厚的积累和经验。

    高杰,是一位 1980 年出生于苏北的“爱学习、能折腾、有情怀”的大叔。毕业

    于扬州中学特招班,1998 年入学华中科技大学机械系,兼修管理、会计,自学计算

    机,2003年考入南京大学软件学院,曾任德国西门子内部 SAP咨询师,还在中银国

    际 TMT投行、金山软件集团投资部任过职,2015年与合伙人联合创立了图灵科技集

    团,与华尔街顶尖交易团队一起致力于量化交易、算法模型和人工智能在金融领域的

    应用,目前这家公司管理着超过 20亿元的资产,是细分市场的领先公司。

    序

    VII ?

    序

    从理论到工程

    技术发展的过程就是人类在探索自身创造能力边界的过程, 而人工智能无疑是最

    重要以及影响最深远的领域之一。

    AlphaGo 及其马甲 Master 在围棋领域大胜人类顶尖高手之后,在智力分析领域

    人类优势开始出现裂痕。而在“听说读写”方面,不管是语音识别、语音合成、机器

    翻译,还是图像识别、物体识别,甚至是自动文章生成、自动曲谱生成、艺术图像合

    成方面,机器已经开始做得比人类更为强大。深度学习在工程领域的突破,使得“机

    器学习”走出了实验室,进入到工程领域,人类开始重新审视机器能带来的更多可能

    性。

    正如 2007年以 iPhone为代表的智能手机出现, 10年之间已经颠覆了诸多商业领

    域、影响了人类的生活方式一样,深度学习也必将如此,作为一名技术人,必须理解

    和跟上行业和时代的变革!

    在过去的计算机技术演变过程中, 数据主线 (展示、 逻辑、 存储) 、 架构主线 (CS,BS,SASS)、语言框架平台主线(语法、库、框架、操作系统、平台)的变迁基本

    有迹可循, 易于举一反三, 迁移学习曲线相对平缓。 而机器学习的学习曲线相当陡峭,需要同时专注于数据处理、模型构建以及结果优化,颠覆了我们以往对数据处理的理

    解。作为工程业界人士来说,没有机器学习理论基础的支持,几乎无法应用相关的工深度学习原理与TensorFlow 实践

    VIII

    具;而没有工程实践的尝试,又很难体系化理解理论基础——入门着实不易。

    本书的作者为具有多年研究经验的博士和多年业界工程研发经验的团队,他们在

    工程领域的经验能快速地帮助读者理解 TensorFlow 的基础概念,并以最快速度搭建

    环境和跑通 Demo。更为重要的是,他们从学术+工程领域的角度,高屋建瓴地拎出

    了 CNN(卷积神经网络)、RNN(循环神经网络)、CNN+LSTM(Long Short Term

    网络)的基本原理,并且结合 CNN在图像领域处理、RNN在语义领域处理以及结合

    CNN+LSTM在图像检测和图像摘要生成等基本工程领域的处理,快速地让读者理解

    深度学习能干什么,如何利用 TensorFlow 快速解决这些领域的问题,让自己的应用

    插上“人工智能”的翅膀!

    人工智能的时代已经开启,唯有快速拥抱变化才能应对变化,希望读者能借这本

    书建立对机器学习的宏观认识并对之深入理解,跑步进入机器学习领域!

    刘铁锋

    《编程之美》作者

    海豚浏览器创始人

    前言

    IX ?

    前言

    创造出具有智能的机器一直是人们梦寐以求的理想。 自20世纪 50年代图灵测试

    被提出以来,人工智能就成为了计算机科学领域中一个极具吸引力的研究方向。近年

    来,深度学习是机器学习领域中一个非常具有突破性的研究方向,从 AlphaGo 战胜

    李世石,到 Prisma 运用深度学习技术制作滤镜刷爆全世界的社交网络,深度学习在

    图像处理、自然语言处理甚至博弈决策等问题上不断取得震惊世人的成绩。

    随着科研理论上的不断突破,机器学习基础架构方面也有了长足进步。为了提高

    科研和应用的开发效率,面向深度学习的开发框架不断涌现,而 TensorFlow 就是其

    中的佼佼者。依托于 Google 强大的影响力,TensorFlow 一经发布就吸引了整个行业

    的关注。TensorFlow 自 2015 年年底在 GitHub 开源以来,一直是机器学习、深度学

    习类别中关注度最高的项目,截至 2016年年底,已经获得超过 40000个 Star。同时,在开源社区共同的努力下,基于 TensorFlow开发的各种算法和应用都在飞速增加。

    本书结合基于 TensorFlow实践的应用代码, 介绍了深度学习的基础概念和知识,但需要读者预先掌握一些传统机器学习、神经网络相关方面的知识。同时,本书代码

    主要基于目前最新的 TensorFlow 1.0 版本,大部分为 Python 代码,需要读者有一定

    的 Python 语言基础。希望通过本书的介绍,读者可以由浅入深、由理论到实践全面

    掌握深度学习的基础知识和实践方法。

    本书第 1章介绍了深度学习的由来以及发展趋势,简要说明了人工智能、机器学深度学习原理与TensorFlow 实践

    X

    习、深度学习等名词概念之间的联系。第 2 章主要介绍了 TensorFlow 系统的基础知

    识和一些重要概念。第 3章通过对 Kaggle竞赛平台上的 Titanic问题的求解实例,介

    绍了 TensorFlow 系统的基本用法,并简要介绍了机器学习问题中的一些常用的处理

    技巧。第 4章和第 5章分别介绍了主要应用于图像处理领域的卷积神经网络 CNN和

    主要应用于自然语言处理领域的循环神经网络 RNN。 其中第 4章介绍了 CNN的基本

    原理和多个经典网络结构,并通过图像风格化的实例展示了 CNN在更多场景下应用

    的可能性。第 5 章介绍了 RNN、LSTM 以及它们的多种变种结构,并通过实例介绍

    了如何构建实用的语言模型和对话机器人。第 6章介绍了卷积神经网络与循环神经网

    络的结合,通过图像检测和图像摘要两个问题介绍了 CNN+LSTM相结合的威力。最

    后的第 7 章介绍了机器学习中非常重要的损失函数与优化算法在 TensorFlow 中的实

    现,对实际使用深度学习解决问题都有极大帮助。

    在此感谢互联网时代,感谢 Google 的开源精神,让我们可以如此紧跟时代最前

    沿的技术,也可以为技术的进步做出自己微薄的贡献。还要感谢电子工业出版社刘皎

    编辑对新技术的关注和推广,感谢同事、家人、各位好友的支持和帮助,有你们的支

    持才有此书的出版,不胜感激。

    作 者

    注册博文视点(www.broadview.com.cn)用户,享受以下服务:

    ● 提勘误赚积分:可在【提交勘误】处提交对内容的修改意见,若被采纳将获赠博

    文视点社区积分(可用来抵扣购买电子书的相应金额)。

    ● 交流学习:在页面下方【读者评论】处留下您的疑问或观点,与作者和其他读者

    共同交流。

    页面入口:http:www.broadview.com.cn31298

    二维码入口:

    目录

    XI ?

    目录

    1 深度学习简介 1

    1.1 深度学习介绍 ....................................................................................... 1

    1.2 深度学习的趋势 ................................................................................... 7

    1.3 参考资料 ............................................................................................. 10

    2 TensorFlow 系统介绍 12

    2.1 TensorFlow诞生的动机 ..................................................................... 12

    2.2 TensorFlow系统简介 ......................................................................... 14

    2.3 TensorFlow基础概念 ......................................................................... 16

    2.3.1 计算图 ..................................................................................... 16

    2.3.2 Session 会话 ........................................................................... 18

    2.4 系统架构 ............................................................................................. 19

    2.5 源码结构 ............................................................................................. 21

    2.5.1 后端执行引擎 ......................................................................... 22

    2.5.2 前端语言接口 ......................................................................... 24

    2.6 小结 ..................................................................................................... 24

    2.7 参考资料 ............................................................................................. 25

    3 Hello TensorFlow 26

    3.1 环境准备 ............................................................................................. 26 深度学习原理与TensorFlow 实践

    XII

    3.1.1 Mac OS 安装 .......................................................................... 27

    3.1.2 Linux GPU服务器安装 ......................................................... 28

    3.1.3 常用 Python库 ....................................................................... 32

    3.2 Titanic题目实战 ................................................................................. 34

    3.2.1 Kaggle平台介绍 .................................................................... 34

    3.2.2 Titanic题目介绍..................................................................... 35

    3.2.3 数据读入及预处理 ................................................................. 38

    3.2.4 构建计算图 ............................................................................. 40

    3.2.5 构建训练迭代过程 ................................................................. 44

    3.2.6 执行训练 ................................................................................. 46

    3.2.7 存储和加载模型参数 ............................................................. 47

    3.2.8 预测测试数据结果 ................................................................. 50

    3.3 数据挖掘的技巧 ................................................................................. 51

    3.3.1 数据可视化 ............................................................................. 52

    3.3.2 特征工程 ................................................................................. 54

    3.3.3 多种算法模型 ......................................................................... 57

    3.4 TensorBoard 可视化 ........................................................................... 58

    3.4.1 记录事件数据 ......................................................................... 58

    3.4.2 启动 TensorBorad服务 .......................................................... 60

    3.5 数据读取 ............................................................................................. 62

    3.5.1 数据文件格式 ......................................................................... 63

    3.5.2 TFRecord ................................................................................ 63

    3.6 SkFlow、TFLearn与 TF-Slim ........................................................... 67

    3.7 小结 ..................................................................................................... 69

    3.8 参考资料 ............................................................................................. 69

    4 CNN“看懂”世界 71

    4.1 图像识别的难题 ................................................................................. 72

    4.2 CNNs 的基本原理 .............................................................................. 74

    4.2.1 卷积的数学意义 ..................................................................... 75

    4.2.2 卷积滤波 ................................................................................. 77

    4.2.3 CNNs中的卷积层 .................................................................. 81

    4.2.4 池化(Pooling) .................................................................... 83

    4.2.5 ReLU ....................................................................................... 84

    目录

    XIII ?

    4.2.6 多层卷积 ................................................................................. 86

    4.2.7 Dropout ................................................................................... 86

    4.3 经典 CNN模型 .................................................................................. 87

    4.3.1 AlexNet ................................................................................... 88

    4.3.2 VGGNets ................................................................................. 95

    4.3.3 GoogLeNet Inception .......................................................... 98

    4.3.4 ResNets ................................................................................. 106

    4.4 图像风格转换 ................................................................................... 109

    4.4.1 量化的风格 ........................................................................... 109

    4.4.2 风格的滤镜 ........................................................................... 116

    4.5 小结 ................................................................................................... 120

    4.6 参考资料 ........................................................................................... 121

    5 RNN“能说会道” 123

    5.1 文本理解和文本生成问题 ............................................................... 124

    5.2 标准 RNN模型 ................................................................................ 128

    5.2.1 RNN模型介绍 ..................................................................... 128

    5.2.2 BPTT算法 ............................................................................ 130

    5.2.3 灵活的 RNN结构 ................................................................ 132

    5.2.4 TensorFlow实现正弦序列预测 ........................................... 135

    5.3 LSTM模型 ....................................................................................... 138

    5.3.1 长期依赖的难题 ................................................................... 138

    5.3.2 LSTM基本原理 ................................................................... 139

    5.3.3 TensorFlow构建 LSTM模型 .............................................. 142

    5.4 更多 RNN的变体 ............................................................................ 144

    5.5 语言模型 ........................................................................................... 146

    5.5.1 NGram语言模型 .................................................................. 146

    5.5.2 神经网络语言模型 ............................................................... 148

    5.5.3 循环神经网络语言模型 ....................................................... 150

    5.5.4 语言模型也能写代码 ........................................................... 152

    5.5.5 改进方向 ............................................................................... 163

    5.6 对话机器人 ....................................................................................... 164

    5.6.1 对话机器人的发展 ............................................................... 165

    5.6.2 基于 seq2seq的对话机器人 ................................................ 169 深度学习原理与TensorFlow 实践

    XIV

    5.7 小结 ................................................................................................... 181

    5.8 参考资料 ........................................................................................... 182

    6 CNN+LSTM 看图说话 183

    6.1 CNN+LSTM 网络模型与图像检测问题 ......................................... 184

    6.1.1 OverFeat和 Faster R-CNN图像检测算法介绍 .................. 185

    6.1.2 遮挡目标图像检测方法 ....................................................... 187

    6.1.3 ReInspect算法实现及模块说明 .......................................... 188

    6.1.4 ReInspect算法的实验数据与结论 ...................................... 204

    6.2 CNN+LSTM 网络模型与图像摘要问题 ......................................... 207

    6.2.1 图像摘要问题 ....................................................................... 208

    6.2.2 NIC图像摘要生成算法 ....................................................... 209

    6.2.3 NIC图像摘要生成算法实现说明 ....................................... 214

    6.2.4 NIC算法的实验数据与结论 ............................................... 243

    6.3 小结 ................................................................................................... 249

    6.4 参考资料 ........................................................................................... 250

    7 损失函数与优化算法 253

    7.1 目标函数优化策略 ........................................................................... 254

    7.1.1 梯度下降算法 ....................................................................... 254

    7.1.2 RMSProp优化算法 .............................................................. 256

    7.1.3 Adam优化算法 .................................................................... 257

    7.1.4 目标函数优化算法小结 ....................................................... 258

    7.2 类别采样(Candidate Sampling)损失函数................................... 259

    7.2.1 softmax类别采样损失函数 ................................................. 261

    7.2.2 噪声对比估计类别采样损失函数 ....................................... 281

    7.2.3 负样本估计类别采样损失函数 ........................................... 286

    7.2.4 类别采样 logistic损失函数 ................................................. 286

    7.3 小结 ................................................................................................... 287

    7.4 参考资料 ........................................................................................... 288

    结语 289

    1

    深度学习简介

    1.1 深度学习介绍

    深度学习是目前机器学习学科发展最蓬勃的分支,也是整个人工智能领域中应用

    前景最为广阔的技术。在现如今的生活中,不管是在 iPhone上随手调戏 Siri,还是看

    着 AlphaGo 赢得围棋世界第一的宝座,都让人们真真切切地感受到人工智能已经不

    再是停留在科幻小说中的幻想,深度学习的时代已经到来了!

    人工智能(Artificial Intelligence,AI)是计算机科学中的一个分支学科,早在

    20 世纪 50 年代就被提出和确立了。著名的“图灵测试”是 AI 发展的终极目标,如

    果某种机器运行的逻辑程序可以表现出与人类等价或者无法分辨的智能, 则认为机器

    有了思维,能够进行思考。从实用的角度讲,AI 的目标是要让计算机系统能够自动

    完成那些需要依靠人类智慧才能完成的工作。

    在 AI发展的早期阶段,随着计算机自动化所取得的成功,AI的主要方法和思路

    是将人类总结的知识用一系列规范的、形式化的数学规则来表示,然后通过自动化的

    程序代替人类处理问题。以知识为基础的专家系统(knowledge-based expert system)

    就是这方面的典型代表,它将某个领域中人类专家的经验通过知识表示方法写成一条一条规则,系统依照规则推理模拟专家的思维方式。不过,在实际应用中,专家系统

    都没有取得太大的成功,其最主要的局限性体现在系统明显受到规则数量的限制,规

    则数量决定了系统对不同情况的适应程度,然而规则是有限的,问题发生时的状况是

    无限的,用有限的规则处理无限的可能,注定是苦海无涯。

    早期在 AI 方面取得成功的项目,多数解决的是具有明确规则和条件的问题,比

    如西洋跳棋。1997年 IBM的“深蓝”计算机在国际象棋上战胜人类世界冠军卡斯帕

    罗夫就是这个方面最著名的例子。对于人类来说,下象棋当然是很有挑战的项目,但

    是相比真实世界的复杂程度而言,国际象棋其实只是一个简单问题。棋盘上只有 32

    个棋子和 64 个可以落子的位置,走法规则是非常明确的,所有可能的局面组合是有

    限的,可以被穷举出来,利用计算机的计算能力辅助以启发式搜索等算法,在摩尔定

    律的作用下,击败人类只是时间问题。在这类问题中,问题的表示通常都不是难题,一个普通程序员也可以在很短时间内完成一个象棋程序。然而许多真实世界的问题却

    并不都是那么容易能用计算机语言表达清楚的,比如图像识别和语音识别,这些问题

    有着比国际象棋大得多的问题域,即使对于人类来说,也有很多不能确定、无法选择

    的时刻,所以用规则来描述问题是不现实的。

    因此,“演绎法”的规则推理暂时行不通,“归纳法”就成为了唯一的出路。基于

    概率统计的机器学习(machine learning)逐渐成为人工智能的主流方法。与专家系

    统不同,机器学习不会在系统中输入任何规则,而是直接在大量真实世界产生的数据

    中挑选最具有代表性的样本(samples)交给算法处理,让算法自动在数据中寻找和

    学习特定的规律,而这些由数据得来的规律,就是我们本来需要输入的规则。这种从

    数据中学习规律的过程也叫做模式识别(pattern recognition) 。

    机器学习的基本思路是假设样本数据与真实世界的概率分布相同,这样就可以认

    为算法从样本数据中归纳所得的规律在一般情况下同样适用。朴素贝叶斯(naive

    bayes)和逻辑回归(logistic regression)等算法都是机器学习的经典方法,并且都在

    实际应用中取得了很好的效果。

    机器学习一般分为监督学习和无监督学习两种。监督学习要求每条样本数据都有

    对应的标签(label) ,样本数据作为输入,标签作为目标输出,学习的目标是求出输

    入与输出之间的关系函数y = f(x),使得针对每个输入样本 x,都得到期望的输出结

    果y。朴素贝叶斯、逻辑回归和神经网络等都属于监督学习的方法。而对于无监督学

    习来说,样本数据并没有标签,学习的目标是为了探索样本数据之间是否有隐含的不

    易被发现的关系,统计样本的分布情况,典型的算法有 K-means等各种聚类算法。

    监督学习主要解决两类核心问题,即回归(regression)和分类(classification) 。

    回归和分类的区别在于强调一个是连续的,一个是离散的。回归的输出可以是任意实

    数,而分类的目标输出为离散的类别编号,或是布尔类型的二值判断。分类问题可以

    利用概率模型以回归方式来求解,即认为样本所属的真实类别概率为 100%,样本属

    于其他类别的概率为 0%。通过将离散的类别编号转化为连续的概率,利用回归方法

    学习和预测样本属于每个类别的概率,概率最大的类别就是分类结果。

    对于朴素贝叶斯和逻辑回归等简单的机器学习算法来说,本质上是要计算样本输

    入与目标输出之间的相关性。相关性固然是非常重要的,但在处理真实世界问题的时

    候,判断相关性其实是人们确定了所有影响因素之后的一个后续问题,各个影响因素

    的表示(representation)会严重影响对于相关性的判断。比如要辨别一段语音中演

    讲者是男人、女人还是小孩,简单机器学习算法的判断依据很可能主要来自音量而不

    是音色和音调。再比如,假设我们想用逻辑回归判断明年北京房价是否继续上涨,如

    果选定人口净流入数和地铁修建的里程数作为输入的话,会得到人口流入越多房价越

    高的结论,那么如果明年人口净流入减少,则系统会预测房价下跌。但真实情况是房

    价与货币增发量相关性更大,如果明年货币继续超发,最终房价还是会上涨,所以预

    测就可能会出现比较大的误差。

    人口流入数、货币增发量这些对于预测房价有影响的因素,是我们从众多维度中

    提取的特征(feature) 。正如在前文例子中描述的那样,设计合适的特征表示在机器

    学习中是一项极其重要却又非常困难的工作。一方面,特征选取会直接影响预测的稳

    定性,要得到准确的预测结果就必须选中相关度最高的特征。在使用逻辑回归、朴素

    贝叶斯等简单机器学习算法的时候,由于特征选取问题而导致模型失效的情况比比皆

    是。但另一方面,如何设计特征又需要加入许多人类的先验经验才能完成,需要运用

    人类的智慧和经验分析各种因素所带来的直接或间接的影响。所以通常的做法是首先

    列举出各种可能的特征,然后通过交叉组合的方式进行穷举验证。在很长一段时间,特征工程(feature engineering)都是机器学习的重中之重,是每个研究员的必修技

    能。特征工程对于传统机器学习算法来说是如此重要,但同时也是机器学习应用的最大束缚,不仅费时费力,还需要由人类提供大量的先验经验以弥补对数据本身挖掘不

    足的缺陷。若要拓展机器学习的适用范围,必须要降低学习算法对特征工程的依赖性。

    深度学习(Deep Learning,也曾被叫作 Feature Learning)是在人工神经网络

    (Aritificial neural network,ANN)基础上发展而来的一种表示学习(Representation

    Learning)方法,也是一种机器学习方法,而且是人工智能领域最具发展前景的一个

    分支,如图 1-1所示。其主要模型是各种深度神经网络(Deep Neural Network) 。表

    示学习是近年来机器学习领域发展最迅猛、最受学术界追捧的方向。所谓表示学习,就是要让算法在少量人为先验经验的情况下,能够自动从数据中抽取出合适的特征,完成原本需要通过特征工程才能得到的结果。在表示学习范畴中,深度学习是通过多

    层非线性变换的组合方式,得到更抽象也更有效的特征表示。原先使用机器学习解决

    问题的主要工作包括需要大量人工处理的特征工程加上一个可被训练的分类器,而到

    了深度学习的时代,特征工程已经被各种可训练的特征提取器所取代,在应用效率上

    有了显著提高。更重要的是,人工智能目标就是让机器有能力理解我们所在的世界,只有当它能学会如何感知和辨别数据背后的各种隐含因素的时候才能达到这个目标。

    图 1-1 深度学习是一种机器学习方法,是人工智能领域最具前景的分支

    真实世界的问题之所以困难,很大程度上是因为我们能够观察到的数据都是种种

    因素叠加而成的。比如同一朵花在白天和夜晚观察的颜色是不同的,同一辆车在不同

    角度观察的形状也不一样。表示学习最核心的诉求就是要发现真正重要的特征,舍弃

    那些并不影响判断的因素。要做到这种程度当然不是一件容易的事,那么深度学习又

    是如何做到呢?

    深度学习是通过构建一个多层的表示学习结构,使用一系列非线性变换操作把从

    人工智能

    机器学习

    深度学习

    原始数据中提取的简单的特征进行组合,从而得到更高层、更抽象的表示。在图像识

    别的场景中,图像在计算机中最基本的表示是一组像素值集合,从像素到物体的映射

    关系需要经过一个很长的过程,从像素组成细小的边,由边组成基础的纹理基元,纹

    理基元组合而成图形,图形构成物体的各种组成部分,最后组成物体的整体。同样,对于文本的理解也符合类似的过程,先认识各个字母,再由字母组成单词,单词组成

    词组,词组组成句子,句子组成段落,段落构成完整的故事。这个过程对于人类来说

    眨眼之间就已经完成了,但是对于计算机来说是非常复杂的,很难简单直接地一步求

    得这种映射关系。因此,深度学习模型的结构设计遵循了这种思路,具体做法是将一

    系列相对简单的非线性映射操作构建成一个多层网络,每一层(layer)都完成一次特

    征变换。以人脸识别为例,网络以像素表示的图像作为输入,在低级层次中主要学习

    到代表图像边缘的特征,可能是连续几个像素所组成的某个方向上的线段。中级层次

    会学习到由边缘线段所组成的局部图案,这些图案实际上是构成目标物体的各种部件,比如眼睛、鼻子、耳朵。在最后的高级层次中,以各种局部部件作为基本单元就可以

    组合出人脸的抽象表示,比如包括人脸上会有一个鼻子两只眼睛、眼睛的相对位置在

    鼻子的两侧,等等。而符合这种抽象表示的图像,就可以被判定为人脸图片。如此多

    层学习结构中的中间特征如图 1-2所示。

    图 1-2 多层学习结构中的中间特征

    那什么样的结构才算是有“深度”?其实包含三个以上隐层(hidden layer)的神

    经网络就可以说是一种深度学习模型,但由于在真实场景使用时参数过多、计算量过

    大,存在梯度消失和梯度爆炸的问题,无法做到稳定收敛,所以一般不会使用。一个

    网络的深度,可以以网络中串联的计算的层数,或者是非线性变换次数,甚至更加抽象一些,以不同的计算概念来评估。关键在于,深度学习比传统机器学习模型多了多

    级特征提取的结构,能够进行表示学习,这样才算是有深度。从这个意义上说,只有

    两个隐层的神经网络就不能算是有深度的结构,因为它并没有能力分级提取特征。

    了解人工神经网络知识的读者可能会有一个疑问,具有一个隐层的人工神经网络

    已经非常强大了,理论上来说,只要神经元足够多,构成一个很“宽”的网络,它可

    以拟合任意的函数,那为什么还要更 “深”?原因在于:在神经元数量相同的情况下,深层网络结构具有更大的容量,分层组合带来的是指数级的表达空间,能够组合成更

    多不同类型的子结构,这样可以更容易地学习和表示各种特征。并且,隐层增加则意

    味着由激活函数(activation function)带来的非线性变换的嵌套层数更多,就能构造

    更复杂的映射关系。

    现如今,深度学习已经在多种应用上取得了突破性进展。卷积神经网络

    (Convolutional Neural Networks,CNNs)是这一波深度学习浪潮的引领者。2012年

    AlexNet在 ILSVRC图像识别竞赛中所带来的惊人表现,让学术界看到了深度学习所

    蕴含的巨大潜力。在随后的几年中,随着 GoogLeNet、VGGNets、ResNets 等模型的

    提出,CNNs的识别准确率持续提高,让计算机拥有了超越人类的图像识别能力。关

    于CNNs的应用将在本书第4章中详细介绍。同时,深度学习在自然语言处理(Natural

    Language Processing,NLP)方面同样取得了巨大的成功,不但有 Siri这样可以与人

    类正常交流的对话机器人,甚至能够写诗、作曲。本书第 5 章会介绍循环神经网络

    (Recurrent Neural Networks,RNNs)在处理语音或者文字等问题中的应用。

    总结来说,深度学习是一种机器学习方法,同时也是目前最有希望具有处理复杂

    的真实世界问题的能力的人工智能方法。深度学习的分层结构能够从简单概念的组合

    中学习到高级抽象的特征表示,让计算机真正具有理解世界的能力。不同类型人工智

    能系统的流程图如图 1-3所示。

    图 1-3 不同类型人工智能系统的流程图。灰色框表示具有从数据中学习的能力

    1.2 深度学习的趋势

    20世纪 90年代,在卷积神经网络应用于文字识别之后,深度学习曾经经历一段

    时间的沉寂,而 2012 年在图像识别领域的爆发式突破,让人们意识到其巨大的潜力

    和广阔的应用前景。现如今,以 Google、Facebook、Nvidia等为首的科技公司全都重

    兵押注深度学习,而国内的百度、阿里巴巴、腾讯也紧随其后,让人深深感觉到这是

    一个朝气蓬勃的领域,同时也是一个硝烟弥漫的战场。

    很多人会好奇,人工神经网络几十年前就已经存在了,为什么直到今天才认为深

    度学习是一项突破性的技术?事实上,在20世纪 90年代深度学习就已经有成功的商

    业应用,但是在那时,人们更多会认为这是一门只有少数几个专家才能掌握的艺术而

    不是技术。深度学习的成功,依赖于四项基本要素:

    ● 海量的训练数据;

    ● 非常灵活的模型;

    ● 足够的运算能力;

    ● 足够对抗维度灾难(curse of dimensionality)的先验经验。

    机器学习是要从数据中学习知识,正所谓“巧妇难为无米之炊”,即使再厉害的

    算法,也需要优质的数据集支持。所以在人工智能几十年的发展过程中,数据集的种类和规模都在逐渐增长。图 1-4 展示了一些经典数据集规模的对比。从中可以看到,样本的规模几乎是在以指数级增长,其中一些著名的数据集(如 ImageNet)的样本

    数量已经达到了千万级别。原先,机器学习的任务是,要从少量数据中学习特定的规

    律,然后泛化到更一般的场景中,并且要防止各种欠拟合和过拟合。但随着大数据时

    代的到来,数据集本身就已经包含了各种可能出现的情况,从数据集中学习的规则可

    以直接应用在现实场景中。以 2016年的趋势来看,对于有监督的深度学习算法来说,只要每个类别有 5000个样本,机器就能达到令人满意的表现,而若有 1000万以上的

    样本,机器就能达到甚至超越人类的水平。在互联网已经深入人们生活每一个角落的

    今天,数据更是会越来越多,各种“独角兽”公司每天产生的数据量是 PB 级别的。

    当收集数据已经不再是难题,如何更有效地利用数据就成为了新的挑战。

    图 1-4 在人工智能学科刚被确立的时候,研究的数据仅在几百条的规模。到了 20世纪 90年代,著名的 MNIST手写数字数据集有60000多张28×28 分辨率的黑白图片。而到了近些年,ImageNet

    数据集超过了 100 万张大尺寸彩色照片

    深度学习涉及大量的科学计算。计算机硬件的性能提升也为深度学习发展推广提

    供了基本必要条件。著名 CPU厂商英特尔(Intel)的创始人之一戈登·摩尔(Gordon

    Moore)曾提出摩尔定律,其内容为:当价格不变时,集成电路上可容纳的元器件的

    数目,约每隔 18~24 个月便会增加一倍,性能也将提升一倍。摩尔定律概括了 20

    世纪末一段时间 CPU 的发展速度。到 2017 年,家用电脑 CPU 计算频率已经接近当

    前技术的上限。因此,除了靠提升单个 CPU 的计算频率来提升计算速度外,人们还

    想到使用多核或多 CPU集成的方式来提升计算性能。CPU能够快速处理多种类型的

    计算,但并不是每种类型的计算耗时都相同的(例如双精度浮点数乘、除法和条件判

    断语句)。因此多 CPU集成,同样受到频率同步和稳定性的限制。我们可以看到,市

    面上好几万元的品牌机服务器的 CPU核心往往是 16~64个,而主频一般都在 3.0GHz

    以下。而几千元的 PC主频虽然可以达到 3.0Ghz,而 CPU核心一般是 2~8个。

    考虑到深度学习的特殊计算需求和 CPU 综合计算性能方面的这些限制,人们考

    虑使用 GPU 来解决科学计算问题。20 世纪 90 年代,PC 电脑发展初期 GPU 的主要

    功能是用于显示交互界面。其画面的显示功能涉及坐标点变换、栅格化、平面渲染等

    大量的浮点数加、减、乘、除等计算操作。对比来说,CPU是面向通用计算的产品,而 GPU 则是天生面向大规模浮点数并行计算的。与 CPU 相比,GPU 的内置计算核

    心虽然计算频率相对较低,但内置计算核心数量更多。以著名GPU厂商英伟达(Nvidia)

    为例,近几年推出的 Tesla、Titan X系列显卡处理器数量都以上百、上千计,而计算

    主频在 1GHz 左右。在 GPU 的帮助下,神经网络的训练效率大幅提高。与同等价位

    CPU相比,速度提升了约几十倍,分析大型的深度网络结构的效率因此得到了提升。

    英伟达公司 Tesla系列显卡与 CPU芯片的计算能力比较如图 1-5所示。

    图 1-5 Tesla系列显卡与 CPU芯片的算力比较。在科学计算方面 GPU显卡是 CPU速度的数倍

    随着计算能力的提升和更大规模数据集的出现,神经网络模型不但结构越来越复

    杂,而且规模也在不断增大。尤其自从隐层结构提出以来,神经网络的神经元数量每

    2.4 年翻一番,如图 1-6 所示。对于深度学习来说,人类赋予其最重要的一个先验经

    验就是:分层组合的表示方式更能准确地描述我们所在世界的规则。因此,深度学习模型发展出更深的结构、更大的规模也是必然趋势。更何况实验已经证明,更大的模

    型能够达到更好的表现。以图像识别为例,拥有 8 个参数层的 AlexNet 在 ImageNet

    大规模视觉识别挑战(ILSVRC)中将图像分类的错误率降低到 15.3%,而有 19个参

    数层的 VGGNet的分类错误率只有 7.3%,现今最大、最深的 ResNet有超过 150个参

    数层,分类错误率仅为惊人的 3.57%,这已经是超越人类能力的成绩。

    可以预见的是,深度学习在未来将能处理越来越复杂的任务,也注定会在我们日

    常生活中扮演越来越重要的角色。

    图 1-6 自从隐层结构提出以来,神经网络的神经元数量每 2.4 年翻一番。图中各编号代表的分别为:1.

    感知机(Perceptron);2.自适应线性单元(Adaptive linear element);3.神经认知机(neocognitron);4.早期

    反向传播网络;5.用于语音识别的递归神经网络;6.用于语音识别的多层感知机;7.sigmoid 置信网络;8.

    LeNet-5;9.回声状态网络(Echo state Network);10.深度置信网络(Deep belief network);11. GPU加速的

    卷积网络;12.深度玻尔兹曼机(Deep Boltzmann machine);13. GPU 加速的深度置信网络;14.非监督卷积

    网络;15. GPU加速的多层感知机;16. OMP-1 网络;17.分布式自动编码器(Distributed autoencoder);18.

    多 GPU加速的卷积网络;19. COTS HPC非监督卷积网络;20. GoogLeNet

    1.3 参考资料

    [1] 本部分内容参考并翻译自:Ian Goodfellow and Yoshua Bengio and Aaron

    Courville. Deep learning. An MIT Press book in preparation. Draft chapters

    available at http:deeplearningbook.org (2016).

    [2] Bengio Y, Courville A, Vincent P. Representation Learning: A Review and New

    Perspectives. arXiv:1206.5538v3.

    [3] Geoffrey Hinton, Yoshua Bengio, Yann LeCun. Deep Learning. NIPS 2015

    Tutorial.

    [4] 周志华,《机器学习》。

    [5] Yann LeCun. Deep Learning. ICML 2013 Tutorial.

    [6] Bengio, Yoshua, and Yann LeCun. Scaling learning algorithms towards

    AI. Large-scale kernel machines 34.5 (2007).

    2

    TensorFlow 系统介绍

    随着各种图像识别、语音识别的纪录被不断刷新,深度学习也被证明是一个极具

    潜力的技术方向,越来越多的研究学者涌入这一领域尝试新思路、新方法、新的应用

    方向。在这样的背景之下,构建高效、可靠、可扩展的基础工具,能为这一领域的发

    展起到极大的推动作用。

    TensorFlow 是 Google 推出的一套深度学习系统,使用其灵活易用的前端语言可

    以轻松地构建各种复杂的算法模型,后端高效的执行系统与分布式架构保证了在模型

    训练和执行方面的高性能。综合来看,TensorFlow是目前业界最优秀的深度学习系统

    之一。

    在本章中,从系统需求、基础概念、系统架构和源代码几个方面对 TensorFlow

    系统进行了介绍。 正所谓 “磨刀不误砍柴工”,在开始实战之前先了解一下 TensorFlow

    内部的设计原理和运行机制,相信可以帮助读者更好地运用这一强大的工具。

    2.1 TensorFlow诞生的动机

    Google可以说是人工智能方面工业界的领军者之一。早在 2011年,就由 Google

    传奇人物 Jeff Dean、Google研究学者 Greg Corrado,携手斯坦福大学教授 Andrew Ng

    共同创建了 Google Brain (谷歌大脑)计划,旨在探索深度学习在实际场景中的应用。

    多位专家的联合努力,基于 Google 已有的云计算基础架构,设计开发了第一代机器

    学习系统 DistBelief。 DistBelief继承了 Google所有分布式系统的长处,具有高性能、高扩展性等特点。在 Google内部,有包括搜索、地图、翻译等超过 50个团队使用了

    基于 DistBelief构建的深度神经网络算法模块。

    深度学习如今发展速度越来越快,大量新颖的研究成果不断涌现,能够应用深度

    学习技术的场景也越来越多。作为学术研究和工程产品的基础,深度学习框架系统在

    其中起到了巨大的促进作用。基于在多个项目上研究应用的经验,Google Brain团队

    总结出了对于深度学习系统的以下几点核心需求。

    要具有灵活的表达能力,能够快速实现各种算法

    随着越来越多的专家学者加入了深度学习领域, 几乎每天都有各种疯狂的新想法、新模型涌现出来。快速实现算法、快速验证结果,成为了主要的需求之一。在曾经的

    MATLAB 时代,算法的实现至少需要有经验的专家花费几天的时间,即使在 Caffe

    等框架出现之后,新模型(如 RNN等)的扩展仍然是一件困难的事情。因此,对神

    经网络进行合理的抽象封装,并设计出灵活的编程接口,支持各种模型的组合与扩展,是深度学习系统的首要目标。

    高执行性能,具备分布式扩展性

    由于机器学习算法执行的计算量通常都比较大,所以程序实现必须经过充分的优

    化,减少不必要的开销,以降低执行时间。因此,对于深度学习框架系统来说,执行

    性能是非常重要的基础评价指标。不仅如此,在服务器集群大行其道的今天,若仅依

    靠单机运算是远远不够的,而利用分布式技术进行并行计算可以大大提高计算吞吐量,进一步提升效率,所以支持分布式扩展对于深度学习系统来说也是非常重要的。

    跨平台可移植性

    跨平台已经不是什么新鲜的概念了,桌面应用会跨 Windows和 MacOS系统,手

    机 APP 要同时支持 iOS 和 Android 平台。机器学习算法要想应用于生产生活场景,也需要适应多种平台载体。随着深度学习技术日趋成熟,应用会越来越贴近人们的生

    活,将模型运行在手机,甚至是手表等随身设备上,应该会成为主要的趋势。因此,由深度学习系统提供跨平台能力,既能让模型在 GPU 服务器上高效训练,又能快速

    部署在各种生产环境中,可以为实用带来极大的便利。

    实验可复现性

    如今是讲究开放和合作的时代,交流与研究同等重要。大部分机器学习算法都是

    基于概率论发展起来的科学,因此很多的实验都具有一定程度的随机性,这就为实验

    的精准复现带来了难度。深度学习框架系统可以从底层提供解决这一问题的工具,让

    实验不再是一次性的结果,而是可重现、可共享的资料。这对促进研究的发展有着极

    其重要的作用。

    支持快速产品化,模型可随时部署

    随着深度学习的快速发展,一些模型和技术已经具备了处理真实世界问题的能力,例如识别各种文字、识别语音、识别图像,等等。对于以往的一些技术而言,研究和

    应用之间往往存在较大的间隔,从学术界到工业界有一个转化的过程。但深度学习不

    同,在问题定义之初可能就已经是一个实际的具体问题,只有很少的抽象成分,所以

    往往模型只要一训练好,就可以立刻投入到生产系统中使用。因此,深度学习系统应

    该支持模型在训练和应用两方面灵活切换,随时将研究成果集成到产品中。

    虽然第一代深度学习系统 DistBelief 已经拥有很好的扩展性,但在灵活性方面的

    不足[3]

    ,使得Google Brain团队有动力开发第二代系统,即 TensorFlow。它对于机器

    学习应用来说就如同 Linux、iOS 等操作系统一样,一方面为用户构建上层应用提供

    接口,让用户以此为平台,开发出各种各样的应用产品,另一方面管理和控制底层的

    计算机硬件和软件资源,以提高资源利用率,降低硬件差异等问题所带来的研发成本。

    2.2 TensorFlow系统简介

    深度学习的研究始终都是为了解决现实世界中存在的问题,所以在学术界不停探

    索新模型、新方法的同时,工业界也不断推出各种工具框架,促进研究和应用的发展。

    Google 经过长期的研究和尝试,在实践的基础上推出了目前最优秀深度学习框架系

    统之一——TensorFlow,其项目 logo如图 2-1所示。

    图 2-1 TensorFlow项目 logo

    在 TensorFlow 的官方介绍中给出的定义是:TensorFlow 是一个基于数据流图

    (Data flow Graph)的数值计算开源软件库,其灵活的架构设计可以让用户以单机或

    分布式的方式将计算部署在台式机、服务器,甚至是手机上。通过这个描述可以看出,首先, TensorFlow面向的是数值计算,虽然起初是作为深度神经网络方向研究的工具,但它在通用计算方面的应用范围也不容小觑。其次,数据流图(或称为计算图)是

    TensorFlow中对于计算过程的抽象表示。数据流图是有向图,图中的点表示各种数学

    计算操作,边表示操作与操作之间传递的高维数组数据,称为 tensor。最后,支持各

    种设备的灵活部署是 TensorFlow 最大的优势,大至分布式服务器集群,小到手机等

    移动设备,都能运行同样的机器学习算法模型。

    TensorFlow 作为一个机器学习框架系统,主要解决了机器学习方面的几个核心

    问题。

    首先,使用 TensorFlow 可以用非常简洁的语言实现各种复杂的算法模型,将研

    究从极为消耗精力的编码和调试工作中解放出来。相比早期研究所用的 MATLAB,使用 TensorFlow 实现的代码行数只是之前的一半甚至更少。代码少就意味着更不容

    易出错,也更容易排 错(debug),仅这一项就可以在实际开发中可以节省大量的时间。

    其次,TensorFlow 的内核执行系统使用 C++编写,因此保持了非常高的执行效

    率。在同类系统的横向评测中,TensorFlow始终保持在领先地位,并且首先开源了完

    整的分布式的加速方案,实验中 50个设备的并行化方案能够达到 30倍以上的加速效

    果,在执行效率上有巨大的提高。

    再次, TensorFlow优秀的分层架构设计使得模型可以非常方便地运行在异构设备

    环境上。TensorFlow采用前端编程语言与后端执行引擎分离、执行引擎又与面向硬件的计算实现分离的架构,充分实践了“高内聚、低耦合”的设计思想。可以非常方便

    在底层增加算子,甚至新增对特殊硬件设备的支持,而在上层则可以不关心硬件运行

    的特殊机理,专心在算法和应用上取得突破。

    最后,TensorFlow不仅包含 TensorBoard等优秀的配套辅助工具,第三方社区也

    贡献了诸如 TFLearn等众多好用的辅助项目,不仅使代码更简洁,也让数据处理工作

    变得轻松容易。

    2.3 TensorFlow基础概念

    2.3.1 计算图

    TensorFlow是一个基于计算图(Computational Graph,也叫作数据流图 Data flow

    Graph)的数值计算系统。计算图是一个有向图,图中的节点代表数学计算操作的算

    子(operations,简称为 op), 节 点之间连接的边代表参与计算的高维数组数据,叫做

    tensor。计算图的执行可以看作数据 tensor按照图的拓扑顺序,从输入节点逐步流过

    所有中间节点,最后流到输出节点的过程,TensorFlow 的名字由此而来。基于

    TensorFlow的计算图如图 2-2所示。

    tensor(张量)这一术语起源于力学,在物理和数学中都有重要的作用。在

    TensorFlow系统中,tensor代表多维数组(multi dimensional data array),对应神经网

    络计算中的高维矩阵。tensor可以有任意维度,每个维度也可以有任意长度。特别来

    说,一维 tensor就是向量,是普通的一维数组;二维 tensor是矩阵。TensorFlow中一

    般使用 4 维 tensor 表示一个 mini-batch 的图片,四个维度分别是批大小、像素行数、像素列数、通道数,即[batch, height, width, channels]。tensor中的元素可以是任意内

    置类型,常用的有:int32、int64、float32、float64,等等。对于神经网络来说,单精

    度 float32应该是最常用的数据类型。

    图 2-2 基于 TensorFlow的计算图示意

    算子 op 是参与计算的基本单位,每个算子都对应一种数学运算,比如:矩阵加

    法、矩阵乘法等。算子接收 0个或多个 tensor作为输入,进行一定的计算,输出 0个

    或多个 tensor的结果。在实现中,一些算子可以带有特定的属性,比如说矩阵运算算

    子带有数据类型 dtype 属性,设置数据类型可以实现计算的多态,既可以完成 int32

    类型数据的运算又可以进行 float64 类型的运算。TensorFlow内置了多种算子,表 2-1

    列出了部分类别的算子示例。

    表 2.1 TensorFlow集成的算子示例

    类 别 算 子 示 例

    数值计算操作 Add, Sub, Mul, Div, Less, Equal, ...

    数组操作 Concat, Slice, Split, Constant, Rank, Shape, Shuffle, ... 续表

    类 别 算 子 示 例

    矩阵计算操作 MatMul, MatrixInverse, MatrixDeterminant, ...

    状态操作 Variable, Assign, AssignAdd, ...

    神经网络相关操作 SoftMax, Sigmoid, ReLU, Convolution2D, MaxPool, ...

    存档操作 Save, Restore

    队列和同步操作 Enqueue, Dequeue, MutexAcquire, MutexRelease, ...

    控制流操作 Merge, Switch, Enter, Leave, NextIteratio

    与其他一些使用数据流作为计算抽象的系统(如 Spark、Tez等)有所不同的是,TensorFlow的计算图对有向图概念进行了一些扩展,加入了图的状态表示。对于神经

    网络等算法来说,有向图可以表示模型的结构,但图中边的权值参数并不是固定不变

    的,而是通过训练过程不断调整更新的。所谓图的状态,就是图中所有参数的组合。

    在 TensorFlow 中,以变量(Variable)来存储参数值。变量可以与 tensor 一样参与各

    种运算,区别在于 tensor的值在每次计算图执行完成之后立即被丢弃,而变量的值在

    通过反向传播计算更新后会保留下来,代入到下一轮训练迭代。

    TensorFlow以计算图作为抽象,为计算的表示提供了极大的空间和自由度,保证

    了各种算法实现的灵活性。

    2.3.2 Session会话

    Session是驱动 TensorFlow系统执行计算交互的入口。 Session负责完成多计算设

    备或集群分布式的节点布置和数据传输节点的添加, 并负责将子图分配给相应的执行

    器单元来运行。

    从使用角度说,典型的用法是客户端通过CreateSession接口与master建立连接,并在初始会话的过程中传入计算图。对于Python接口,计算图可以在 Session创建之

    前构造完成,并在 tf.Session 对象初始化时载入到后端执行引擎。Session 还提供了

    Extend的接口,可以在会话中修改计算图。

    触发计算图的执行通过 Run接口,也就是 Python的 tf.Session.run方法。通过这

    个接口,可以将数据代入模型,执行计算,并得到执行结果。训练过程由客户端的循

    环来控制,一般情况下,都会在一个会话中通过 Run接口执行成千上万次的计算。

    Session 管理了运行时的一系列资源的申请和分配,所以在计算完成后,必须要

    关闭 Session以释放资源。

    TensorFlow的 Python接口典型示例如下:

    import tensorflow as tf

    b = tf.Variable(tf.zeros([100])) 100维向量,初始化为全0

    W = tf.Variable(tf.random ([784,100],-1,1)) 784x100 矩阵,随机初

    始化的变量

    x = tf.placeholder(name=x) 输入占位符

    relu = tf.nn.relu(tf.matmul(W, x) + b) Relu(Wx+b)

    C = [...] 代价函数

    s = tf.Session

    for step in xrange(0, 10):

    input = ...construct 100-D input array ... 100维的输入数据

    result = s.run(C, feed_dict={x: input}) 代入x=input, 获取代价函数的计算结果

    print step, result

    2.4 系统架构

    TensorFlow 是拥有“client → master → worker”架构的分布式系统。在一般的

    执行流程中,客户端通过会话 tf.Session接口与 master进行通信,并向 master提交触

    发执行的请求,master 将执行任务分配到一个或多个 worker 进程上,执行的结果通

    过 master 返回给客户端。其中,worker 是最终负责执行计算的角色,每一个 worker

    进程都会管理和使用计算机上的计算硬件设备资源,包括一块或多块 CPU 和 GPU,来处理计算子图(subgraph)的运算过程。

    计算设备(device)是 TensorFlow系统中对计算资源定义的基础单位,由 worker

    进程管理和使用。TensorFlow官方支持 CPU和 GPU,即每个 CPU核或每块 GPU都

    是一个计算设备。每个抽象的计算设备要负责该硬件芯片上的内存分配与释放,并且

    执行上层应用所分配的计算。在系统中,每个计算设备都被分配了标识名称,该名称

    由三部分组成:worker 所属的任务名、计算设备的类型、硬件在 worker 中的编号。

    例如,“job:localhostdevice:cpu:0”代表单机 worker 中第一个 CPU 芯片设备,“job:workertask:17device:gpu:3”代表分布式环境下第 17 个 task 所在机器的第三块

    GPU 显卡。有了标识名称,上层应用可以显式地手动指定计算设备。虽然目前官方仅支持 CPU和 GPU两类设备,若想添加新的硬件设备也并不困难,TensorFlow的实

    现中将算子的定义和面向硬件的代码实现进行了分离,可以单独开发所有算子在新设

    备上执行代码,并通过注册机制注入系统,即可实现计算设备的扩展。

    TensorFlow是一个可以灵活横向扩展的架构。在单机模式下,一般 client、master

    和 worker 都在同一个进程之中启动,worker 进程会管理本机上所有的计算设备。而

    在分布式环境下,client、master 和 worker 之间会通过远程调用的方式连接在一起,每个 worker 各自独立管理执行机上的计算设备。TensorFlow 的单机与分布式架构如

    图 2-3所示。

    图 2-3 TensorFlow的单机与分布式架构

    从计算图的执行角度来说,当只有一个执行计算的硬件设备时,计算图会按照节

    点的依赖关系顺序执行。

    在单机多设备模式下,为了提高计算性能,会将计算图分解成若干个子图,每个

    子图被分配到不同的设备上执行。此时主要会面临两个问题,一个是要决定每一个计

    算节点安置在哪个硬件设备上执行,二是要在不同设备之间构建数据交互的通道。

    TensorFlow 系统要做的是要将计算图中的每一个节点与硬件的计算设备做一个映射,将算子的执行安置在合适的计算硬件设备上。这个安置过程由布置算法(placement

    algorithm)决定。基础布置算法会模拟计算图的执行,针对每一个算子节点,系统利

    用代价模型推算该操作在所有可用设备上的预计耗时,使 用贪心算法选出耗时最小的

    设备。在计算代价时,会考虑设备之间数据复制的问题,数据在设备的内存间复制传

    输往往会有比较大的时间消耗。

    当计算图的算子被布置到不同设备上时,系统会自动在跨设备的操作之间加入数

    据传输算子,如图 2-4 所示,系统会成对添加发送(send)和接收(recv)算子。此

    时,每个设备实际只负责子图的执行,子图执行所得的结果 tensor会通过发送和接收

    数据的算子在设备之间复制传输。添加通信节点的工作由系统自动完成,对于上层应

    用来说,编写的程序与单机版本并无二致,可以说极大简化了分布式的开发工作。更

    加值得一提的是,在程序实现中,数据传输是根据需要在发送和接收节点之间自动触

    发的,完全是一种去中心化的组织方式,无需 master 在其中参与调度,这可以让系

    统的横向扩展性得到极大提高。

    图 2-4 跨设备布置算子时,TensorFlow会自动添加发送和接收数据的节点

    在集群分布式环境中,执行方式与单机多设备模式比较类似,区别仅为节点通信

    是跨机器的网络通信。对于集群来说,最大的问题是容错机制。TensorFlow有两种检

    测错误的机制,一种是基于发送和接收算子之间传输的错误信息,另一种是 master

    进程的轮询检查。当发现错误后,系统会终止当前迭代,从存档状态重新运行。

    TensorFlow的分布式架构,既保证了单机环境下的易用性,又让用户在有需要时

    可以非常容易地扩展计算规模,利用集群优势提高训练效率,充分体现了 Google 工

    程师们杰出的工程架构能力。

    2.5 源码结构

    TensorFlow的系统实现采用了分层的结构,核心是由 C++语言实现的后端执行系

    统,前端则提供了基于多种语言的编程接口。在保证了执行性能的同时,又降低了学

    习门槛和应用集成的代价。

    TensorFlow系统架构的示意图如 2-5所示。

    图 2-5 TensorFlow系统架构示意图

    2.5.1 后端执行引擎

    TensorFlow 的后端执行引擎是整个系统的核心,对应源代码中的 tensorflowcore

    目录,在 TensorFlow 系统中,计算执行部分的逻辑都在此部分实现。执行系统的实

    现借鉴了NumPy等高性能数值计算库的方案,使用C++编写,以充分保证执行性能。

    从代码来分析,执行引擎主要由以下几个模块组成。

    1.系统框架(对应 coreframework目录)

    框架主要实现 TensorFlow系统的基本运行方式。其中定义了计算图、tensor、算

    子等数据结构,还包括数据类型、资源管理器、消息通信机制等基础设施。

    在算子的实现中,TensorFlow使用了注册机制。框架并不关心系统都实现了哪些

    算子,而是在运行时按注册名称查找算子的实现。这 种方式对工程扩展是非常有益的,算子的实现内聚性高,不用担心在扩展新的计算类型时对系统造成意想不到的破坏。

    2.计算图(对应 coregraph目录)

    计算图模块主要实现了计算图模型的数据结构,包括节点 Node、边 Edge 和图

    Graph等类的定义,以及图的遍历算法和在布置节点时所需的代价模型。

    3.算子声明与内核实现(对应 coreops和 corekernels目录)

    TensorFlow作为一个数值计算系统,包含了种类丰富的数学计算算子。算子的声

    明和实现是分离的。注 册声明使用 C++的宏 REGISTER_OP,其中定义了算子的名称、输入输出、算子相关参数以及说明文档。内置算子的注册声明在 ops目录中。

    计算操作在硬件上的具体代码实现被称为内核(kernel)。这个实现与计算平台相

    关,也就是说,同样的计算操作在 CPU 和 GPU 上的运行代码是不同的。对于 CPU

    计算而言,数值计算会基于 Eigen库。 Eigen库是一个 C++编写的模板库,支持整数、浮点数、复数,使用模板编程,可以为特殊的数据结构提供矩阵操作。而对于 GPU,计算会基于Nvidia的CUDA库来完成。 CUDA是计算统一设备架构(Compute Unified

    Device Architecture)的简称,它是一个并行编程平台,提供了基于 GPU加速的编程

    API。

    4.前后端交互接口(对应 coreprotobuf目录)

    TensorFlow前后端交互接口使用 protocol buffer 协议定义。在源码目录中,最主

    要的是 master_service.proto 和 worker_service.proto 两个文件,分别声明了 master 和

    worker服务的接口。这部分的定义符合了前文介绍的分布式架构。

    除了服务 API定义以外,其他 proto文件中定义了各种必要的数据结构,比如有

    master 和 worker 服务接口的请求数据结构及响应数据结构,有执行时设置的

    GPUOptions和 GraphOptions等配置的参数结构,还有用于存档模型的 MetaGraphDef

    等。

    5.运行时(对应 corecommon_runtime和 coredistributed_runtime目录)

    运行时模块负责管理程序执行时所需要的资源,其中包括对设备device的定义、内存分配 BFC (best-fit with coalescing)算法,以及计算图执行器和执行状态收集器。

    此外,运行时模块还包含了节点布置的 SimplePlacer 算法的实现。

    在分布式运行时模块中,主要实现了 master 和 worker 两个服务,以及执行调度

    器。

    6.操作系统平台(对应 coreplatform目录)

    该模块主要的作用是隔离不同的底层操作系统。 由于在Linux、 Windows、 Android、iOS,甚至 Google内部的操作系统上,底 层的接口各不相同,需要引用的库也不相同,所以先对底层操作进行封装,可以降低跨平台运行的开发成本。

    7.TFRecord数据的格式定义类 Example(对应 coreexample目录)

    Example 类是在使用 TFRecord 格式数据时必须用到的数据格式声明方法。关于TFRecord格式,将在第 3章介绍。

    2.5.2 前端语言接口

    TensorFlow目前已经支持了 CC++、Python、Java、Go等多种前端语言的接口。

    前端接口最主要的作用是利用宿主语言的优势对client进行封装,使得系统更加易用。

    以 Python 前端为例,在计算图的构建方面,使用了符号式编程(symbolic

    programming)的定义方式,即在计算图的构建阶段,命令的执行并不会真正进行数

    学运算,而是仅完成计算节点的声明。这与一般的命令式编程,即每执行一条语句就

    能得到相应的计算输出,在使用上存在一定差别,在实现一些复杂的代价函数时需要

    注意转换思路。

    TensorFlow 系统的核心是计算,也提供了多达数百种的算子。对于算子的接入,如果依靠人工逐个建立前后端 wrapper,工作量会是非常巨大的,而且针对不同语言

    也需要重复实现几乎相同的逻辑,效率比较低。为此,TensorFlow的代码中充分采用

    了代码生成技术,对于 Python 语言版本,前后端使用 swig 生成的代码相连接,Go

    语言版本则是实现了一个代码生成器,在编译期间生成所需要的代码。

    2.6 小结

    TensorFlow 自 2015年 11月开源以来一直受到业界热烈的追捧,是GitHub上机

    器学习门类中最受关注的项目。截至 2016年年底,已经获得超过 4万个 Star,被fork

    了超过 2万次。

    TensorFlow作为目前深度学习领域最优秀的项目之一,在设计理念上,充分吸收

    了 Google在众多项目上的实践经验,拥有合理的抽象表示;在工程上,Google优秀

    的工程师和开源社区共同保证了系统实现的高质量与极强的可扩展性。这都为深度学

    习领域的研究和应用实践铺平了道路。

    相信在业界共同的努力下,TensorFlow 这样一个重量级项目必将长时间持续发

    展下去。

    2.7 参考资料

    [1] TensorFlow官方网站:https:tensorflow.org

    [2] TensorFlow白皮书,https:arxiv.orgabs1603.04467

    [3] TensorFlow源代码:https:github.comtensorflowtensorflow

    [4] TensorFlow playground:http:playground.tensorflow.org

    [5] Jeff Dean Oriol Vinyals. “Large Scale Distributed Systems for Training

    Neural Networks”. NIPS 2015 Tutorial.

    [6] 谷歌大脑 Wikipedia页面:https:en.wikipedia.orgwikiGoogle_Brain

    [7] TensorFlow Wikipedia页面:https:en.wikipedia.orgwikiTensorFlow

    3

    Hello TensorFlow

    TensorFlow是一套深度学习开源软件库。从实现上来说,它的计算核心是基于高

    性能 CC++实现的,而外部封装使用的则是易用的 Python 语言。这样的设计思路不

    仅保证了软件库函数的性能,还降低了使用的难度。简单来说,使用 TensorFlow 就

    是使用 Python软件库编写深度学习程序。因此,在介绍 TensorFlow使用的同时,本

    章还会概括一些关于 Python程序的相关内容。

    本章首先介绍了开发之前的环境准备工作,包括 TensorFlow 的安装注意事项和

    一些常用的辅助函数库。随后通过解决泰坦尼克号幸存者预测这样一个典型的分类问

    题,使用 TensorFlow 实现标准的神经网络分类器。通过这个例子介绍了 TensorFlow

    提供的强大功能,并进一步概括了深度学习相关的优化技巧。

    3.1 环境准备

    在看完前面的各种介绍之后,相信各位读者一定都迫不及待地想要开始开发训练

    自己的模型了!但是还请稍安勿躁,第一步先来准备好开发运行环境。

    在操作系统方面,TensorFlow主要支持UNIX内核的操作系统,对于Windows系统

    的支持并不全面。这对于资深Windows用户来说并不是个好消息。虽然可以用虚拟机

    或者Docker之类的虚拟化方法运行,但是且不说存在比较严重的性能损失,运行起来

    仍可能存在各种小问题。所以,Mac OS或者Linux系统是安装TensorFlow的基础必要

    条件 1。

    从开发语言方面讲, TensorFlow的Python接口是功能最全且最简单的调用方式。

    而 CC++接口虽然运行效率更高,但毕竟编写和调试的门槛略高。TensorFlow 对

    Python 2和Python 3都有非常全面的支持,所 以对于Python的版本没有特别的要求,可以自由选择。本书主要以 Python 2.7 版本为主。

    在硬件方面,作为需要大量计算的深度学习程序,非常需要有强大计算性能的底

    层硬件给予支持。 GPU显卡是目前执行高精度浮点型计算性能最强的设备,所以 GPU

    服务器是深度学习研究中不可或缺的部分。理想情况下,可以在单机环境中用小规模

    数据完成代码调试,调试通过以后,在高性能的 GPU 服务器(或服务器集群)上使

    用大数据对模型进行训练。TensorFlow 目前支持 Nvidia 出品的多款显卡,只要支持

    CUDA 7.0以上驱动即可,可根据实际需求配备。

    3.1.1 Mac OS安装

    在 Mac OS 系统下,TensorFlow 的安装过程非常简单方便(千万不要说在 Mac

    的电脑上装了 Windows系统)。Mac OS是基于 UNIX的操作系统,系统中已经基本

    包含了所有 TensorFlow需要的依赖组件。

    在跟着官方教程安装之前,建议使用Homebrew重新安装Python。主要原因是,虽然Mac OS自带的Python在功能上同样完整,也可以正常使用,但部分系统路径与

    使用源码安装的版本略有差别,为了避免一些不必要的麻烦,推荐使用brew重新安装

    Python 2.72。另外,重新安装Python的一个好处是,使用pip安装Python库时不再需要

    sudo权限。

    1 TensorFlow 从 0.12.0 版本开始增加了对 Windows 系统的支持,但还存在一些明显的限制,如不能使用 HDFS 存储、不能加载自定义算子、一些内置算子还未实现等。具体详情请参

    见 TensorFlow 的版本发布声明:https:github.comtensorflow tensorflowblobmaster

    RELEASE.md。

    2 Homebrew 推荐使用 中科大镜像源 , 设置方法参见: https:lug.ustc.edu.cnwiki

    mirrorshelpbrew.git。 brew install python

    通过 Homebrew 安装的 Python的位置默认为usrlocalCellarpython。

    TensorFlow可以通过二进制包或源码安装。这里推荐使用pip安装二进制包 3

    ,pip

    为 8.1以上版本。过程非常简单,只需要短短几行命令即可。

    easy_install pip

    pip install -U six

    pip install tensorflow

    通过 pip安装的库默认位置为usrlocallibpython2.7site-packages。

    对于配备独立显卡的 Mac电脑,可以安装 GPU版本:

    pip install tensorflow-gpu

    需要注意的是,若要启用 GPU支持,需要先安装 coreutils和 cuda库。安装同样

    使用 brew,详细步骤可查看官方文档。

    顺利执行结束后,可以检测一下安装:

    python

    >>> import tensorflow as tf

    >>> hello = tf.constant('Hello, TensorFlow!')

    >>> sess = tf.Session

    >>> sess.run(hello)

    Hello, TensorFlow!

    >>>

    搞定!就是这么简单!

    3.1.2 Linux GPU服务器安装

    对于一般的深度学习程序来说,目前最具综合优势的运行设备非 GPU 莫属。

    Nvidia作为当今世界著名的显卡生产制造企业(网友戏称为核弹厂,因为出品过多款

    性能强劲但功耗和发热量都极高的“核弹级”显卡),已经早早下注深度学习领域,全力开发高性能计算显卡。在最新的评测中,几款最强显卡在关键程序上的计算性能

    3 推荐使用阿里pip源:http:mirrors.aliyun.comhelppypi。

    指标是 Intel E5系列服务器 CPU的 10倍以上。也就是说,10台CPU服务器全力运

    行,才能抵得上一块高性能计算显卡,差距十分明显。也正因如此,在深度学习的研

    究和应用方面,高性能 GPU服务器可以说是必不可少的基础设施。

    要拥有自己的 GPU 服务器可以有两种方式,一种是直接购买配件自行搭建服务

    器,另一种是购买云计算服务商提供的 GPU云主机。国内外比较知名的云计算厂商,如 Amazon、阿里云、UCloud等,都提供了 GPU云服务器的选择。而搭建自己的服

    务器能更灵活地满足业务需求,并且从目前的价格来说,也更加经济实惠。所以,在

    有条件的情况下,组装服务器是目前更推荐的选择。

    首先来介绍最为关键的GPU的选择。对于科学计算而言,决定性能最关键的指标

    是GPU的浮点运算能力。特别地,对于目前主流的深度学习应用来说,单精度浮点运

    算能力是核心需求。所以,在单精度浮点运算方面综合性价比最高的就是合理的选择。

    从这方面讲,Tesla系列虽然性能出众,但由于价格过于昂贵,对于深度学习应用来

    说优势不太明显。Geforce GTX系列一直是Nvidia在游戏市场的主打,拥有较高的性

    价比。其中,Titan X是计算单元最多、性能最高的一款产品,在深度学习研究中被广

    泛应用。在配置服务器时,推荐选择同系列显卡中性能最高的产品 4

    ,原因是如果要

    达到同等的计算能力,顶级显卡需要更少的机器数量。否则, 不仅会导致CPU、内 存 、主板、硬盘等配套硬件的额外成本,还会增加维护的成本。

    其次,服务器的供电和散热是需要重点关注的方面。Nvidia的高性能显卡素来以

    高功耗、高发热量著称,若一台服务器装满 4块或 8块显卡,那耗电量和发热量都是

    相当高的。所以,为主机配备稳定的电源,甚至 UPS 等保证供电稳定的设备,配合

    强劲的散热风扇,对保护服务器都有巨大的帮助。

    最后,除了 GPU以外的其他部分,如 CPU、内存、硬盘、网络带宽等,没有特

    别要求,达到普通服务器的平均水平就基本不会构成性能瓶颈。如果有大数据的 IO

    操作,附加配置一块 SSD固态硬盘即可满足。

    服务器的操作系统推荐选择 Ubuntu 或 Cent OS,稳定、配套全面、升级方便,4 Nvidia 官方给出了各种 GPU 计算性能的参照表,可以参看网址:https:developer.

    nvidia.comcuda-gpus。 总之就是省力省心。

    服务器初步搭建完毕后,需要安装 CUDA Toolkit和 cuDNN库以启用 GPU加速

    环境。CUDA Toolkit是 Nvidia提供的 CUDA开发套件,其中包括了CUDA驱动,以

    及编写 CUDA程序必须使用的编译器和头文件,还有一些辅助函数库。cuDNN是基

    于 CUDA Toolkit编写的专门面向深度神经网络的 GPU加速库,其中提供了一系列深

    度神经网络常用的计算,如网络的 forward 和 backward 计算、卷积计算、池化计算、标准化,以及多种激活函数, TensorFlow直接使用这些库函数来实现各种计算的 GPU

    加速。

    CUDA Toolkit直接从Nvidia官方网站上选择相应平台下载二进制安装文件即可 5。

    以CUDA 8.0 为例,下载文件为cuda_8.0.44_linux.run,使用Bash命令执行安装, 默认

    安装位置为 usrlocalcuda:

    sudo bash cuda_8.0.44_linux.run

    安装完成后可以发现,Nvidia 提供了多种辅助工具。其中,nvidia-smi 命令可以

    查看服务器上每块显卡的状态。可以从图 3-1 中看到,nvidia-smi 命令显示了服务器

    上每一块显卡的信息,包括型号、温度、功率、显存使用情况、CUDA 计算单元的

    使用情况等,还能看到哪些进程正在使用 GPU 执行计算。这些信息对程序剖析有一

    定的帮助。

    TensorFlow对于神经网络的GPU加速都通过cuDNN库实现。cuDNN可以在Nvidia

    官方网站下载 6

    ,需 要注意的是, 下载版本需要与CUDA Toolkit的版本相匹配。 cuDNN

    库以动态链接库的形式提供,解压下载tar包,并设置LD_LIBRARY_PATH环境变量

    使系统可以加载,或者将环境变量设置在 bashrc文件中会更加方便。

    5 CUDA Toolkit下载网址:https:developer.nvidia.comcuda-downloads。

    6 cuDNN下载网址:https:developer.nvidia.comcudnn。

    图 3-1 用 nvidia-smi工具查看显卡信息

    cd

    export LD_LIBRARY_PATH=`pwd`:LD_LIBRARY_PATH

    安装完 CUDA Toolkit 和 cuDNN 库后,同样使用 pip来安装 TensorFlow。

    sudo apt-get install python-pip python-dev

    sudo pip install --upgrade pip

    sudo pip install tensorflow-gpu

    检测一下安装:

    python

    >>> import tensorflow as tf

    I tensorflowstream_executordso_loader.cc:108] successfully

    opened CUDA library libcublas.so locally

    I tensorflowstream_executordso_loader.cc:108] successfully

    opened CUDA library libcudnn.so locally

    I tensorflowstream_executordso_loader.cc:108] successfully

    opened CUDA library libcufft.so locally

    I tensorflowstream_executordso_loader.cc:108] successfully

    opened CUDA library libcuda.so locally

    I tensorflowstream_executordso_loader.cc:108] successfully

    opened CUDA library libcurand.so locally

    >>> tf.__version__

    '0.12.1'

    >>>

    可以看到,与CPU版本不同的是, GPU版本的TensorFlow在启动时会加载CUDA相关的动态链接库,如 libcuda.so、libcudnn.so 等。在执行时看到这样的 log 就说明

    GPU版本 TensorFlow安装成功了。

    3.1.3 常用 Python 库

    MATLAB 曾经是机器学习领域里的主流语言,是因为它拥有强大的科学计算能

    力和丰富的数据处理库。而在当下,Python 得到了越来越多的数据分析专业人士的

    青睐,是因为它不但拥有灵活强大的语法,有较低的学习门槛,而且出现了 NumPy

    等专门用于科学计算的函数库,补足了计算性能上的问题。配合以更多辅助工具库,如绘制图形的 Matplotlib等,让 Python成为当前在机器学习领域使用最多的语言。

    这里介绍几个常用工具库。

    1.NumPy

    NumPy 库为 Python 提供了基础的科学计算能力,遵循 BSD 开源协议。在标准

    的 Python中,为了保持数组对象的动态特性,数组中实际存储的是每个元素的指针,存储和访问时都需要经过多次指针跳转。这样的方式虽然非常灵活,但对于数值运算

    来说既浪费内存又低效。NumPy 弥补了这方面的不足,它提供了如 C 语言一样的高

    效的 N维数组结构 ndarray (N-dimensional array object)和一系列直接对数组进行处理

    的函数 ufunc (universal function object),不但保留了 Python简洁灵活的语法,也带来

    了不逊于 C语言程序的运算速度。除此之外, NumPy还提供了常用的线性代数计算,甚至傅里叶变换等函数,可以进行多种信号处理。

    2.pandas

    pandas全称为 Python Data Analysis Library,是一个高性能数据结构和数据分析

    工具,同样遵循 BSD开源协议。pandas基于 NumPy构建,让以 NumPy为中心的应

    用开发变得简单。它提供了一种高效的 DataFrame 结构,可以自动对齐、补全数据,免去了由于输入数据缺失导致的问题。还可以灵活地完成增加、删除数据列,调整列

    的顺序等元数据操作。此外,DataFrame 还能像数据库一样进行一些简单的查询、聚

    合操作。因此,可以说 pandas是解决数据处理问题不可或缺的重要工具之一。

    3.Matplotlib

    Matplotlib 是功能强大的画图引擎,可以制作高质量的图表。绘图是数据分析工

    作中的一项重要任务,通过简洁易懂的类 MATLAB接口,可以只用短短几行代码绘

    制曲线图、散点图、直方图、柱状图、饼状图等图标,方便人们更加直观地感受数据,并且完成分析数据的特征、查找异常数据值等工作。另外,通过 pandas 集成的部分

    工具函数,如scatter_matrix,可以直接对高维数据进行可视化观察,对于分析数据处

    理数据有非常重要的帮助。

    4.PIL

    PIL全称 Python Imaging Library,目前已经成为 Python平台事实上的标准图片处

    理库。PIL可以方便地读入和输出包括 jpg、png等多种常见类型的图像文件,还能对

    图像做切割、翻转、添加文字等变换。是处理图像数据的常用工具之一。

    5.IPython Jupyter

    Jupyter是一个开源的交互式数据分析处理平台。 Jupyter Notebook 能以Web网页

    的形式创建和分享文档,并可以在文档中插入代码段,交互式地查看代码运行结果。

    IPython是 Jupyter的前身,也是目前 Jupyter中 Python代码的执行引擎。目前, Jupyter

    已经支持包括 R、 Julia在内的多种数据分析常用语言。同时,因其搭建服务的便捷性,加上多种扩展功能,如制作精美的幻灯片,使其成为分享代码、分享文档的利器。

    6.scikit-learn (sklearn)

    scikit-learn的标语是“Machine Learning in Python”,是构建在 NumPy、Matplotlib

    等工具之上的一套完整的机器学习工具库。在该库中封装了多种常用的分类、回归、聚类、数据降维、数据预处理等算法,三五行代码就可以完成简单机器学习模型的定

    义和训练,使数据挖掘变得非常简单。scikit-learn的接口设计是如此的合理易用,以

    至于 TensorFlow 出现以后,很多项目都仿照 scikit-learn 的接口对 TensorFlow 进行了

    二次封装,使接口更加简洁,代码更加明晰易读。

    7.OpenCV

    OpenCV的全称是 Open Source Computer Vision Library,是一款跨平台机器视觉工具库,在产品质量检测、医学成像、机器人、监控摄像机定位等多种计算机视觉应

    用领用中都有使用。 OpenCV内核使用CC++语言开发, 运行速度快。前端支持Python、MATLAB、Ruby 等多种语言。OpenCV 中包含图像滤波、特征提取、视频分析、三

    维重建等功能模块,还包括人脸识别、目标检测等高级功能,可以满足许多图像处理

    方面的高级需求。此外,由于计算机视觉与机器学习密切相关,OpenCV中还集成了

    机器学习库,可以用于处理一些模式识别和聚类方面的问题。

    在这些功能强大的工具的辅助下,数据分析处理的工作就可以事半功倍。在本书

    的实际应用例子中,会穿插介绍这些工具中的部分功能。

    3.2 Titanic 题目实战

    实践是最好的学习手段。 接下来我们通过尝试用TensorFlow解决一个分类问题,来了解 TensorFlow的编程模式和常用接口,以及一些提升预测准确率的优化思路。

    Titanic问题是Kaggle平台上的一个练手题目 7

    ,要求使用数据分析的方法预测泰

    坦尼克号的幸存者名单。 虽然这并不是一个有奖金的正式题目,仅供大家尝试和学习,但是由于数据简单整洁,又是典型的二分类问题,作为第一次实践是非常不错的题目。

    3.2.1 Kaggle平台介绍

    Kaggle平台是著名的数据分析竞赛在线平台,创始于 2010年。在 Kaggle平台上

    有各种有趣的数据挖掘挑战题目,包括分类、预测、推荐等多种类型。全世界的科学

    家和数据分析师可以以组队或者 solo 的形式参与竞赛。参赛者可以使用任何方法对

    题目给出的数据进行分析,并对测试集数据进行预测,最后平台以预测准确率为标准

    判定参赛者的成绩。一些知名企业和机构也会与 Kaggle 平台合作,将业务中的一些

    难题提出为数据挖掘任务,并设立高额奖金,让更多的专家参与解决,比如针对高清

    卫星图的物体识别、产品推荐、超声图像识别、鱼类检测识别,等等。

    Kaggle 作为竞赛平台,拥有一套比较完备的评分系统。参赛者的成绩一般以预

    测的准确率排名,预测结果越准确则排名越高。参赛者每天的排名设立了公开排行榜

    7 Titanic题目网址:https:www.kaggle.comctitanic。

    (public leaderboard)和非公开排行榜(private leaderboard)。在公开排行榜中,所有

    人随时都可以查看预测准确率和当前排名,不过这里对于准确率的计算并不是以全部

    测试数据作为基准,而只是测试集中的一部分数据,或者说可以认为是平台的验证集

    数据。公开榜可以让参赛者对自己算法的表现有一个初步评估,通过与他人的对比来

    看是否还有提升空间。为了防止参赛者利用多次提交的方法来试探测试集数据的结果,人肉对测试数据“过拟合”,竞赛最终成绩由另一份测试数据,也就是非公开排行榜

    的排名所决定的。

    除了举办各种比赛之外,Kaggle平台上还积累了各种有趣的数据集 8。其中被关

    注较多的有欧洲足球赛对战数据,在这份数据中囊括了超过 25000 场比赛和超过

    10000名球员的数据,其中被详尽记录(进球、角球、越位、红黄牌等)的比赛就超

    过 1 万场,甚至有 10 家博彩机构给出的投注赔率。通过这样的大数据不仅可以对各

    个球员或球队的历史进行多维度分析,计算各种单项和综合实力,更能对未来的表现

    进行预测。这样丰富全面数据确实不可多得。

    Kaggle 平台是一个可以让人们充分交流的地方,参赛者们不仅比拼技术,更能

    交流经验。即使只是翻看各个题目的讨论帖,也会觉得受益匪浅,例如题目会有数据

    图形化讨论专区,在里面会从各种维度给出数据的可视化视图。这对于初学者来说是

    非常好的学习途径。

    3.2.2 Titanic 题目介绍

    泰坦尼克号轮船(RMS Titanic,又称为铁达尼号)的沉没是历史上最著名的海

    难事故之一。作为当时世界上最大的客运轮船,它在处女航中由于撞上冰山导致轮船

    断裂,并最终沉入大西洋。当时船上共有 2224名乘客和船员,其中 1502名丧生。在

    回顾这样一场浩劫的过程中,分析发现造成如此巨大损失的原因之一是当时轮船上并

    没有准备足够的救生艇。在这起事件发生后,除了推动建立了更合理的航行安全规范

    外,人们还分析了当时对于仅有的救生艇位置的分配过程,虽然最后幸存是有一定的

    运气成分,但一些乘客确实比另外一些更容易获救,比如妇女、儿童,以及高级舱位

    的乘客。

    8 Kaggle数据库:https:www.kaggle.comdatasets。 本题目是希望重新站在客观的视角来重新回顾这一事件。通过分析事发时的数据,使用机器学习的方法来预测哪些乘客最终能在这次灾难中幸存下来。更具体来说,是

    通过乘客的各项信息,如姓名、性别、年龄、乘船客舱等级等信息,尝试预测每位乘

    客幸存的概率。

    既然是要预测每位乘客是否可以幸存,那么可以认为这是一个二分类问题,即一

    类标签为存活,另一类标签为丧生。我们最终需要训练一个分类器,可以是 SVM、神经网络、随机森林等模型,来判定样本所属的类别。

    对于此类数据挖掘题目,对数据进行一些简单的分析和处理是必要的第一步。从

    Kaggle网站下载本问题的数据集 9

    ,可以看到,数据分为训练集和测试集两类,均以

    csv格式存储。训练集数据文件train.csv大小为 59.76KB,包含 891条数据,测试集数

    据文件test.csv的大小为 27.96KB,包含 418条数据。在数据文件中,每一行是一个样

    本,代表一名乘客的信息,包含以下 12个字段,如表 3-1所示。

    表 3-1 Titanic 挑战字段说明

    字段名称 字段解释 类 型 说 明

    PassengerId

    乘客 ID

    int

    训练集数据 ID 编号为 1~891,测

    试集数据编号为892~1309

    Survived 是否幸存 bool 0:故去,1:幸存

    Pclass

    客舱等级

    int

    客舱分为 3 级,1 为头等舱,2 为

    中等舱,3 为普通船舱

    Name 乘客姓名 string

    Sex 乘客性别 string male: 男性, female: 女性

    Age 乘客年龄 int 年龄为整数

    SibSp 兄弟姐妹和配偶在船数量 int

    ParCh 父母孩子的在船数量 int

    Ticket 船票编号,例“STONO2. 3101282” string

    Fare 船票价格 float

    Cabin 客舱位置,例“C123” string

    Embarked

    登船港口的编号,例“S”

    string

    C代表 Cherbourg;

    Q代表 Queenstown;

    S代表 Southampton

    9 Titanic问题数据下载网址:https:www.kaggle.comctitanicdata。

    其中,“Survived”字段代表该名乘客最终是否生还,是样本的标签字段。图 3-2

    展示了前 10条训练数据的内容:

    图 3-2 Titanic挑战前 10条样本数据

    测试集的每条数据包含了除“Survived”字段以外的其他所有字段。

    最后需要输出的结果包含两列,分 别为测试集乘客 ID和对应乘客是否幸存预测。

    通过观察题目给定的条件, 我们可以根据一些生活常识和对Titanic事件的了解,对数据进行一些初步推断。比如我们看过《泰坦尼克号》电影的都知道,事故发生在

    寒冷的海上冰山,如果在轮船沉没前登上了为数不多的救生筏,则基本可以幸存,否

    则落入寒冷的大西洋就一定是凶多吉少,就像电影中的男主人公 Jack 一样。那么在

    这样一种情况下,都有哪些人登上了救生筏呢? 首先是妇女和儿童,轮船上大部分

    人为英国人,英国是讲究绅士风度的国家,不管是船员还是乘客都会一致认为应该让

    妇女和儿童先登上救生筏,也因此妇女儿童幸存的比例会比成年男性要高。其次,高

    等客舱的乘客基本是贵族、军官等有身份地位的人,他们在事故发生后也会得到额外

    照顾,获得优先登上救生筏的资格。剩下的其他人就没有那么幸运了,幸存概率比较

    低。这些先验知识,在后续的判定中将起到非常大的作用。

    对于我们认为相关性较高的字段,比如客舱等级“Pclass”、 乘 客性别“Sex”、乘

    客年龄“Age”, 将 在之后作为主要的特征字段,需要经过正规化(Normalization)处

    理后转换为数值形式。在本例中,正规化主要有三个方面,一是将字符串字段转换为

    数值化的表达方式,比如将性别字段原本取值“male”和“female”分别转换为 0 和

    1,这样才能作为分类器的输入;二是可以将数值都归一化到 [0, 1] 的取值范围内,比如年龄字段原本的值域是 [0, 100),归一化过程可以是将每个值都除以 100;三是

    补齐缺失数据。 除了我们认为的关键字段以外,其他字段可能也包含很多有用的信息,部分可以

    经过挖掘转换后作为特征使用。对于一些现实生活中的复杂问题,人类的认知可能也

    是片面的、不准确的,真实的相关性可能隐藏在其他数据中,所以抓取更多数据是惯

    用的思路,但同时会随之出现维度灾难(curse of dimensionality)的问题,也就是维

    度过多、无效的噪声过多,导致无法有效地从中过滤出真正有用的信息。在本例中,如姓名“Name”、 父 母子女在船舱数量“ParCh”、 客 舱位置“Cabin”、 登 船码头编号

    “Embarked”等几个字段,猛一看似乎与能否逃生并没有太大的直接关系,但若经过

    挖掘也许能有意外的收获。在本章后半部分会进一步深入讨论。

    经过上述分析后,我们可以得出解决 Titanic 问题的主要思路,即首先采用正规

    化操作等手段对原始数据进行预处理,然后挑选特征向量的维度,并以此训练一个分

    类器,最终使用训练好的分类器来预测测试集数据的结果。

    接下来,就可以进入真正的编码解题阶段。作为首次尝试,无须追求一步到位地

    做到最好,而应该先以简单规则得出基线(baseline)版本,然后不断优化以得到更

    好的结果。因此,我们首先尝试用 TensorFlow 训练一个逻辑回归分类器来看看效果

    如何。

    整个代码可以分为:数据读入及预处理,构建计算图,构建训练迭代过程,执行

    训练、存储模型,预测测试数据结果几个部分。下面就对每一部分分别加以介绍 10。

    3.2.3 数据读入及预处理

    对数据进行预处理会使用到 pandas和 scikit-learn库所提供的一些功能。

    首先,使用 pandas内置的数据文件解析器读入数据。 pandas内置了多种解析器,可以直接处理 csv、pickle、json、excel、html等常用的数据文件格式,甚至还可以从

    MySQL 数据库或者操作系统的剪切板中读入数据。读入操作非常简单,只需要用

    read_csv 函数读取 train.csv 文件,读入的数据为一个 DataFrame 类型的对象。

    import pandas as pd

    从CSV文件中读入数据

    10 完整版本代码可参见:https:github.comwangchen1renTitanic。

    data = pd.read_csv('train.csv')

    DataFrame 是一个类似于电子表格的二维数据结构,长度可变,维度可变,类型

    亦可变。在 DataFrame 中,行列都经过排序编号。

    可以通过 DataFrame.info方法查看数据的概况:

    >>> data.info

    

    RangeIndex: 891 entries, 0 to 890

    Data columns (total 12 columns):

    PassengerId 891 non-null int64

    Survived 891 non-null int64

    Pclass 891 non-null int64

    Name 891 non-null object

    Sex 891 non-null object

    Age 714 non-null float64

    SibSp 891 non-null int64

    Parch 891 non-null int64

    Ticket 891 non-null object

    Fare 891 non-null float64

    Cabin 204 non-null object

    Embarked 889 non-null object

    dtypes: float64(2), int64(5), object(5)

    memory usage: 83.6+ KB

    可以看到,数据包含 891 条记录,下标编号为 0 到 890。数据包含 12 个列,正

    如前面介绍过的一样。其中,PassangerId、Survived、Pclass、Age、SibSp、Parch、Fare几个字段为数值类型 (64位整形或 64位浮点型) ,而 Name、 Sex、 Ticket、 Cabin、Embarked 字段是对象,其实也就是字符串类型。同时,还可以从这个简短的统计看

    到,Age、Cabin、Embarked三个字段存在缺失的情况,Age字段只有 714个有效值,缺失 177个;Embarked有 889个值,缺失 2个;Cabin字段仅有 204个值,缺失达到

    687个。

    为了方便处理,我们仅保留Sex、Age、Pclass、SibSp、Parch、Fare这 6个字段。

    在前文中提到,首先对各字段做正规化处理。具体来说,要将 Sex字段的字符串进行

    转换,将“male”替换为 0,将“female”替换为 1。同时,将 Age 字段有缺失的部

    分统一赋值为 0。 另外,需要将样本的标签转换为独热编码(one-hot encoding)。 独 热编码又称为

    一位有效编码,是分类标签常用的编码方式。具体来说,就是使用 N 位布尔型的状

    态标识来对 N 种状态进行编码,任意时刻编码中只有一位有效,即取值为 True。在

    本例中, Survived是幸存一类的标签,新建一个 Deceased字段来表示乘客是否死亡,其取值为 Survived的取非。这样 Survived 与 Deceased两个字段一起相当于构成了一

    组 one-hot编码。

    取部分特征字段用于分类,并将所有缺失的字段填充为 0

    data['Sex'] = data['Sex'].apply(lambda s: 1 if s == 'male' else 0)

    data = data.fillna(0)

    dataset_X = data[['Sex', 'Age', 'Pclass', 'SibSp', 'Parch', 'Fare']]

    dataset_X = dataset_X.as_matrix

    两种分类分别是幸存和死亡,'Survived'字段是其中一种分类的标签, 新增 'Deceased' 字段表示第二种分类的标签,取值为 'Survived' 字段取非

    data['Deceased'] = data['Survived'].apply(lambda s: int(not s))

    dataset_Y = data[['Deceased', 'Survived']]

    dataset_Y = dataset_Y.as_matrix

    然后,为了防止训练过拟合,我们将仅有的标记数据分成训练数据集(training

    dataset)和验证数据集(validation dataset)两类。验证数据不参与模型训练,样本数

    占全部标记数据的 20%。scikit-learn 库中提供了用于切分数据集的工具函数

    train_test_split,随机打乱数据后按比例拆分数据集。

    from sklearn.model_selection import train_test_split

    使用 sklearn 的 train_test_split 函数将标记数据切分为“训练数据集和验证

    数据集

    将全部标记数据随机洗牌后切分,其中验证数据占20%,由test_size参数指定

    X_train, X_test, y_train, y_test = train_test_split(

    dataset_X, dataset_Y, test_size=0.2, random_state=42)

    3.2.4 构建计算图

    逻辑回归是形式最简单,并且最容易理解的分类器之一。从数学上,逻辑回归的

    预测函数可以表示为如下公式:

    y′

    = softmax(xW+ b)

    其中,x为输入向量,是大小为d × 1的列向量,d是特征数。W是大小为c × d的

    权重矩阵, c是分类类别数目。 b是偏置向量,为c × 1列向量。在数学定义里, softmax是

    指一种归一化指数函数。它将一个k维的向量z按照下列公式

    δ(z)j =

    ezj

    ∑ ezk K

    k=1

    的形式将向量中的元素转换为(0, 1)的区间。机器学习领域常使用这种方法将类似判

    别函数的置信度值转换为概率形式(如判别超平面的距离等)。softmax函数常用于输

    出层,用于指定唯一的分类输出。

    权重矩阵W和偏置向量b是模型中的参数,也就是要通过训练来求得的部分。

    使用 TensorFlow 构建这样的计算过程是十分简单的,整个构建计算图的过程只

    需要以下几个步骤。

    1.使用 placeholder声明输入占位符

    在第 2 章中曾经介绍过,TensorFlow 设计了数据 Feed 机制。也就是说计算程序

    并不会直接交互执行,而是在声明过程只做计算图的构建。所以,此时并不会触碰真

    实的数据,而只是通过 placeholder 算子声明一个输入数据的占位符,在后面真正运

    行计算时,才用数据替换占位符。

    声明占位符 placeholder 需要给定三个参数,分别是输入数据的元素类型 dtype、维度形状 shape 和占位符名称标识 name。TensorFlow 内置了所有标准数据类型,包

    括 int16、uint16、int32、uint32、float16、float32、string 等,在指定元素类型时可以

    直接使用。维度形状使用数组指定。若 shape 不指定,默认值为 None,表示任意形

    状。需要注意的是,通过 mini-batch批量训练是如今常用的优化技巧,通常能在更短

    时间内得到更好的拟合效果。所以在定义输入形状时,一般将第一个维度作为

    mini-batch 维度,而从第二个维度开始才是特征维度。占位符名称 name 用于区分计

    算图里的各个节点,不管在查找节点,还是在可视化方面,设置容易识别的名称都非

    常有帮助。名称参数 name 默认也为 None,系统会自动将节点设置为类似

    “Placeholder:0”这样的名称。

    本例中,对于模型来说有两个输入数据,一个为特征数据 X,由 Sex、 Age、 Pclass、SibSp、Parch、Fare这 6个字段的值组成,另一个为标记值 y,由 Deceased、Survived

    两个字段组成。

    声明输入数据占位符

    shape参数的第一个元素为None,表示可以同时放入任意条记录

    X = tf.placeholder(tf.float32, shape=[None, 6])

    y = tf.placeholder(tf.float32, shape=[None, 2])

    2.声明参数变量

    逻辑回归模型中包含两个参数,分别是权重矩阵W和偏置向量b。TensorFlow 使

    用变量(Variable)来存储和更新这些参数的值。

    变量的声明方式是直接定义 tf.Variable对象。初始化变量对象有两种方式,一

    种是从 protocol buffer结构 VariableDef中反序列化,另一种是通过参数指定初始值。

    最简单的方式就是像下面程序这样,为变量传入初始值。初始值必须是一个 tensor

    对象,或是可以通过 convert_to_tensor方法转换成 tensor的 Python对象。 TensorFlow

    提供了多种构造随机 tensor 的方法,可以构造全零 tensor、随机正态分布 tensor 等。

    定义变量会保留初始值的维度形状。

    值得注意的是,变量 Variable的构造函数同样也没有做数据的初始化,而是在计

    算图中加入了一个 variable算子和其对应的 assign算子。

    声明变量

    W = tf.Variable(tf.random_normal([6, 2]), name=’weights’)

    b = tf.Variable(tf.zeros([2]), name=’bias’)

    3.构造前向传播计算图

    所谓前向传播就是网络正向计算,由输入计算出标签的过程。逻辑回归的公式用

    TensorFlow表示只需要一行代码:

    y_pred = tf.nn.softmax(tf.matmul(input, W) + bias)

    其中,tf.matmul是矩阵乘法算子,tf.nn.softmax是 softmax 函数。另外可以看

    到,对于偏置向量 bias,可以直接用加号“+”完成矩阵相加操作,这与 NumPy等库用

    法类似。 TensorFlow中的 Tensor对象和 Variable对象都对常用四则运算符号进行过重

    载,运用十分灵活。

    在计算图的构建过程中,TensorFlow会自动推算每一个节点的输入输出形状。若

    无法运算,比如两个行列数不同的矩阵相加,则会直接报错。

    4.声明代价函数

    机器学习算法的优化需要靠代价函数来评估优化方向。本 例的二分类问题一般使

    用交叉熵(cross entropy)作为代价函数。

    交叉熵的计算公式为:

    C = -

    1

    n

    ∑y log (y′)

    x

    程序代码为:

    使用交叉熵作为代价函数

    cross_entropy = - tf.reduce_sum(y tf.log(y_pred + 1e-10),reduction_indices=1)

    批量样本的代价值为所有样本交叉熵的平均值

    cost = tf.reduce_mean(cross_entropy)

    值得注意的是,在计算交叉熵的时候,对模型输出值 y_pred 加上了一个很小的

    误差值(在上面程序中是 1e-10),这是因为当 y_pred 十分接近真值 y_true 的时候,也就是 y_pred 的值非常接近 0 或 1 时,计算 log(0) 会得到负无穷 -inf,从而导致

    输出非法,全部都是 nan,并进一步导致无法计算梯度,迭代陷入崩溃。要解决这个

    问题有三种办法:

    ● 在计算 log 时,直接加入一个极小的误差值,使计算合法。这样可以避免计

    算log(0),但存在的问题是加入误差后相当于 y_pred 的值会突破 1。在示例代

    码中使用了这种方案;

    ● 使用 clip 函数,当 y_pred 接近 0 时,将其赋值成为极小误差值。也就是将

    y_pred 的取值范围限定在 [10-10, 1] 的范围内;

    ● 当计算交叉熵的计算出现 nan 值时,显式地将 cost 设置为 0。这种方式回避了

    log 函数计算的问题,而是在最终的代价函数上进行容错处理。

    5.加入优化算法

    TensorFlow 内置了多种经典的优化算法,如随机梯度下降算法(Stochastic

    Gradient Descent, SGD)、动 量 算 法(Momentum)、 Adagrad算法、 ADAM算法、 RMSProp

    算法,另外还有在线学习算法 FTRL。优化器内部会自动构建梯度计算和反向传播部

    分的计算图。

    一般对于优化算法,最关键的参数是学习率(learning rate),对于学习率的设置

    是一门技术。同时,不同优化算法在不同问题上可能会有不同的收敛速度,在解决实

    际问题时可以做多种尝试。

    使用随机梯度下降算法优化器来最小化代价,系统自动构建反向传播部分的计算图

    train_op =

    tf.train.GradientDescentOptimizer(0.001).minimize(cost)

    至此,计算图的声明过程就完成了。

    3.2.5 构建训练迭代过程

    完成了计算图的定义,再接下来要构建训练迭代。

    在第 2 章中提到过,在 TensorFlow 的设计中,前端编程语言要触发后端执行引

    擎开始计算,必须通过 Session 接口完成。Session 对象负责将运行环境打包,并且

    管理运行时需要处理的变量、队列(queues)、读取器(readers)等资源。

    需要特别说明的是,由于 Session 中管理了上下文的各种资源,所以在计算执行

    结束后一定要关闭,以释放对资源的占用。一般有两种使用方式,一种是在声明后手

    动调用 Session.close方法来关闭,一般会在大型应用中使用。另外一种是更为简便

    的方式,Session 类重载了 __enter__ 和 __exit__ 两个方法,所以可以用 Python

    的 with 语句将 Session 作为上下文管理器(Context Manager)来操作,退出作用域

    时自动关闭对象。

    Session 启动后就正式进入了训练过程。首先要做的是使用 tf.global_variables_

    initializer.run 方法初始化所有的变量 11。接下来就是用一个循环将训练数据反复

    代入计算图来执行迭代。在循环内,Session.run是触发后端执行的入口。

    Session.run 有两个关键的参数,fetches 和 feed_dict。其中,fetches 指定需要

    被计算的节点,可以用数组同时制定多个节点。节点可以是算子 op,比如前文程序

    中的优化算法算子 train_op,也可以是 tensor,比如代表代价函数值的 cost。执行会

    从输入节点开始,按照节点的依赖关系,也就是有向图的拓扑序,依次计算目标节点

    所在的子图中的所有节点。计算所需要的输入数据则由 feed_dict 代入。feed_dict 需

    要传入一个字典,字典的 key是输入占位符 placeholder,value为真实的输入数据。

    Session.run 执行完计算后,会返回计算节点的结果。若节点为算子,则没有返

    回值,若节点是 tensor,则返回当前的值。比如最常见的优化算子和代价函数 tensor

    的组合,而优化算子的执行结果其实是通过梯度下降算法更新所有参数变量,不需要

    返回值,而在前向传播计算得到的代价值将会返回。

    通过将每一轮迭代的代价值打印出来,可以监控训练的收敛情况。

    with tf.Session as sess:

    初始化所有变量,必须最先执行

    tf. global_variables_initializer( .run

    以下为训练迭代,迭代10轮

    for epoch in range(10):

    total_loss = 0.

    for i in range(len(X_train)):

    feed = {X: [X_train[i]], y_true: [y_train[i]]}

    通过session.run接口触发执行

    _, loss = sess.run([train_op, cost], feed_dict=feed)

    total_loss += loss

    print('Epoch: %04d, total loss=%.9f' % (epoch + 1,total_loss))

    print 'Training complete!'

    训练迭代循环执行结束后,用验证数据集评估模型的表现。

    评估校验数据集上的准确率

    11 注:TensorFlow 0.12.0之前的版本使用tf.initialize_all_variables.run,在最新版本代码中

    标明该接口将于2017年 3月 2日后正式废弃。 pred = sess.run(y_pred, feed_dict={X: X_val})

    correct = np.equal(np.argmax(pred, 1), np.argmax(y_val, 1))

    accuracy = np.mean(correct.astype(np.float32))

    print(Accuracy on validation set: %.9f % accuracy)

    从上面代码中可以看到,若只计算模型预测值 y_pred,则只需要传入占位符 X

    所对应的数据即可,不需要指定另一个占位符 y。TensorFlow在计算时会进行图的剪

    枝优化,只会计算 fetches 指定的子图,因此也只需要代入子图包含的占位符。在这

    一点上,TensorFlow保证了编程的灵活性和执行效率,在使用时不用担心会执行不必

    要的计算。

    3.2.6 执行训练

    将代码保存为 01_tensorflow_basic.py 文件,通过命令行运行程序即可看到训

    练过程中的输出。

    python 01_tensorflow_basic.py

    Epoch: 0001, total loss=5827.214925724

    Epoch: 0002, total loss=1866.215580815

    Epoch: 0003, total loss=1416.462430373

    Epoch: 0004, total loss=1274.361242647

    Epoch: 0005, total loss=1287.683731217

    Epoch: 0006, total loss=1207.134947834

    Epoch: 0007, total loss=1191.541045362

    Epoch: 0008, total loss=1180.067145067

    Epoch: 0009, total loss=1169.640558892

    Epoch: 0010, total loss=1160.065555358

    Training complete!

    Accuracy on validation set: 0.586592197

    可以看到,通过 10 轮迭代的训练,代价值从 5827 下降到 1160,这代表模型对

    训练数据的拟合越来越好,误差越来越小。同时还可以看到,在验证数据集上,本次

    训练的预测正确率为 58%。

    在执行程序的时候,可能会遇到的最常见的错误有如下几种:

    ● 变量未初始化

    开启 session 后的第一步就需要初始化所有变量,否则在执行其他操作时将会产

    生如下错误:

    FailedPreconditionError: Attempting to use uninitialized value

    Variable

    解决方法是在 Session 对象初始化后,紧接着执行 tf.global_variables_

    initializer.run 方法。

    ● 真实数据与占位符形状不匹配

    如果在执行时出现类似下面这样的错误:

    ValueError: Cannot feed value of shape (2,) for Tensor

    u'Placeholder_1:0', which has shape '(?, 2)'

    那一般是从 feed_dict 代入的真实数据的数组形状与占位符不匹配导致的。在确

    认传入数据无误的情况下,可以使用 numpy.reshape将数据调整成需要的形状后再

    代入计算。

    ● Session 已关闭

    若在 Session作用域之外执行运算,就会报出如下错误:

    RuntimeError: Attempted to use a closed Session.

    这时候就要检查确认 Session.run语句是在 Session 对象生命周期作用域内执行

    的。

    3.2.7 存储和加载模型参数

    训练是一件十分费时耗力的事情,如果每次预测之前都还要训练,那显然是不现

    实的。正确的姿势是在训练得到一组优秀的参数时将其保存下来,预测时直接加载到

    模型中使用。 TensorFlow当然也满足了这一需求,使用的是 tf.train.Saver 和 checkpoint

    机制。

    变量的存储和读取是通过 tf.train.Saver 类来完成的。Saver 对象在初始化时,为

    计算图加入了用于存储和加载变量的算子,并可以通过参数指定是要存储哪些变量。

    Saver对象的save和 restore方法是触发图中算子的入口。 Checkpoints 是用于存储变量的二进制文件,在其内部使用字典结构存储变量,键为变量名字,即 Variable.name 成员的值,值为变量的 tensor 值。TesnorFlow 代码

    中提供了一个工具程序可以用于查看 checkpoint 文件的内容,代码在

    tensorflowpythontoolsinspect_checkpoint.py。

    Saver最简单的用法就如下面代码所示。

    v1 = tf.Variable(tf.zeros([200]))

    saver = tf.train.Saver

    在Saver之后声明的变量将不会被Saver处理

    v2 = tf.Variable(tf.ones[100]))

    训练Session创建参数存档

    with tf.Session as sess1:

    完成模型训练过程...

    持久化存储变量

    save_path = saver.save(sess1, model.ckpt)

    在新Session中加载存档

    with tf.Session as sess2:

    加载变量

    saver.restore(sess2, model.ckpt)

    判别预测,或继续训练...

    需要注意的是,Saver 对象在初始化时,若不指定变量列表,默认只会自动收集

    其声明之前的所有变量,在 Saver对象初始化后的所有变量将不被记录,上面代码中

    的 v2 变量就不会在存取的范围内。这样的机制在迁移学习的应用中非常有用,例如

    要将一个基于 ImageNet数据训练好的 CNN应用在新类型图片识别上, 只需要加载模

    型卷积部分的参数,重新训练最后的全连接网络即可。

    在上面的程序示例中,由Saver.save触发的存储操作会生成 4个文件 12。第一个

    是名为“model.ckpt”的文件,这个文件是真实存储变量及其取值的文件。第二个是

    名为“model.ckpt.meta”的描述文件,在这个文件存储的是MetaGraphDef结构的对象

    12 TensorFlow 0.12.0 版本之后,对于变量存储的定义升级为 V2 版本。此前的版本不会生成

    “.index”为后缀的文件,只有其他三个。

    经过二进制序列化后的内容。MetaGraphDef结构由Protocol buffer定义,其中包含了

    整个计算图的描述、各个变量定义的声明、输入管道的形式,以及其他相关信息。

    meta文件可以在没有计算图声明代码的情况载入模型,而若在应用时还有原始的

    Python程序代码,程序就已经可以重新构建计算图的基本信息,则加载只需要

    “model.ckpt”一个文件即可。第三个文件是以“model.ckpt.index”为名称的文件,存

    储了变量在checkpoint文件中的位置索引。最后一个是名为 “checkpoint”的文件,这个文件中存储了最新存档的文件路径。

    模型存档有两种存取模式,除了上面示例展示的一次性存储之外,还有一种方式

    是通过引入迭代计数器的方式,按训练迭代轮次存储。 使用这种方式时,需要在 save ......

您现在查看是摘要介绍页, 详见PDF附件(6948KB,304页)