日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 人工智能 > Caffe >内容正文

Caffe

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

發(fā)布時(shí)間:2025/7/25 Caffe 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【开源】Caffe、TensorFlow、MXnet三个开源库对比 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

from:http://www.wtoutiao.com/p/1cbxddO.html

最近Google開源了他們內(nèi)部使用的深度學(xué)習(xí)框架TensorFlow[1],結(jié)合之前開源的MXNet[2]和Caffe[3],對(duì)三個(gè)開源庫做了一些討論,其中只有Caffe比較仔細(xì)的看過源代碼,其他的兩個(gè)庫僅閱讀官方文檔和一些研究者的評(píng)論博客有感,本文首先對(duì)三個(gè)庫有個(gè)整體的比較,再針對(duì)一些三者設(shè)計(jì)的不同數(shù)據(jù)結(jié)構(gòu)、計(jì)算方式、gpu的選擇方式等方面做了比較詳細(xì)的討論。表格1是三者的一些基本情況的記錄和比較。其中示例指的是官方給出的example是否易讀易理解,因?yàn)門ensorFlow直接安裝python包,所以一開始沒有去下源代碼,從文檔中找example不如另外兩個(gè)下源碼直接。實(shí)際上TensorFlow更加像一套獨(dú)立的python接口,它不止能夠完成CNN/RNN的功能,還見到過有人用它做Kmeans聚類。這個(gè)表主觀因素比較明顯,僅供參考。??????????????????????????

庫名稱 開發(fā)語言支持接口安裝難度(ubuntu)文檔風(fēng)格示例支持模型上手難易

Caffe

c++/cuda

c++/python/matlab

***

*

***

CNN

**

MXNet

c++/cuda

python/R/Julia

**

***

**

CNN/RNN

*

TensorFlow

c++/cuda/python

c++/python

*

**

*

CNN/RNN/…

***

????????1.基本數(shù)據(jù)結(jié)構(gòu)

庫名稱數(shù)據(jù)結(jié)構(gòu)名稱設(shè)計(jì)方式

Caffe

Blob

存儲(chǔ)的數(shù)據(jù)可以看成N維的c數(shù)組,有(n,k,h,w)四個(gè)維數(shù),一個(gè)blob里面有兩塊數(shù)據(jù)空間保存前向和后向求導(dǎo)數(shù)據(jù)

MXNet

NDArray

提供cpu/gpu的矩陣和矢量計(jì)算,能夠自動(dòng)并行

TensorFlow

tensor

相當(dāng)于N維的array或者list,維數(shù)可變,數(shù)據(jù)類型一旦定義不能改變

????????caffe的數(shù)據(jù)存儲(chǔ)類blob,當(dāng)把數(shù)據(jù)可以看成是一個(gè)N維的c數(shù)組,它們的存儲(chǔ)空間連續(xù)。例如存儲(chǔ)圖片是4維(num, channel, height, width),變量(n,k,h,w)在數(shù)組中存儲(chǔ)位置為((n*K+k)*H+h)*W+w。blob有以下三個(gè)特征[4]:

  • 兩塊數(shù)據(jù),一個(gè)是原始data,一個(gè)是求導(dǎo)值diff

  • 兩種內(nèi)存分配方式,一種是分配在cpu上,一種是分配在gpu上,通過前綴cpu、gpu來區(qū)分

  • 兩種訪問方式,一種是不能改變數(shù)據(jù),一種能改變數(shù)據(jù)

????????Caffe最讓我覺得精妙的地方在于一個(gè)blob保存前向和后向的數(shù)據(jù)。雖然就代碼本身而言,前向數(shù)據(jù)是因?yàn)檩斎霐?shù)據(jù)不同而改變,后向求導(dǎo)是因?yàn)榍髮?dǎo)不同而改變,根據(jù)SRP原則,在一個(gè)類里面因?yàn)閮蓚€(gè)原因而改變了數(shù)據(jù)這種是不合適的設(shè)計(jì)。但是從邏輯層面,前向數(shù)據(jù)的改變引起了反向求導(dǎo)的不同,它們實(shí)際上是一起在改變,本身應(yīng)該是一個(gè)整體。所以我很喜歡這個(gè)設(shè)計(jì),雖然基本上其他框架中都是將兩個(gè)數(shù)據(jù)給分離出來,caffe2也不知是否保留。

