Caffe、TensorFlow、MXnet三个开源库对比+主流分类模型对比

2022-02-26库名称开发语言支持接口安装难度()文档样式示例支持模型上手容易

咖啡

c++/cuda

c++//

***

*

***

美国有线电视新闻网

**

MXNet

c++/cuda

/R/朱莉娅

**

***

**

CNN/RNN

*

c++/cuda/

c++/

*

**

*

CNN/RNN/…

***

1.基本数据结构库名数据结构名设计方法

咖啡

斑点

存储的数据可以看成一个有四个维度(n,k,h,w)的N维c数组。一个 blob 中有两个数据空间来存储前向和后向推导数据。

MXNet

提供cpu/gpu矩阵和向量计算,可自动并行化

相当于一个N维数组或列表,维数是可变的,数据类型一旦定义就不能改变

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

Caffe 最微妙的地方在于,一个 blob 保存了前向和后向数据。虽然就代码本身而言,前向数据因输入数据不同而变化,而后向推导因推导不同而变化。根据 SRP 原理,数据在一个类中发生变化有两个原因。合适的设计。但从逻辑层面来说,正向数据的变化导致了反向推导的差异。它们实际上是一起变化的,它们应该是一个整体。所以我很喜欢这个设计,虽然基本上其他框架都是把这两个数据分开的,但不知道要不要保留。

类似于numpy。MXNet的,它还支持在gpu或cpu上分配数据进行操作。但与numpy和caffe不同的是,在运行时,它可以自动将要执行的数据分发到多个gpu和cpus进行计算,从而完成高速并行。在调用者的眼里,代码可能只是单线程,数据只分配到一块内存,但后面执行的进程其实是并行的。MXnet 在分布式计算方面做得更好,可以充分利用多个 GPU 资源。将指令(加、减等)放入中间引擎,然后引擎评估哪些数据具有依赖性,哪些可以并行处理。一旦定义了数据,就可以通过将其绑定到网络来对其进行处理。

是的,它相当于一个 N 维数组或列表。与 MXNet 类似,以调用的形式显示。定义的数据类型是常量,但可以动态更改维度。用秩和来表示它的维数(例如秩为2可以看成一个矩阵,秩和是1可以看成一个向量)。是相当不错的类型。唯一特殊的是,在形成的网络中,它是唯一可以传递的类型,数组和列表之类的东西不能作为输入。

值得一提的是,cuda使用的数据结构是NV,意思是数据分配在gpu上,也就是把所有的变量都当作矩阵来对待。它只有两个维度。它是cuda实现的最早的深度学习框架。​​以上三个框架采用了多维变维的思想,在对矩阵做卷积运算时非常有效。

2.网络实现

Caffe 是一种典型的函数(过程)计算方法。它首先根据各个主要功能(可视化、损失函数、非线性激励、数据层)对功能进行分类,并为部分功能实现相应的父类,然后实现具体功能。变成子类,或者直接继承Layer类,从而形成表格。然后将不同的层组合成一个网。

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

MXNet 是符号计算和过程计算的混合体 [5]。它设计了主要的类别,并提供了许多符号计算接口。每个都定义了如何处理数据,但只定义了处理方法。这一步还不是真的。执行操作。需要注意的一点是,它是一个承载数据的符号,它定义了需要将什么样的数据传递给某个,并在后续操作中将数据绑定到它。下面的代码是一个使用示例,它实现了激励函数与之前定义的网络的连接,并给出了这个的名称和激励函数的类型,从而构建了网络。下图左侧是定义的集合。中间绑定数据后,

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

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

选择符号计算方法。其程序分为计算构建阶段和执行阶段。构建阶段是构建图。图是包含一系列符号操作和数据对象的流程图。与 mxnet 类似,它定义了如何执行计算(加法、减法、乘法、除法等),数据通过不同计算的顺序(又名流,数据在符号操作之间流动的感觉)。但是,暂时不是读取输入来计算得到输出,而是通过后续执行阶段开始的run来执行定义好的图。这个方法和mxnet很像,应该都是借鉴的思路。还引入了一种类型,它不像mxnet的(tf的类似于mxnet),而是一个单独的类型,其主要功能是存储网络权重参数,可以在运行过程中动态改变。tf将每个操作抽象成一个符号,可以读取0个或多个对象作为输入(输出),操作内容包括基本的数学运算,支持,(中间部分的运算。比如长度为10,可以在同时,计算前5个,中间2个,后3个的总和),对于image,pad,crop,等tf没有给出很好的图形解释或者像mxnet这样的例子(可能是因为我没有’找不到…),并根据自己的理解画了一部分流程图。有点不解的是为什么要设计它。tf给出的源码中,设置了输入数据和权重,并没有直接定义每一层的输出。根据 tf,只有类型可以在网络中传输。输出的类型应该是,但是由于输入和权重已经改变,输出也应该改变。在这种情况下,为什么不只是设计一个,还要动态改变它。

图 3 图表

在设计上,它比其他两个更像是一个通用的机器学习框架,而不仅仅是针对 cnn 或 rnn,但就目前的性能而言,tf 比许多开源框架要慢一些 [6]。

3.分布式训练

Caffe并没有给出分布式版本,MXNet提供了多机分布,所以前两个只控制如何使用多个gpus。Caffe表示调用两个gpu0和1,直接在执行指令后面加上-gpu 0,1,只实现数据并行,即在不同的gpu上执行同一个网络,不同的数据,caffe会实例化,net 每个处理。然后您可以自己定义要对哪个 gpu 执行操作。用tf.(‘/gpu:2′)调用,表示接下来的操作要在gpu2上处理,也是数据并行。MXNet 在执行脚本时通过指定多机节点的数量来决定运行在多台主机上,这也是数据并行。MXNet’

要使用它,首先要创建一个 kv 空间,用于在不同 GPU 和不同主机之间共享数据。最基本的操作是推拉。push是将数据放入这个空间,pull是从这个空间获取数据。这个空间存储在key-value([int, ])中,push/pull时指定哪个key。下面的代码通过key3将分配在kv空间中不同设备上的b[i]累加起来输出到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已经可以解决显存不足的问题,而且模型并行会有额外的通信开销,所以开源框架使用数据并行来提高并行度。

4.总结

以上对三个框架不同方面的分析比较可以看出。可以看出与 MXNet 有一些相似之处。他们都想做一个更通用的深度学习框架,而且似乎也会用到符号计算[5]。该框架将更加通用和高效。我最喜欢的是caffe,我还写了一个卷积网络模仿它和cuda-的结构。如果你想提高自己的编程能力,可以看看这两个框架的源码。MXNet给人的感觉是很用心,更注重效率,文档也很详细。它不仅上手容易,而且使用起来也非常灵活。功能非常强大,可以搭建的网络比caffe还丰富,只限于CNN。总之,每个框架都有自己的优点,如何选择也只能看个人喜好了。不过,这个大杀手的出现,却吸引了最多的目光。虽然单机性能不够好,但看一长串的开发者名单,只能说大部分牛人都是任性的。

参考:

[1]

[2]

[3]

[4] [caffe]的项目架构及源码分析

[5] 如何评估和其他深度学习系统

[6]

[7]Blobs, , and Nets: 一个 Caffe 模型

[8]

分类:

技术要点:

相关文章:

© 版权声明
THE END
喜欢就支持一下吧
点赞5 分享
评论 抢沙发
头像
欢迎您留下宝贵的见解!
提交
头像

昵称

取消
昵称表情代码图片