阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

Caffe、TensorFlow、MXnet三个开源库对比

492次阅读
没有评论

共计 4841 个字符,预计需要花费 13 分钟才能阅读完成。

最近 Google 开源了他们内部使用的深度学习框架 TensorFlow[1],结合之前开源的 MXNet[2]和 Caffe[3],对三个开源库做了一些讨论,其中只有 Caffe 比较仔细的看过源代码,其他的两个库仅阅读官方文档和一些研究者的评论博客有感,本文首先对三个库有个整体的比较,再针对一些三者设计的不同数据结构、计算方式、gpu 的选择方式等方面做了比较详细的讨论。表格 1 是三者的一些基本情况的记录和比较。其中示例指的是官方给出的 example 是否易读易理解,因为 TensorFlow 直接安装 Python 包,所以一开始没有去下源代码,从文档中找 example 不如另外两个下源码直接。实际上 TensorFlow 更加像一套独立的 python 接口,它不止能够完成 CNN/RNN 的功能,还见到过有人用它做 Kmeans 聚类。这个表主观因素比较明显,仅供参考。


(2016 年 6 月 27 日更新)大半年的时间过去了,再回过头来看这篇文章,感觉有点伤感,Caffe 已经很久没有更新过了,曾经的霸主地位果然还是被 tensorflow 给终结了,特别是从 0.8 版本开始,tensorflow 开始支持分布式,一声叹息…MXNet 还是那么拼命,支持的语言新增了四种,Matlab/Javascripts/C++/Scala,文档也变的更漂亮了,还推出了手机上图片识别的 demo[8]。


(原文如下)

库名称 开发语言 支持接口 安装难度(Ubuntu) 文档风格 示例 支持模型 上手难易
Caffe c++/cuda c++/python/matlab * * * CNN **
MXNet c++/cuda python/R/Julia ** * ** CNN/RNN *
TensorFlow c++/cuda/python c++/python * ** * CNN/RNN/… *
  • 安装难度: (简单) –> **(复杂)
  • 文档风格: (一般) –> **(好看、全面)
  • 示例: (给的少) –> **(给的多、全)
  • 上手难易: (易) –> **(难)

1. 基本数据结构

库名称 数据结构名称 设计方式
Caffe Blob 存储的数据可以看成 N 维的 c 数组,有 (n,k,h,w) 四个维数,一个 blob 里面有两块数据空间保存前向和后向求导数据
MXNet NDArray 提供 cpu/gpu 的矩阵和矢量计算,能够自动并行
TensorFlow tensor 相当于 N 维的 array 或者 list,维数可变,数据类型一旦定义不能改变

caffe 的数据存储类 blob,当把数据可以看成是一个 N 维的 c 数组,它们的存储空间连续。例如存储图片是 4 维 (num, channel, height, width), 变量(n,k,h,w) 在数组中存储位置为((n*K+k)*H+h)*W+w。blob 有以下三个特征[4]:

  • 两块数据,一个是原始 data,一个是求导值 diff
  • 两种内存分配方式,一种是分配在 cpu 上,一种是分配在 gpu 上,通过前缀 cpu、gpu 来区分
  • 两种访问方式,一种是不能改变数据,一种能改变数据

Caffe 最让我觉得精妙的地方在于一个 blob 保存前向和后向的数据。虽然就代码本身而言,前向数据是因为输入数据不同而改变,后向求导是因为求导不同而改变,根据 SRP 原则,在一个类里面因为两个原因而改变了数据这种是不合适的设计。但是从逻辑层面,前向数据的改变引起了反向求导的不同,它们实际上是一起在改变,本身应该是一个整体。所以我很喜欢这个设计,虽然基本上其他框架中都是将两个数据给分离出来,caffe2 也不知是否保留。

MXNet 的 NDArray 类似 numpy.ndarray,也支持把数据分配在 gpu 或者 cpu 上进行运算。但是与 numpy 和 caffe 不同的是,当在操作 NDArray,它能自动的将需要执行的数据分配到多台 gpu 和 cpu 上进行计算,从而完成高速并行。在调用者的眼中代码可能只是一个单线程的,数据只是分配到了一块内存中,但是背后执行的过程实际上是并行的。将指令 (加减等) 放入中间引擎,然后引擎来评估哪些数据有依赖关系,哪些能并行处理。定义好数据之后将它绑定到网络中就能处理它了。

