Theano与其他深度学习框架的比较,主要强调一系列低水平的设计选择,没有特别顺序。

概述

  • 微分

  • 计算图形/IR

  • 优化

  • 调度

  • GPU/CPU透明化

  • 外部函数接口

  • 动态编译/元编程

  • Theano 心愿列表

微分

符号微分:Theano,CGT;自动微分:Torch, MXNet

虽然符号微分和自动微分实现的方式完全不同,但在实际使用中符号微分和自动微分总是被混淆或者交替出现

反向自动微分是反向传播的一般化 [1].当需要计算梯度时,输入是向前传播通过计算图时,各个节点记住的值。然后进行图的反向遍历,该方法称为每个节点的“backward(反向)”方法,它使用梯度(相对于节点的输出)作为参数。

另一方面,符号微分取决于每个运算符有其自己的梯度定义,即构建图的相同符号运算符。当某个参数的梯度需要计算时,就会反向遍历节点,每个节点都返回一系列扩展计算图的符号运算符。最后的结果是一个扩展的计算图,它定义了一个从输入到梯度的路径。

图形尺寸

如果采用自动微分法,同一个图需遍历两次,同时需要优化和编译一半的图。

调试

自动微分法更容易调试,因为在用户调用每个操作符的某一个点上都会产生一个错误。使用符号微分,新的操作符可能作为梯度计算的一部分出现,这对用户来说定位错误抛出点比较困难。

优化

符号微分需要通过图的彻底优化达到诸如删除公共子表达式的目的,而自动微分不需要。然而,符号微分法可能要考虑更多的优化,如操作符在向前传播时不能融合,而在反向传播时可以融合。

记忆

自动微分需要每个操作符来记住它的输入(至少,原始的实现是这么做的[2])。记忆优化后的符号微分的记忆效率可能更高。

高阶导数

符号微分法的优点在于只有前向R-op需要实现。而使用自动微分法,我们需要实现前向和后向R-op[3].

灵活性

当我们有多个损失函数且需要有一个符号表示梯度以进行进一步处理时,符号微分似乎更加灵活。自动微分法支持多种情况,但为了能够进一步给出梯度的符号表达式,需要对框架进行扩展。

[1]Automatic differentiation in machine learning: a survey

[2]The Data-Flow Equations of Checkpointing in Reverse Automatic Differentiation

[3]torch/nn#399

计算图形/IR

许多深度学习的库都依赖于计算图能力,它可以作为我们程序的中间表示( intermediate representation, IR)。图的惰性构造可以优化(Theano, CGT),调度(MXNet),或者自动微分(Torch, MXNet) 。问题在于此图应该包含什么信息。

形状

在构造图时定义一个张量的的形状,这么做会显著的降低灵活性(例如,小批量有不同的形状)。另外,形状信息可以完全地从图中排除,这是theano目前的情况(除了一些诸如卷积的特殊运算)。 [*] 中间区域使得规范化的形状信息可选。这可以用于优化目的:如果一些张量确定是固定大小的,那么他们可以在编译前就分配(从内存效率性能考虑)[4].

内存分配

内存分配是IR组成的一部分,这意味着我们可以用y = x + 1代表Var(x), Constant(1) -> [Add] -> y, 或者代表const_storage = Allocate((1,)); y_storage = Allocate(x.shape); const_storage, x_storagey_storage -> [Add] ->y_storage。无论是哪种方法,优点都是不明确的。

循环和分枝

循环和分枝可以用不同的方式来实现。Theano的方法看起来是通过把环当做单结点来实现计算图的无环性(scan运算符),其本身包含另一个计算图。分支由任务调度器处理(在Theano中常常也称作虚拟机)。其他的大多数框架不支持循环和分枝。一种更加有说服力的处理循环的方法是在计算图中允许循环。为了保持严格的静态单一赋值(SSA,[ 5 ])的形式,需要实现Phi函数(或是类似的东西[ 6 ])。保持图形平面使循环更具扩展性,例如允许嵌套循环。

设备独立性

Theano尝试支持各种后端,在Theano中,他们分享相同的IR,这在优化阶段转化为一个指定设备的表示。与设备独立的优化通过设置优化的“等级”把指定设备分离。这种编程方式可以使分离更充分。通过这种编译器,我们将有一个IR优化器和一个完全独立的设备特定的优化器和(或者)任务调度器。

[4]MXNet documentation

[5]Wikipedia: Static single assignment

[6]WebKit code

优化

