本文翻译自 http://www.deeplearningbook.org/contents/applications.html
待续...
第 12 章
应用
在本章中,我们将介绍如何使用深度学习来解决计算机视觉,语音识别,自然语言处理,和其它应用商业领域的应用问题。我们首先讨论了最需要认真思考的 AI 应用所需的大规模神经网络的实现。接下来,我们回顾几个深度学习已被用来解决特定的应用领域。深度学习的一个目标是设计出能够广泛解决各种各样任务的算法,这需要一些专业化的知识。例如,视觉任务需要为每一帧处理大量的输入特征(像素)。语言任务需要为每个输入特征模拟大量的可能值(词汇表中的单词)。
12.1 大规模深度学习
深度学习是基于联结的理念:一个独立的生物神经元或一个单独的功能在机器学习模型中并不具有智能,但大量的这些神经元或功能的集合一起行动时却能表现出智能行为。确实需重要强调一个事实,即神经元的数量一定要 大。从 80 年代到今天,有一个关键因素,它改善了神经网络的精确性,并提高了能够解决的任务的复杂性,这就是急剧增加的我们使用的网络的规模。正如我们在第 1.2.3 节中看到的那样,网络规模虽然在过去三十年呈几何级数的增长,但人工神经网络的规模目前只是相当于一只大型昆虫的神经系统。
由于神经网络的规模是非常重要的,深度学习需要高性能的硬件和软件基础设施。
12.1.1 快速 CPU 实现
传统上,神经网络只用一台机器的 CPU 进行训练。今天,这种方法通常被认为是不够的。我们现在主要使用 GPU 或多台联网的机器的多个 CPU 进行计算。在使用这些昂贵的设备之前,研究人员曾努力证明 CPU 没有能力管理神经网络所需的超高计算工作量。
如何实现高效的 CPU 字节码的描述超出了这本书的范围,但是我们在这里强调一下,认真为具体的 CPU 型号做出优化可以产生大的改进。例如,在 2011 年可用的最好的 CPU 使用定点算术而不是浮点运算时,可以使运行的神经网络工作负载的速度更快。通过创建一个精心调校过的定点实现,[Vanhoucke 等 (2011)]() 获得了超过 3 倍加速,相比另一个强大的浮点系统。CPU 的每一个新的型号有不同的表现特点,所以有时浮点实现也可能更快。最重要的原则是认真对数值计算例程做专业化的调校可以产生很高的回报。其他策略,除了选择使用固定还是浮点之外,还包括优化数据结构,避免高速缓存未命中以及使用向量指令。许多机器学习研究者忽视这些实施细节,但是当一个实现的性能限制了模型的规模时,模型的精度会受到影响。
12.1.2 GPU 实现
最现代的神经网络的实现是基于图形处理单位。图形处理单元(GPU)最初是为图形应用程序开发的专用硬件。消费市场对视频游戏系统的追捧,刺激了图形处理硬件的发展。优秀的视频游戏系统对高性能的要求的特点对神经网络也是有益的。
视频游戏渲染需要并行快速执行许多操作。人物模型和环境模型使用特定的 3 维顶点的坐标来表示。显卡必须执行矩阵乘法和除法,并行的将这些顶点的三维坐标转换成 2 维屏幕上的坐标。然后,显卡必须并行的执行许多计算各像素,以确定每个像素的颜色。在这两种情况下,该计算是相当简单的,并且不涉及多分支的情况,相比一个 CPU 通常遇到的情况中的计算工作量。例如,每个顶点在同一个刚性物体中将用相同的矩阵相乘;不需要通过一个 if 语句来判断每个顶点乘哪个矩阵。这些计算也是完全相互独立的,因此可以很容易并行化。该计算还涉及到处理大量的缓冲区内存,把包含每个对象的质地的描述(颜色模式)的位图呈现出来。这些加在一起,导致显卡被设计为适合高度并行并且拥有很高的存储器带宽,代价是具有较低的时钟速度和相对较少的分支计算能力相比传统的 CPU。
神经网络算法需要与上述实时图形算法相同的性能特征。神经网络通常涉及巨大的缓冲区和众多的参数,变化值和梯度值,每个值必须在训练的每一步被完全更新。这些缓冲器足够大导致经常落入传统台式计算机的高速缓冲存储器的外部,所以该系统的存储器带宽往往成为速率限制的因素。图形处理器,由于其高内存带宽,提供了超过 CPU 的令人信服的优势。神经网络训练算法通常不涉及太多的分支或复杂的控制,它们更适合 GPU 的硬件。由于神经网络可以分为多个单独的“神经元”,并独立地交给处在同一层的其他神经元来处理,神经网络很容易从 GPU 计算的并行性中获益。
GPU 硬件原本是只能用于计算图形任务。随着时间的推移,GPU 硬件变得更加灵活,允许自定义子程序被用于转化顶点或指定颜色的坐标为像素。原则上,并没有要求这些像素值实际上基于渲染的任务。这些 GPU 可用于科学计算,由计算的输出写入到像素值的缓冲区。Steinkrau 等 (2005年)]() 证明了同样的技术可以被用来加快监管卷积网络。
通用 GPU 问世后显卡的神经网络训练被普及并呈爆炸式增长。这些通用 GPU 可以执行任意代码,不只是渲染子程序。NVIDIA 的 CUDA 编程语言提供了一种方法来写一个类似 C 语言的任意代码。凭借其相对方便的编程模型,大规模并行处理和高内存带宽,通用 GPU 提供了神经网络编程的理想平台。[Raina 等人,2009; Ciresan 等人,2010]()在这个平台被证明可用后,这个平台迅速被深度学习研究人员采用。
写高效的通用 GPU 代码仍然是一个艰巨的任务,最好留给专家来完成。获得在 GPU 上良好的性能所需的技术与在 CPU 上使用是非常不同的。例如,良好的基于 CPU 的代码通常是设计成:尽可能读取来自缓存的信息。在 GPU 上,大多数可写内存位置并没有缓存,所以它实际上可以更快的计算同一个值两次,而不是只计算一次,以后从内存中读回来。GPU 代码也是固有多线程的,并且不同的线程之间必须与对方认真协调。例如,内存操作的速度更快,如果它们可以被 合并。合并的读取或写入发生在多个可以读或写的线程同时需要一个值时,作为单一的一次内存访问的一部分。不同型号的 GPU 能够合并不同类型的读或写模式。通常情况下,如果在 n
个线程之间,线程 i
访问地址为 i + j
的存储器上的字节,而且 j 是 2 的幂数,这时内存操作更容易合并。不同型号的 GPU 的确切规格是不同的。另一种常见的对于 GPU 来说需要考虑的是:确保一组中的每个线程同步地执行相同的指令。这意味着在 GPU 上实现分支可能非常困难。线程被划分成称为 wrap
的多个小组。同一个 wrap
中的每个线程,在每个周期期间执行相同的指令,因此,如果同一个 wrap
内不同的线程需要执行不同的代码路径,这些不同的代码路径必须按顺序执行而不是平行。
由于编写高性能 GPU 代码的难度大,研究者应该构建他们的工作流程,以避免需要编写新的 GPU 代码,来测试新模型或算法。通常情况下,人们可以通过建立一个高性能运算的软件库,实现例如卷积矩阵乘法,然后根据不同的需求调用这个库的指定操作。例如,机器学习的库 Pylearn2 Goodfellow 等,2013c 和 CUDA-convnet Krizhevsky, 2010 和 Torch [Collobert 等,2011b]() 也一样提供了类似的功能。
12.1.3 大规模分布式实现
在许多情况下,在一台机器上可用的计算资源 不足。 因此,我们要分发的训练和推理的工作量 在许多机器。 分发推理很简单,因为每个输入例子中,我们要处理 可以通过一个单独的机器上运行。 这就是所谓的 数据并行性 。 另外,也可以得到 模型并行 ,在多台机器的工作 一起在单个数据点,每个机运行的不同部分 模型。 这对于推断和培训是可行的。 在训练期间数据并行是有点困难。 我们可以增加大小 用于单个SGD一步minibatch,但通常我们得到的比线性少 返回优化性能方面。 这将是更好地使多个 机计算并行的多个梯度下降步骤。 不幸, 梯度下降的标准定义是一个完全顺序算法: 在步骤梯度是由步骤产生的参数的函数 。 ŧ 笔- 1 这可以通过使用 异步随机梯度下降 ( 解决 Bengio 等 , ; 2001年的法 2011 等 , )。 在这种方法中,几个处理器内核共享 代表参数的存储器。 每个核心读取参数没有 锁,然后计算的梯度,然后在不锁递增的参数。 这减少了改进,每个梯度下降步骤中的平均量 产量,因为一些核心的互相覆盖的进步,但增加 生产步骤的速度使学习的过程会更快的整体。 迪恩 等 ( )首创了多机实现这种无锁的方法 2012 以梯度下降,其中的参数一个 参数服务器 管理 而不是存储在共享存储器。 分布式异步梯度下降 仍然是主要的战略,培养大而深的网络,并且由 在行业最主要的深度学习组( , ; Chilimbi 等人 2014年吴等人 , 2015年 )。 学术深度学习研究人员通常无法承担同等规模 分布式学习系统,但一些研究主要集中于如何建立 在大学提供的分布式网络,成本相对较低的硬件 设置 ( , )。
12.1.4 模型压缩
在许多商业应用中,降低时间和内存在机器学习模型推断时的开销比降低时间和内存在训练时的开销更重要。对于不要求个性化的应用,有可能只训练模型一次,就将其部署出去给十亿用户使用。在许多情况下,最终用户比开发者受到更多的资源限制。例如,你可能用性能强大的计算机集群来训练一个语音识别网络,然后在手机上部署它。
减少推理成本的关键策略是模型压缩(Bucilua 等,2006)。模型压缩的基本思想是,使用一个需要更小存储空间和更少计算时间的模型来取代原来的开销巨大的模型。
模型压缩适合用在当原始模型的大小主要由防止过拟合来决定的情况。在大多数情况下,拥有最低泛化误差的模型是几个独立训练的模型的协奏。评估所有 n
个集合成员是昂贵的。有时候,单一模型反而概括的更好,如果它是足够大的(例如,对把误差规律化)。
这些大型模型学习到一些函数 f(x)
,但可能会使用比任务所必需的更多的参数。这些多余的大小是必须的,只是由于训练事例的数量有限。如果我们拟合这个函数 f(x)
,就可以产生一个包含无穷多例子的训练集,只要通过映射 f
到随机的抽样点 x
。然后,我们训练新的,更小的模型以匹配 f(x)
到这些点。为了最有效地使用这些新的、小的模型,最好是从一个离散的类似于以后将要提供给模型的实际测试输入中采样新的 x
点。这可以通过破坏训练实例,或在生产模型上使用原始训练集画出点来实现。
或者说,你可以只在原始训练点上训练小模型,但训练它复制模型的其它特征,比如它后面的分布在不正确的类 (Hinton 等,2014, 2015)。
12.1.5 动态结构
对于一般加速数据处理系统的一个策略是构建系统 具有 动态结构在描述所需的计算的曲线 处理输入。 数据处理系统可以动态地确定哪些 许多神经网络的子集应该在给定的输入来运行。 个别神经 网络也可以通过内部确定哪些子表现出动态结构 特征(隐单位)计算从输入给定的信息。 这个 神经网络内动态结构的形式有时称为 条件 计算 ( , ; , )。 自的许多组件 Bengio 2013 Bengio 等人 2013b 体系结构可以只对少量的可能的输入,该系统是相关可以通过运行在需要时只计算这些功能更快。 计算的动态结构是应用了基本的计算机科学原理 一般在整个软件工程学科。 最简单的版本 施加到神经网络的动态结构是基于确定哪些 一些组神经网络(或其他机器学习模型)的子集应 被应用到特定的输入。 在分类器加速推断一个令人尊敬的策略是使用级联 分类的。 当目标是检测级联策略可被应用于 罕见的对象(或事件)的存在。 肯定知道该对象存在, 我们必须使用一个复杂的分类具有容量高,这是运行成本。 然而,因为对象是罕见的,我们通常可以用少得多的计算 拒绝输入作为不包含对象。 在这些情况下,我们可以训练 分类器的一个序列。 序列中的第一分类器具有低的容量, 并进行培训,具有较高的召回。 换句话说,它们被训练,以确保 我们当对象存在不错误地拒绝输入。 最终的分类 被训练精度高。 在测试时,我们通过运行运行推理 分类器在一个序列中,一旦放弃任何实施例中任一个元件 级联拒绝。 总的来说,这使我们能够验证与物体的存在 高置信度,使用高容量的型号,但并不迫使我们付出的成本 全推断每个例子。 有两种不同的方法,该级联 可以实现高容量。 一种方法是,使级联的后面部件 分别具有高的容量。 在这种情况下,系统作为一个整体显然 高容量,因为它的一些成员个人的事。 它也可以 使级联,其中每个单独的模型具有容量低,但系统 作为一个整体具有很高的容量,由于许多小型号的结合。 堇菜 和2001年琼斯 ( )用于提高决策树的级联实现快速, 适用于手持式数码相机强大的人脸检测器。 他们的分类 利用本地化本质上滑动窗口的办法脸中,许多窗户 被检查,如果它们不包含面拒绝。 级联的另一个版本 使用较早的机型实现了几分硬关注机制: 级联的早期成员本地化级联的目的及以后的成员 执行给定的对象的位置进一步处理。 例如,谷歌 录制采用两步级联从街景视图地址号码 首先定位到地址号码与一个机器学习模型,然后 与另一个转录它( 古德费洛 2014d 等 , )。 决策树本身是动态的结构的一个例子,因为每个 在树中节点确定哪些其子树的应为每个输入进行评估。 一个简单的方法来实现深度学习和动态结构的结合是培养,其中每个节点使用的神经网络,使决策树 分裂的决定( , ),虽然这通常不被 郭和1992年盖尔芬德 与加速推理计算的首要目标完成。 以同样的精神,可以使用神经网络,被称为 选择哪个 门控器 几个 专家 网络之一出将用于计算输出,鉴于 电流输入。 这个想法的第一个版本被称为 专家的混合物 ( , NOWLAN 1990年雅各布斯 1991年 ; 等 , ),其中,所述门控器输出一组概率或 权重(通过SOFTMAX非线性获得),一个每专家,并且最终输出 由专家的输出的加权组合获得。 在那里面 情况下,使用门控器的不提供在计算成本的降低,但如果 单专家由门控器对于每个实施例所选择,我们得到 硬混合物 专家 ( , , ),它可以显着加速训练 Collobert 等 2001 2002 和推理时间。 这种策略效果很好,当门的数量决定是 小,因为它不组合。 但是,当我们要选择不同的子集 单元或参数,是不可能使用的“软开关”,因为它需要 枚举(和计算产出)所有门控器配置。 交易,处理 这个问题,几种方法已探索培养组合 gaters。 ( )实验与梯度的几个估计 Bengio 等人 2013b 在门的概率,而 ( )和 ( ) 使用 培根 等人。2015年 Bengio 等 2015A 强化学习技术(政策梯度)学习的条件形式 辍学的隐藏单元块,并获得计算实际减少 成本而不对近似的质量产生负面影响。 另一种动态的结构是一个开关,其中一个隐藏的单元可以 从根据上下文不同的单元接收输入。 这种动态路由 方法可以被解释为注意机制( , )。 Olshausen 等 1993 到目前为止,使用的硬开关的并未证明在大规模应用程序有效。 现代方法,而不是使用一个加权平均值在许多可能的输入, 因此不会实现所有的动态的可能计算的好处 结构体。 当代的关注机制二段描述。 。 12.4.5.1 使用动态结构的系统的一个主要障碍是下降 并行度从系统以下不同代码分支结果 对于不同的输入。 这意味着在网络中的一些操作可被描述 作为例的minibatch矩阵乘法或分批卷积。 我们 可以写出更专业化的子例程卷积不同的每个示例 内核或由不同组列乘以设计矩阵的每一行 的权重。 不幸的是,这些更专门的子程序是难以 有效地实施。 CPU实现将是缓慢的,由于缺乏缓存 一致性和GPU实现将是缓慢的,由于缺乏的聚结内存交易并需经纱序列化时,经成员采取 不同的分支。 在某些情况下,这些问题都可以通过分割来减轻 举例成团,所有采取同样的分支,处理这些群体 实例同时进行。 这可以是用于最小化在可接受的策略 所需的时间来处理一个脱机设置的例子的固定量。 在 一个实时的环境,实施例必须被连续地处理,分区 工作量会导致负载平衡的问题。 例如,如果我们指定一个 机加工以级联的第一步和另一台机器来处理 在一个级联的最后步骤,则第一将趋向于超载和最后 将趋向于被欠载。 出现类似的问题,如果每个机被分配给 实现神经决策树的不同节点。
12.1.6 深度网络的专用硬件实现
由于神经网络研究的初期,硬件设计师花了 专门的硬件实现,可以加快培训和/或 神经网络算法推断。 见的早期和近期的评论 专门的硬件深网( , ; , 林赛和林德布劳德1994年Beiu 等。 2003米斯拉和萨哈2010 ; , )。 不同形式的专业硬件( 格拉夫和Jackel公司1989年和米德 , ; 伊斯梅尔·金2012 2009年范 陈2012 2014A b , ; 等 , ; 等 , ; 等 , ,)有 已开发在过去几十年来,无论是与的ASIC(特定应用的英特 磨碎电路),或者与数字(基于数字的二进制表示), 模拟( 格拉夫和Jackel公司1989年米德和伊斯梅尔2012 , ; , )(基于物理imple- 连续的值的mentations如电压或电流)或混合的实现 (结合数字和模拟组件)。 近年来更灵活的FPGA (现场可编程门阵列)实现(的地方细节 电路可以已经开发了它已建成后的芯片)上被写入。 虽然在通用处理单元软件实现(CPU的 和GPU)的一般使用的精密32或64位来表示浮点 号,它早已知道,这是可以用较少的精确度,在 至少在推理时间( 霍尔特和贝克1991年霍利和黄某1993年普雷斯利 , ; , ; 憔悴1994年锡马德和1994年格拉芙Wawrzynek 1996年Savich , ; , ; 等 , ; 等 , 2007年 )。 这已成为一个更加紧迫的问题,近年来随着深度学习 已获得在工业产品的普及,为更快的巨大影响 硬件被证明与图形处理器。 这促使目前的另一个因素 对深厚的网络专用硬件的研究是社会进步的速度 一个单一的CPU或GPU核心有所放缓,而最近的改进 运算速度已经跨越核心(无论是在CPU或来自并行图形处理器)。 这是从20世纪90年代的情况(以前的神经非常不同 网络时代),其中神经网络的硬件实现(这可能 需要两年的时间,从开始到芯片的可用性)无法跟上 飞速进步和通用CPU的价格低。 建筑专业 硬件因此,当新的硬件,以进一步推动信封,在时间的方式 设计正在为低功率设备如电话开发的,旨在为 深度学习(比如,一般公众的应用,演讲,计算机视觉或 自然语言)。 基于backprop神经网络的低精度的实现近期工作 (Vanhoucke 2011 Courbariaux 2015年古普塔 2015年 等 , ; 等 , ; 等 , )建议 该精度8至16位可以足够使用或培训深 神经网络的反向传播。 显而易见的是,更多的精度 训练比在推理时间过程中所需的,并且,某些形式的动态 数字的定点表示可以用来减少多少位都 每个号码必需的。 传统的固定点数字限制为一个固定 范围(其对应于给定指数在一个浮点表示)。 动态定点表示共享一组数字之间的范围内 (如在一个层中的所有的权重)。 使用固定的点,而不是浮点 交涉和使用更少的比特数每降低了对硬件的表面积, 需要进行乘法功耗要求和计算时间, 和乘法是使用最苛刻的操作的需要或 训练与backprop现代深网络。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。