TensorFlow 的 tensor,它相当于 N 维的 array 或者 list,与 MXNet 类似,都是采用了以 python 调用的形式展现出来。某个定义好的 tensor 的数据类型是不变的,但是维数可以动态改变。用 tensor rank 和 TensorShape 来表示它的维数(例如 rank 为 2 可以看成矩阵,rank 为 1 可以看成向量)。tensor 是个比较中规中矩的类型。唯一特别的地方在于在 TensorFlow 构成的网络中,tensor 是唯一能够传递的类型,而类似于 array、list 这种不能当成输入。

值得一提的是 cuda-convnet 采用的数据结构是 NVMatrix,NV 表示数据分配在 gpu 上,即将所有变量都当成矩阵来处理,它只有两维,它算是最早用 cuda 实现的深度学习框架,而上面三种框架都采用了多维可变维的思想,这种可变维在用矩阵做卷积运算的时候是很有效的。

2. 网络实现方式

Caffe 是典型的功能(过程)计算方式,它首先按照每一个大功能(可视化、损失函数、非线性激励、数据层)将功能分类并针对部分功能实现相应的父类,再将具体的功能实现成子类,或者直接继承 Layer 类,从而形成了 XXXLayer 的形式。然后将不同的 layer 组合起来就成了 net。

Caffe、TensorFlow、MXnet 三个开源库对比

图 1 caffe 的网络结构(来源[7])

MXNet 是符号计算和过程计算混合[5],它设计了 Symbol 大类,提供了很多符号运算的接口,每个 symbol 定义了对数据进行怎样的处理,symbol 只是定义处理的方式,这步还并未真正的执行运算。其中一个需要注意的是 symbol 里面有 Variable,它作为承载数据的符号,定义了需要传递什么样的数据给某个 Variable,并在后续的操作中将数据绑定到 Variable 上。下面的代码是一个使用示例,它实现了将激励函数连接到前面定义好的 net 后面,并给出了这一个 symbol 的名字和激励函数类型,从而构造出 net。下图左边部分是定义 symbol 的合集,中间将数据绑定到 Variable 上之后变成了右边真正的执行流程图。

net = mx.symbol.Activation(data=net, name='relu1', act_type="relu")

Caffe、TensorFlow、MXnet 三个开源库对比

图 2 MXNet 的网络结构(图来源[2])

TensorFlow 选择的是符号计算方式,它的程序分为计算构造阶段和执行阶段,构造阶段是构造出 computation graph,computation graph 就是包含一系列符号操作 Operation 和 Tensor 数据对象的流程图,跟 mxnet 的 symbol 类似,它定义好了如何进行计算(加减乘除等)、数据通过不同计算的顺序(也就是 flow,数据在符号操作之间流动的感觉)。但是暂时并不读取输入来计算获得输出,而是由后面的执行阶段启动 session 的 run 来执行已经定义好的 graph。这样的方式跟 mxnet 很相似,应该都是借鉴了 theano 的想法。其中 TensorFlow 还引入了 Variable 类型,它不像 mxnet 的 Variable 属于 symbol(tf 的 operation 类似 mxnet 的 symbol),而是一个单独的类型,主要作用是存储网络权重参数,从而能够在运行过程中动态改变。tf 将每一个操作抽象成了一个符号 Operation,它能够读取 0 个或者多个 Tensor 对象作为输入(输出),操作内容包括基本的数学运算、支持 reduce、segment(对 tensor 中部分进行运算。例如 tensor 长度为 10,可以同时计算前 5 个,中间 2 个,后面三个的和)、对 image 的 resize、pad、crop、filpping、transposing 等。tf 没有像 mxnet 那样给出很好的图形解释或者实例(可能因为我没找到。。),按照自己的理解画了一部分流程图。有点疑惑的是,为什么要设计 Variable,tf 给出的一个 alexnet 的 example 源码中,输入数据和权重都设置成了 Variable,每一层的输出并未直接定义,按照 tf 的说法,只有 tensor 类型能够在网络中传递,输出的类型应该是 tensor,但是由于输入和权重改变了,输出应该也在随着改变,既然如此,为何不只设计一个 tensor,让 tensor 也能动态改变。

Caffe、TensorFlow、MXnet 三个开源库对比

图 3 TensorFlow 的 computation graph

就设计而言,TensorFlow 相对于其他两个更像是一种通用的机器学习框架,而不是只针对 cnn 或 rnn,但就现在的性能而言,tf 的速度比很多开源框架都要差一点[6]。

3. 分布式训练

