动手学深度学习

面向中文读者的能运行、可讨论的深度学习教科书

就在几年前,不管在大公司还是创业公司,都鲜有工程师和科学家来将深度学习应用到智能产品与服务中。作为深度学习前身的神经网络,才刚刚摆脱被机器学习学术界认为是过时工具的印象。那个时候,即使是机器学习也非新闻头条的常客。它仅仅被看作是一门具有前瞻性,并拥有一系列小范围实际应用的学科。在包含计算机视觉和自然语言处理在内的实际应用通常需要大量的相关领域知识:这些实际应用被视为相互独立的领域,而机器学习只占其中一小部分。

然而仅仅在这几年之内,深度学习便令全世界大吃一惊。它非常有力地推动了计算机视觉、自然语言处理、自动语音识别、强化学习和统计建模等多个领域的快速发展。随着这些领域的不断进步,我们现在可以制造自动驾驶的汽车,基于短信、邮件甚至电话的自动回复系统,以及在围棋中击败最优秀人类选手的软件。这些由深度学习带来的新工具也正产生着广泛的影响:它们改变了电影制作和疾病诊断的方式,并在从天体物理学到生物学等各个基础科学中扮演越来越重要的角色。

与此同时,深度学习也给它的使用者们带来了独一无二的挑战:任何单一的应用都汇集了各学科的知识。具体来说,应用深度学习需要同时理解:

  1. 问题的动机和特点;
  2. 将大量不同类型神经网络层通过特定方式组合在一起的模型背后的数学原理;
  3. 在原始数据上拟合极复杂的深层模型的优化算法;
  4. 有效训练模型、避免数值计算陷阱以及充分利用硬件性能所需的工程技能;
  5. 为解决方案挑选合适的变量(超参数)组合的经验。

同样,我们几位作者也面临前所未有的挑战:我们需要在有限的篇幅里糅合深度学习的多方面知识,从而使读者能够较快理解并应用深度学习技术。本书代表了我们的一种尝试:我们将教给读者概念、背景知识和代码;我们将在同一个地方阐述剖析问题所需的批判性思维、解决问题所需的数学知识,以及实现解决方案所需的工程技能。

包含代码、数学、网页、讨论的统一资源

我们在2017年7月启动了写作这本书的项目。当时我们需要向用户解释Apache MXNet在那时的新接口Gluon。不幸的是,我们并没有找到任何一个资源可以同时满足以下几点需求:

  1. 包含较新的方法和应用,并不断更新;
  2. 广泛覆盖现代深度学习技术并具有一定的技术深度;
  3. 既是严谨的教科书,又是包含可运行代码的生动的教程。

那时,我们在博客和GitHub上找到了大量的演示特定深度学习框架(例如用TensorFlow进行数值计算)或实现特定模型(例如AlexNet、ResNet等)的示例代码。这些示例代码的一大价值在于提供了教科书或论文往往省略的实现细节,比如数据的处理和运算的高效率实现。如果不了解这些,即使能将算法倒背如流,也难以将算法应用到自己的项目中去。此外,这些示例代码还使得用户能通过观察修改代码所导致的结果变化而快速验证想法、积累经验。因此,我们坚信动手实践对于学习深度学习的重要性。然而可惜的是,这些示例代码通常侧重于如何实现给定的方法,却忽略了有关算法设计的探究或者实现细节的解释。虽然在像Distill这样的网站和某些博客上出现了一些有关算法设计和实现细节的讨论,但它们常常缺少示例代码,并通常仅覆盖深度学习的一小部分。

另外,我们欣喜地看到了一些有关深度学习的教科书不断问世,其中最著名的要数Goodfellow、Bengio和Courville的《深度学习》。该书梳理了深度学习背后的众多概念与方法,是一本极为优秀的教材。然而,这类资源并没有将概念描述与实际代码相结合,以至于有时会令读者对如何实现它们感到毫无头绪。除了这些以外,商业课程提供者们虽然制作了众多的优质资源,但它们的付费门槛依然令不少用户望而生畏。

正因为这样,深度学习用户,尤其是初学者,往往不得不参考来源不同的多种资料。例如,通过教科书或者论文来掌握算法及其相关数学知识,阅读线上文档学习深度学习框架的使用方法,然后寻找感兴趣的算法在这个框架上的实现并摸索如何将它应用到自己的项目中去。如果你正亲身经历这一过程,你可能会感到痛苦:不同来源的资料有时难以相互一一对应,即便能够对应也可能需要花费大量的精力。例如,我们需要将某篇论文公式中的数学变量与某段网上实现中的程序变量一一对应,并在代码中找到论文可能没交代清楚的实现细节,甚至要为运行不同的代码安装不同的运行环境。

针对以上存在的痛点,我们正在着手创建一个为实现以下目标的统一资源:

  1. 所有人均可在网上免费获取;
  2. 提供足够的技术深度,从而帮助读者实际成为深度学习应用科学家:既理解数学原理,又能够实现并不断改进方法;
  3. 包含可运行的代码,为读者展示如何在实际中解决问题。这样不仅直接将数学公式对应成实际代码,而且可以修改代码、观察结果并及时获取经验;
  4. 允许我们和整个社区不断快速迭代内容,从而紧跟仍在高速发展的深度学习领域;
  5. 由包含有关技术细节问答的论坛作为补充,使大家可以相互答疑并交换经验。

这些目标往往互有冲突:公式、定理和引用最容易通过LaTeX进行管理和展示,代码自然应该用简单易懂的Python描述,而网页本身应该是一堆HTML及配套的CSS和JavaScript。此外,我们希望这个资源可以作为可执行代码、实体书以及网站。然而,目前并没有任何工具可以完美地满足以上所有需求。

因此,我们不得不自己来集成这样的一个工作流。我们决定在GitHub上分享源代码并允许提交编辑,通过Jupyter记事本来整合代码、公式、文本、图片等,使用Sphinx作为渲染引擎来生成不同格式的输出,并使用Discourse作为论坛。虽然我们的系统尚未完善,但这些选择在互有冲突的目标之间取得了较好的折中。这很可能是使用这种集成工作流发布的第一本书。

从在线课程到纸质书

本书的两位中国作者曾每周末在线免费讲授“动手学深度学习”系列课程。课程的讲义自然成为了本书内容的蓝本。这个课程持续了5个月,其间近3,000名同学参与了讨论,并贡献了近5,000多个有价值的讨论,特别是其中几个参加比赛的练习很受欢迎。这个课程的受欢迎程度出乎我们的意料。尽管我们将课件和课程视频都公开在了网上,但我们同时觉得出版成纸质书也许能让更多喜爱纸质阅读的读者受益。因此,我们委托人民邮电出版社来出版这本书。

从蓝本到成书花费了更多的时间。我们对所有涉及的所有技术点补充了背景介绍,并使用了更加严谨的写作风格,还对版式和示意图做了大量修改。书中所有的代码执行结果都是自动生成的,任何改动都会触发对书中每一段代码的测试,以保证读者在动手实践时能复现结果。

我们的初衷是让更多人更容易地使用深度学习。为了让大家能够便利地获取这些资源,我们保留了免费的网站内容,并且通过不收取出版稿费的方式来降低纸质书的价格,使更多人有能力购买。