Theano特点的之一是它的优化引擎,这既保证了计算效率,也保证了数值稳定性[7]。只有CGT模仿这种行为;其他框架不包含优化框架。一个明显的并行可以从优化文献中得出:

  • 公共子表达式消除(Common subexpression eliminiation,CSE,在Theano中使用merge 函数)

  • 常量折叠(Constant folding)

  • 常量传播(Constant propagation)

  • 代数简化(Algebraic simplification,加,乘等等)

  • 代数重新关联(Dead store elimination,称为“规范化”)

  • 死存储消除(Dead store elimination,Theano将丢弃不需要计算指定输出的部分计算图)

  • 操作强度降低/局部优化(Operator strength reduction/local optimizations,例如合并多个操作符成一个单一的GEMM调用)

Theano应用更加独特的是数字稳定性优化(这违反一个编译器产生语义等价输出的概念)。

非逐元素融合(Non-elementwise fusing)

一个有趣的想法是评估操作符non-elementwise融合的可能性,例如矩阵与矩阵乘法有一个共同的结合面,例如Y = Wx和Y’= W’x可以计算单一调用[Y| Y’] =[W | W’]x(LSTM在模块中的实现技巧)。这样做涉及内存分配优化。

调试

一个优化框架使得调试复杂化,因为结果计算图和用户构造图的不同使得它很难确定哪个确切指令造成了错误。

性能

优化的主要目的是提高性能。对于Theano,有和没有优化的差异显著。然而,其他的框架可以实现和没有优化的Theano框架相似的速度。这可能是由于Theano细粒度(finer-grained)运算符(相对于其他框架更独立的“层”),或是它们对于Theano来说是一种内在固有的低效率。

可用性

一个优化的框架需要用户较少的专业知识;低效操作符的自动优化,允许用户集中于构建模型,而不是优化其代码的效率。

[7]Theano optimizations

调度

任务调度(或指令调度,并行与优化文献)是在计算图节点(操作符)已被优化之后(必选,可选,编译)执行的调度。显著增益可以在这里通过使用并行获得(CUDA中的streams[8],CPU中的threads)。许多新的框架都集中这个方法上,例如MXNet [9], Purine [10], Minerva [11]等等。

[8]CUDA streams

[9]MXNet’s “dependency engine”

[10]Purine: A bi-graph based deep learning framework

[11]Minvera’s “dataflow engine”

多GPU

调度程序还可以编写支持多GPU的情况。自动模式的并行性是远远不足以解决问题的,而数据的并行可以采用一种简单的方式来调度。

异步调用

理想情况下,调度器应该异步调用。例如,数据传输和计算可以并行执行的,所以我们在原来的数据仍在计算时,在GPU加载数据。在某些情况下,可以取得显著的结果。明智地编码及接口,比当前的方法更复杂。

CUDA 流与事件

CUDA内核可以同时发出多个单独的CUDA流,从而并行执行。它们还可以做出同步让它们等待事件。非常想知道通过这些方法可以受益多少(如通过调用诸如cudaEventQuery来比较采取0流[0 stream]还是同步流[ synchronizing streams])。

GPU/CPU 透明化

CPU和GPU之间可以通过多种方法进行交互。

完全透明化(Fully transparent)

Theano不仅尝试在需要时通过交互来完全地透明化卸载GPU,而且可以完全透明地把数据转入和转出主机。例如,当一个特定的操作符仅在CPU上实现时。好处是即使不是在GPU上实现的运算,仍然可以利用GPU来加速。缺点是Theano在用户未意识到的情况下给主机传递数据表现欠佳(例如,他们使用了高级索引)。这意味着用户仍需编写”GPU-runnable”Theano代码。

显式传输(Explicit transfers)

Torch 使用了一种更明显的方法。GPU-enabled操作符只接受GPU数组,反之也是如此。在GPU移动张量仅仅需要调用张量的cuda()或者double()函数[†]。 优点是用户能够完全意识到正在执行计算任务的设备。缺点是脚本需要通过把张量转移给GPU来占用GPU。

互斥模式(Exclusive mode)

最后一个选项是在单个计算图中不允许CPU与GPU之间的传输。缺点是,如果用户真的需要在CPU上执行一部分计算,他们需要需要构建和编译独立的计算图。优点是用户能够完全意识到传输的过程。在内部,这种约束可以简化代码。这也是我相信Caffe的一面。

需要注意的是Torch并没有一个图形编译器或者任务调度器,这意味着用户任何时候都可以以用一条命令来调用 cuda()或者 double()终止计算。很难想象这种在GPU-CPU之间的显性传输在完全计算图方法中是怎样的。

外部函数接口

Theano:C扩展 , CGT: Cython, scikit-cuda: ctypes, cuda4py: CFFI

Python和C语言的之间的接口有各种各样的方法。

C 扩展 (Python C API)

Theano的当前做法,资源开销较少,支持较好,但引入了一定的复杂性,如:用户可以负责传递Python对象的引用计数。