Caffe 和 TensorFlow 没有给出分布式的版本,MXNet 提供了多机分布式,因而前两者只有如何控制使���多 gpu。Caffe 通过直接在执行指令后面加上 -gpu 0,1 来表示调用两个 gpu0 和 1,只实现了数据并行,也就是在不同的 gpu 上执行相同网络和不同数据,caffe 会实例化多个 solver 和 net 让每次处理的 batch_size 加倍。TensorFlow 则能够自己定义某个操作执行在哪个 gpu 上,通过调用 with tf.device(‘/gpu:2’) 表示接下来的操作要在 gpu2 上处理,它也是数据并行。MXNet 通过执行脚本时指定多机节点个数来确定在几台主机上运行,也是数据并行。MXNet 的多 gpu 分配和它们之间数据同步是通过 MXNet 的数据同步控制 KVStore 来完成的。

KVStore 的使用首先要创建一个 kv 空间,这个空间用来在不同 gpu 不同主机间分享数据,最基本的操作是 push 和 pull,push 是把数据放入这个空间,pull 是从这个空间取数据。这个空间内保存的是 key-value([int, NDArray]),在 push/pull 的时候来指定到哪个 key。下面的代码将不同的设备上分配的 b[i]通过 key3 在 kv 空间累加再输出到 a,从而完成了对多 gpu 的处理。这个是个非常棒的设计,提供了很大的自由度,并且为开发者减少了控制底层数据传输的麻烦。

gpus = [mx.gpu(i) for i in range(4)]    
b = [mx.nd.ones(shape, gpu) for gpu in gpus]
kv.push(3, b)
kv.pull(3, out = a)

之前有看过一篇论文,如何将卷积网络放在多 gpu 上训练,论文中有两种方法,一种是常用的数据并行,另一种是模型并行。模型并行指的是将一个完整的网络切分成不同块放在不同 gpu 上执行,每个 gpu 可能只处理某一张图的四分之一。采用模型并行很大程度上是因为显存不够放不下整个网络的数据,而现在 gpu 的功能性能提高,一个 gpu 已经能够很好的解决显存不够的问题,再加上模型并行会有额外的通信开销,因此开源框架采用了数据并行,用来提高并行度。

4. 小结

上面针对三个框架的不同方面进行了一些分析与比较,可以看出 TensorFlow 和 MXNet 有一些相似的地方,都是想做成更加通用的深度学习框架,貌似 caffe2 也会采用符号计算[5],说明以后的框架会更加的偏向通用性和高效,个人最喜欢的是 caffe,也仿造它和 cuda-convnet 的结构写过卷积网络,如果是想提高编程能力可以多看看这两个框架的源码。而 MXNet 给人的感觉是非常用心,更加注重高效,文档也非常的详细,不仅上手很容易,运用也非常的灵活。TensorFlow 则是功能很齐全,能够搭建的网络更丰富而不是像 caffe 仅仅局限在 CNN。总之框架都是各有千秋,如何选择也仅凭个人的喜好,然而 google 这个大杀器一出现引起的关注度还是最大的,虽然现在单机性能还不够好,但是看着长长的开发人员名单,也只能说大牛多就是任性。

本文永久更新链接地址:http://www.linuxidc.com/Linux/2016-07/133222.htm

正文完
星哥玩云-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-01-21发表,共计4841字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中

星哥玩云

星哥玩云
星哥玩云
分享互联网知识
用户数
4
文章数
19350
评论数
4
阅读量
7962652
文章搜索
热门文章
星哥带你玩飞牛NAS-6:抖音视频同步工具,视频下载自动下载保存

星哥带你玩飞牛NAS-6:抖音视频同步工具,视频下载自动下载保存

星哥带你玩飞牛 NAS-6:抖音视频同步工具,视频下载自动下载保存 前言 各位玩 NAS 的朋友好,我是星哥!...
星哥带你玩飞牛NAS-3:安装飞牛NAS后的很有必要的操作

星哥带你玩飞牛NAS-3:安装飞牛NAS后的很有必要的操作

星哥带你玩飞牛 NAS-3:安装飞牛 NAS 后的很有必要的操作 前言 如果你已经有了飞牛 NAS 系统,之前...
我把用了20年的360安全卫士卸载了

我把用了20年的360安全卫士卸载了

我把用了 20 年的 360 安全卫士卸载了 是的,正如标题你看到的。 原因 偷摸安装自家的软件 莫名其妙安装...
再见zabbix!轻量级自建服务器监控神器在Linux 的完整部署指南