????????MXNet的NDArray類似numpy.ndarray,也支持把數(shù)據(jù)分配在gpu或者cpu上進(jìn)行運(yùn)算。但是與numpy和caffe不同的是,當(dāng)在操作NDArray,它能自動(dòng)的將需要執(zhí)行的數(shù)據(jù)分配到多臺(tái)gpu和cpu上進(jìn)行計(jì)算,從而完成高速并行。在調(diào)用者的眼中代碼可能只是一個(gè)單線程的,數(shù)據(jù)只是分配到了一塊內(nèi)存中,但是背后執(zhí)行的過程實(shí)際上是并行的。將指令(加減等)放入中間引擎,然后引擎來評(píng)估哪些數(shù)據(jù)有依賴關(guān)系,哪些能并行處理。定義好數(shù)據(jù)之后將它綁定到網(wǎng)絡(luò)中就能處理它了。

????????TensorFlow的tensor,它相當(dāng)于N維的array或者list,與MXNet類似,都是采用了以python調(diào)用的形式展現(xiàn)出來。某個(gè)定義好的tensor的數(shù)據(jù)類型是不變的,但是維數(shù)可以動(dòng)態(tài)改變。用tensor rank和TensorShape來表示它的維數(shù)(例如rank為2可以看成矩陣,rank為1可以看成向量)。tensor是個(gè)比較中規(guī)中矩的類型。唯一特別的地方在于在TensorFlow構(gòu)成的網(wǎng)絡(luò)中,tensor是唯一能夠傳遞的類型,而類似于array、list這種不能當(dāng)成輸入。

????????值得一提的是cuda-convnet采用的數(shù)據(jù)結(jié)構(gòu)是NVMatrix,NV表示數(shù)據(jù)分配在gpu上,即將所有變量都當(dāng)成矩陣來處理,它只有兩維,它算是最早用cuda實(shí)現(xiàn)的深度學(xué)習(xí)框架,而上面三種框架都采用了多維可變維的思想,這種可變維在用矩陣做卷積運(yùn)算的時(shí)候是很有效的。

????????2.網(wǎng)絡(luò)實(shí)現(xiàn)方式

????????Caffe是典型的功能(過程)計(jì)算方式,它首先按照每一個(gè)大功能(可視化、損失函數(shù)、非線性激勵(lì)、數(shù)據(jù)層)將功能分類并針對(duì)部分功能實(shí)現(xiàn)相應(yīng)的父類,再將具體的功能實(shí)現(xiàn)成子類,或者直接繼承Layer類,從而形成了XXXLayer的形式。然后將不同的layer組合起來就成了net。

????????

????????圖1 caffe的網(wǎng)絡(luò)結(jié)構(gòu)

????????MXNet是符號(hào)計(jì)算和過程計(jì)算混合[5],它設(shè)計(jì)了Symbol大類,提供了很多符號(hào)運(yùn)算的接口,每個(gè)symbol定義了對(duì)數(shù)據(jù)進(jìn)行怎樣的處理,symbol只是定義處理的方式,這步還并未真正的執(zhí)行運(yùn)算。其中一個(gè)需要注意的是symbol里面有Variable,它作為承載數(shù)據(jù)的符號(hào),定義了需要傳遞什么樣的數(shù)據(jù)給某個(gè)Variable,并在后續(xù)的操作中將數(shù)據(jù)綁定到Variable上。下面的代碼是一個(gè)使用示例,它實(shí)現(xiàn)了將激勵(lì)函數(shù)連接到前面定義好的net后面,并給出了這一個(gè)symbol的名字和激勵(lì)函數(shù)類型,從而構(gòu)造出net。下圖左邊部分是定義symbol的合集,中間將數(shù)據(jù)綁定到Variable上之后變成了右邊真正的執(zhí)行流程圖。