Ctypes

部分标准库,可以使用诸如scikit-cuda形式的方法。特别简单,支持度较好并且仅要求Python代码。然而,会出现很大的开销(与C-API相比,开销会从50%提升至250%)。

CFFI

PyPy的首选方式是与C做接口,这个灵感是来源于LuaJIT的 FFI(这是Torch使用Lua语言编写的主要原因)。这种方式比较冗长,但是速度很快而且简单,cuda4py库采用的就是这个。

Cython

当前流行的框架将Python版本的扩展(注释)编译成C扩展。Cython在库CGT中被采用。[15]

Numba

尽管Numba不直接提供C语言的直接接口,但是它的JIT编译器支持把Python函数和ctypes [16] 与CFFI[17]一起调用编译,以此来加快速度。

[12]http://www.dalkescientific.com/writings/NBN/c_extensions.html

[13]http://stackoverflow.com/a/8069179

[14]cuda4py

[15]cycgt.pyx

[16]Numba ctypes

[17]Numba cffi

动态编译/元编程

上述库可以动态编译操作符(如Theano),也可以简单地调用预编译的操作符(如Torch)。

性能

内核和C函数的动态编译使他们能够完全专业化,跳过不必要的输入检查,少用一般的实现,而是用更有效的实现。像cuDNN和cuBLAS框架,使用手动调整内核减少动态编译的需要,因为它们往往比自定义编写那些更加有效。

编译时间

具有动态编译的操作引入了在评估之前等待函数编译的需要。这可以通过使操作的非编译版本来减轻(例如,一些Theano操作符有numpy的实现),但要注意,这会引起维持每个操作符多个实现的负担,并需要操作符的行为相同。

核融合

有了动态编译的内核允许,例如element-wise操作可以被融合到单个内核中。对于GPU编程,这可以是有益的,因为启动内核和从全局将数据传输到共享存储器开销可能非常大。在Theano,这被称为“elemwise fusion”。

外部语言接口

如果计算图形的多个节点可以一起编译,那么它可以限制来自主机语言的函数调用次数(例如Python中的Theano,Lua中的Torch)。对于像Python这样的语言,具有相对缓慢的FFI和显著函数调用的开销,这么做会显著提高效率。

鲁棒性

动态编译操作在管道中引入了一个编译步骤,它可以是错误的源,例如(库)路径一定要设置正确,在编译过程中会出现的内存问题等等。动态编译的操作符难以调试,因为重现这个错误可能需要重现在该操作符被编译下的确切条件。

共享库

CGT编译在运行时被动态链接的分享库,而Theano编译的是一个Python C-API扩展(需要python和numpy头文件)。后者显著更慢。

Theano 心愿列表

  • 坚持使用符号微分。

  • 没有更多的动态编译(除了逐元素内核可能融合);像cuDNN手动调整的库已经减少了这种方法的优点,它明显地简化了代码,等待模块进行编译。

  • 支持计算图形循环,来自phi函数的全部SSA。

  • GPU任务调度支持CUDA流和异步调用。

  • CFFI或者Cython接口;C-API更复杂,如果一些更人性化的替代品表能够以类似的速度执行,那么就会带来一些优势。

  • 独占CPU/GPU模式;简化代码并移除意外减慢的源。

  • 从后端优化严格分离IR。

  • 蓝天思维:Non-elementwise的内核融合,需要智能的内存分配。

原文链接:A comparison of deep learning frameworks
译者:刘帝伟 审校:刘翔宇
责编:周建丁(投稿请联系zhoujd@csdn.net)

2016年3月18日-19日,由CSDN重磅打造的数据库核心技术与实战应用峰会、互联网应用架构实战峰会将在上海举行。这两场峰会将邀请业内顶尖的架构师和技术专家,共同探讨高可用/高并发系统架构设计、新技术应用、移动应用架构、微服务、智能硬件架构、云数据库实战、新一代数据库平台、产品选型、性能调优、大数据应用实战等领域的热点话题与技术。(报名参会)