再见zabbix!轻量级自建服务器监控神器在Linux 的完整部署指南

再见 zabbix!轻量级自建服务器监控神器在 Linux 的完整部署指南 在日常运维中,服务器监控是绕不开的...
飞牛NAS中安装Navidrome音乐文件中文标签乱码问题解决、安装FntermX终端

飞牛NAS中安装Navidrome音乐文件中文标签乱码问题解决、安装FntermX终端

飞牛 NAS 中安装 Navidrome 音乐文件中文标签乱码问题解决、安装 FntermX 终端 问题背景 ...
阿里云CDN
阿里云CDN-提高用户访问的响应速度和成功率
随机文章
颠覆 AI 开发效率!开源工具一站式管控 30+大模型ApiKey,秘钥付费+负载均衡全搞定

颠覆 AI 开发效率!开源工具一站式管控 30+大模型ApiKey,秘钥付费+负载均衡全搞定

  颠覆 AI 开发效率!开源工具一站式管控 30+ 大模型 ApiKey,秘钥付费 + 负载均衡全...
把小米云笔记搬回家:飞牛 NAS 一键部署,小米云笔记自动同步到本地

把小米云笔记搬回家:飞牛 NAS 一键部署,小米云笔记自动同步到本地

把小米云笔记搬回家:飞牛 NAS 一键部署,小米云笔记自动同步到本地 大家好,我是星哥,今天教大家在飞牛 NA...
星哥带你玩飞牛NAS硬件03:五盘位+N5105+双网口的成品NAS值得入手吗

星哥带你玩飞牛NAS硬件03:五盘位+N5105+双网口的成品NAS值得入手吗

星哥带你玩飞牛 NAS 硬件 03:五盘位 +N5105+ 双网口的成品 NAS 值得入手吗 前言 大家好,我...
星哥带你玩飞牛NAS-5:飞牛NAS中的Docker功能介绍

星哥带你玩飞牛NAS-5:飞牛NAS中的Docker功能介绍

星哥带你玩飞牛 NAS-5:飞牛 NAS 中的 Docker 功能介绍 大家好,我是星哥,今天给大家带来如何在...
仅2MB大小!开源硬件监控工具:Win11 无缝适配,CPU、GPU、网速全维度掌控

仅2MB大小!开源硬件监控工具:Win11 无缝适配,CPU、GPU、网速全维度掌控

还在忍受动辄数百兆的“全家桶”监控软件?后台偷占资源、界面杂乱冗余,想查个 CPU 温度都要层层点选? 今天给...

免费图片视频管理工具让灵感库告别混乱

一言一句话
-「
手气不错
星哥带你玩飞牛NAS-16:飞牛云NAS换桌面,fndesk图标管理神器上线!

星哥带你玩飞牛NAS-16:飞牛云NAS换桌面,fndesk图标管理神器上线!

  星哥带你玩飞牛 NAS-16:飞牛云 NAS 换桌面,fndesk 图标管理神器上线! 引言 哈...
三大开源投屏神器横评:QtScrcpy、scrcpy、escrcpy 谁才是跨平台控制 Android 的最优解?

三大开源投屏神器横评:QtScrcpy、scrcpy、escrcpy 谁才是跨平台控制 Android 的最优解?

  三大开源投屏神器横评:QtScrcpy、scrcpy、escrcpy 谁才是跨平台控制 Andr...
让微信公众号成为 AI 智能体:从内容沉淀到智能问答的一次升级

让微信公众号成为 AI 智能体:从内容沉淀到智能问答的一次升级

让微信公众号成为 AI 智能体:从内容沉淀到智能问答的一次升级 大家好,我是星哥,之前写了一篇文章 自己手撸一...
星哥带你玩飞牛NAS硬件 01:捡垃圾的最爱双盘,暴风二期矿渣为何成不老神话?

星哥带你玩飞牛NAS硬件 01:捡垃圾的最爱双盘,暴风二期矿渣为何成不老神话?

星哥带你玩飞牛 NAS 硬件 01:捡垃圾的最爱双盘,暴风二期矿渣为何成不老神话? 前言 在选择 NAS 用预...
恶意团伙利用 PHP-FPM 未授权访问漏洞发起大规模攻击

恶意团伙利用 PHP-FPM 未授权访问漏洞发起大规模攻击

恶意团伙利用 PHP-FPM 未授权访问漏洞发起大规模攻击 PHP-FPM(FastCGl Process M...