????????

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

????????

????????圖2 MXNet的網(wǎng)絡(luò)結(jié)構(gòu)

????????TensorFlow選擇的是符號(hào)計(jì)算方式,它的程序分為計(jì)算構(gòu)造階段和執(zhí)行階段,構(gòu)造階段是構(gòu)造出computation graph,computation graph就是包含一系列符號(hào)操作Operation和Tensor數(shù)據(jù)對(duì)象的流程圖,跟mxnet的symbol類似,它定義好了如何進(jìn)行計(jì)算(加減乘除等)、數(shù)據(jù)通過不同計(jì)算的順序(也就是flow,數(shù)據(jù)在符號(hào)操作之間流動(dòng)的感覺)。但是暫時(shí)并不讀取輸入來計(jì)算獲得輸出,而是由后面的執(zhí)行階段啟動(dòng)session的run來執(zhí)行已經(jīng)定義好的graph。這樣的方式跟mxnet很相似,應(yīng)該都是借鑒了theano的想法。其中TensorFlow還引入了Variable類型,它不像mxnet的Variable屬于symbol(tf的operation類似mxnet的symbol),而是一個(gè)單獨(dú)的類型,主要作用是存儲(chǔ)網(wǎng)絡(luò)權(quán)重參數(shù),從而能夠在運(yùn)行過程中動(dòng)態(tài)改變。tf將每一個(gè)操作抽象成了一個(gè)符號(hào)Operation,它能夠讀取0個(gè)或者多個(gè)Tensor對(duì)象作為輸入(輸出),操作內(nèi)容包括基本的數(shù)學(xué)運(yùn)算、支持reduce、segment(對(duì)tensor中部分進(jìn)行運(yùn)算。例如tensor長度為10,可以同時(shí)計(jì)算前5個(gè),中間2個(gè),后面三個(gè)的和)、對(duì)image的resize、pad、crop、filpping、transposing等。tf沒有像mxnet那樣給出很好的圖形解釋或者實(shí)例(可能因?yàn)槲覜]找到。。),按照自己的理解畫了一部分流程圖。有點(diǎn)疑惑的是,為什么要設(shè)計(jì)Variable,tf給出的一個(gè)alexnet的example源碼中,輸入數(shù)據(jù)和權(quán)重都設(shè)置成了Variable,每一層的輸出并未直接定義,按照tf的說法,只有tensor類型能夠在網(wǎng)絡(luò)中傳遞,輸出的類型應(yīng)該是tensor,但是由于輸入和權(quán)重改變了,輸出應(yīng)該也在隨著改變,既然如此,為何不只設(shè)計(jì)一個(gè)tensor,讓tensor也能動(dòng)態(tài)改變。

????????

????????圖3 TensorFlow的computation graph

????????就設(shè)計(jì)而言,TensorFlow相對(duì)于其他兩個(gè)更像是一種通用的機(jī)器學(xué)習(xí)框架,而不是只針對(duì)cnn或rnn,但就現(xiàn)在的性能而言,tf的速度比很多開源框架都要差一點(diǎn)[6]。

????????3.分布式訓(xùn)練

????????Caffe和TensorFlow沒有給出分布式的版本,MXNet提供了多機(jī)分布式,因而前兩者只有如何控制使用多gpu。Caffe通過直接在執(zhí)行指令后面加上-gpu 0,1來表示調(diào)用兩個(gè)gpu0和1,只實(shí)現(xiàn)了數(shù)據(jù)并行,也就是在不同的gpu上執(zhí)行相同網(wǎng)絡(luò)和不同數(shù)據(jù),caffe會(huì)實(shí)例化多個(gè)solver和net讓每次處理的batch_size加倍。TensorFlow則能夠自己定義某個(gè)操作執(zhí)行在哪個(gè)gpu上,通過調(diào)用with tf.device(‘/gpu:2’)表示接下來的操作要在gpu2上處理,它也是數(shù)據(jù)并行。MXNet通過執(zhí)行腳本時(shí)指定多機(jī)節(jié)點(diǎn)個(gè)數(shù)來確定在幾臺(tái)主機(jī)上運(yùn)行,也是數(shù)據(jù)并行。MXNet的多gpu分配和它們之間數(shù)據(jù)同步是通過MXNet的數(shù)據(jù)同步控制KVStore來完成的。