Theano与其他深度学习框架的比较相关推荐

  1. Keras深度学习框架配置

    北京 | 深度学习与人工智能研修 12月23-24日 再设经典课程 重温深度学习阅读全文> 正文共7349个字,49张图,预计阅读时间19分钟. 作者:周纵苇 微博:@MrGiovanni 邮箱 ...

  2. 简易的深度学习框架Keras代码解析与应用

    北京 | 深度学习与人工智能研修12月23-24日 再设经典课程 重温深度学习阅读全文> 正文约12690个字,22张图,预计阅读时间:32分钟. 总体来讲keras这个深度学习框架真的很&qu ...

  3. 2017深度学习最新报告及8大主流深度学习框架超详细对比(内含PPT)

    2017深度学习最新报告(PPT) ​ 深度学习领军人物 Yoshua Bengio 主导的蒙特利尔大学深度学习暑期学校目前"深度学习"部分的报告已经全部结束. 本年度作报告的学术 ...

  4. 转:【AI每日播报】从TensorFlow到Theano:横向对比七大深度学习框架

    http://geek.csdn.net/news/detail/139235 说到近期的深度学习框架,TensorFlow火的不得了,虽说有专家在朋友圈大声呼吁,不能让TensorFlow形成垄断地 ...

  5. 深度学习框架的介绍与比较(Caffe, TensorFlow, MXNet, Torch, Theano)

    在这里,我将会介绍当前比较主流的5种深度学习框架,包括 Caffe, TensorFlow, MXNet, Torch, Theano,并对这些框架进行分析. 首先对这些框架进行总览. 库名称 开发语 ...

  6. DL框架:主流深度学习框架(TensorFlow/Pytorch/Caffe/Keras/CNTK/MXNet/Theano/PaddlePaddle)简介、多个方向比较、案例应用之详细攻略

    DL框架:主流深度学习框架(TensorFlow/Pytorch/Caffe/Keras/CNTK/MXNet/Theano/PaddlePaddle)简介.多个方向比较.案例应用之详细攻略 目录 深 ...

  7. 深度学习框架的比较(MXNet, Caffe, TensorFlow, Torch, Theano)

    1. 基本概念 1.1 MXNet相关概念 深度学习目标:如何方便的表述神经网络,以及如何快速训练得到模型 CNN(卷积层):表达空间相关性(学表示) RNN/LSTM:表达时间连续性(建模时序信号) ...

  8. python机器学习系列教程——深度学习框架比较TensorFlow、Theano、Caffe、SciKit-learn、Keras

    全栈工程师开发手册 (作者:栾鹏) python教程全解 Theano Theano在深度学习框架中是祖师级的存在.Theano基于Python语言开发的,是一个擅长处理多维数组的库,这一点和nump ...

  9. 深度学习:常见深度学习框架【Theano、TensorFlow、Keras、Caffe/Caffe2、MXNet、CNTK、PyTorch】

    常见的深度学习框架有 TensorFlow .Caffe.Theano.Keras.PyTorch.MXNet等,如下图所示.这些深度学习框架被应用于计算机视觉.语音识别.自然语言处理与生物信息学等领 ...

  10. 深度学习框架之一:Theano | Lasagne简单教程

    北京 上海巡回站 | NVIDIA DLI深度学习培训 2018年1月26/1月12日 NVIDIA 深度学习学院 带你快速进入火热的DL领域 阅读全文                        ...

最新文章

  1. DRF工程搭建、环境安装与配置
  2. FEMS综述: 如何从微生物网络中的“毛线球”理出头绪(3万字长文带你系统学习网络)...
  3. mysql function select 赋值_MySql 进阶
  4. 遮掩java_Java炸弹:重载、重写、隐藏、遮蔽、遮掩(2)
  5. 你最想要的圣诞礼物是什么?
  6. go语言的书籍的淘宝调查
  7. linux内核head.S文件分析
  8. labuladong的算法小抄pdf_东哥手写正则通配符算法,结构清晰,包教包会!
  9. SAP HANA SQL获取当前日期
  10. 添加打印机,本地打印后台处理程序服务没有运行
  11. 【OpenCV C++】照片修改像素(尺寸大小)
  12. wordpress瀑布流图片主题PhotoBroad模板V2.0
  13. 飞冰,怎么配置打包时候去掉console.log配置
  14. Java Stream来写算法01——自幂数(水仙花数)
  15. 第1章第2节:PowerPoint的选项卡 [PowerPoint精美幻灯片实战教程]
  16. 进击的巨人 《兵王》6月28日启动新服【游戏资讯】
  17. SourceTree系列1:SourceTree连接github从无到有
  18. 基于 Python 爬虫+简单数据分析的课程设计(附PPT)
  19. hadoop安装-redhat
  20. javaweb出现HTTP500的可能问题的解决方案

热门文章

  1. Project2013快速使用入门教程(简单四步)
  2. 查看App应用签名工具
  3. 云服务器日志4625登录验证失败
  4. Ubuntu通过清华镜像源下载软件
  5. powerDesign逆向工程Mysql转Oracle
  6. 基于php考试系统设计与实现研究文毕业设计(论文)学生中期检查,毕业设计(论文)中期检查报告(学生填写)...
  7. mysql怎么没有中文手册_mysql 中文手册
  8. python+selenium+autoit实现自动百度识图
  9. NorthWind基本数据库添加问题
  10. 计算机enter代表什么意思,enter是什么意思