????????KVStore的使用首先要?jiǎng)?chuàng)建一個(gè)kv空間,這個(gè)空間用來在不同gpu不同主機(jī)間分享數(shù)據(jù),最基本的操作是push和pull,push是把數(shù)據(jù)放入這個(gè)空間,pull是從這個(gè)空間取數(shù)據(jù)。這個(gè)空間內(nèi)保存的是key-value([int, NDArray]),在push/pull的時(shí)候來指定到哪個(gè)key。下面的代碼將不同的設(shè)備上分配的b[i]通過key3在kv空間累加再輸出到a,從而完成了對(duì)多gpu的處理。這個(gè)是個(gè)非常棒的設(shè)計(jì),提供了很大的自由度,并且為開發(fā)者減少了控制底層數(shù)據(jù)傳輸?shù)穆闊?/p>

????????

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)

????????之前有看過一篇論文,如何將卷積網(wǎng)絡(luò)放在多gpu上訓(xùn)練,論文中有兩種方法,一種是常用的數(shù)據(jù)并行,另一種是模型并行。模型并行指的是將一個(gè)完整的網(wǎng)絡(luò)切分成不同塊放在不同gpu上執(zhí)行,每個(gè)gpu可能只處理某一張圖的四分之一。采用模型并行很大程度上是因?yàn)轱@存不夠放不下整個(gè)網(wǎng)絡(luò)的數(shù)據(jù),而現(xiàn)在gpu的功能性能提高,一個(gè)gpu已經(jīng)能夠很好的解決顯存不夠的問題,再加上模型并行會(huì)有額外的通信開銷,因此開源框架采用了數(shù)據(jù)并行,用來提高并行度。

????????4.小結(jié)

????????上面針對(duì)三個(gè)框架的不同方面進(jìn)行了一些分析與比較,可以看出TensorFlow和MXNet有一些相似的地方,都是想做成更加通用的深度學(xué)習(xí)框架,貌似caffe2也會(huì)采用符號(hào)計(jì)算[5],說明以后的框架會(huì)更加的偏向通用性和高效,個(gè)人最喜歡的是caffe,也仿造它和cuda-convnet的結(jié)構(gòu)寫過卷積網(wǎng)絡(luò),如果是想提高編程能力可以多看看這兩個(gè)框架的源碼。而MXNet給人的感覺是非常用心,更加注重高效,文檔也非常的詳細(xì),不僅上手很容易,運(yùn)用也非常的靈活。TensorFlow則是功能很齊全,能夠搭建的網(wǎng)絡(luò)更豐富而不是像caffe僅僅局限在CNN。總之框架都是各有千秋,如何選擇也僅憑個(gè)人的喜好,然而google這個(gè)大殺器一出現(xiàn)引起的關(guān)注度還是最大的,雖然現(xiàn)在單機(jī)性能還不夠好,但是看著長長的開發(fā)人員名單,也只能說大牛多就是任性。

????????參考:

????????[1]http://tensorflow.org/

????????[2]http://mxnet.readthedocs.org/en/latest/index.html

????????[3]http://caffe.berkeleyvision.org/

????????[4][caffe]的項(xiàng)目架構(gòu)和源碼解析

????????[5]如何評(píng)價(jià)Tensorflow和其它深度學(xué)習(xí)系統(tǒng)

????????[6]Imagenet Winners Benchmarking


總結(jié)

以上是生活随笔為你收集整理的【开源】Caffe、TensorFlow、MXnet三个开源库对比的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。