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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人工智能 > pytorch >内容正文

pytorch

深度学习caffe的代码怎么读?

發(fā)布時間:2025/3/21 pytorch 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 深度学习caffe的代码怎么读? 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
知乎用戶?,Caffe / Torch7 / CNN 知乎用戶、任逸風、陳文?等人贊同 我是從Torch7轉(zhuǎn)移到Caffe的人,僅供參考,當你閱讀前你應該具備一些有關DL的基礎知識,本文集中寫Caffe代碼結構而非介紹DL知識。
我是去年底開始看Caffe代碼的,看代碼的時間加在一起也不到一個月,也算半個新手,我的回答是從新手角度作一個入門階段的經(jīng)驗分享。

本文只涉及Caffe結構的相關問題,不涉及具體實現(xiàn)技巧等細節(jié)。

==============================================================

1. 初識Caffe
1.1. Caffe相對與其他DL框架的優(yōu)點和缺點:
優(yōu)點:
  • 速度快。Google Protocol Buffer數(shù)據(jù)標準為Caffe提升了效率。
  • 學術論文采用此模型較多。不確定是不是最多,但接觸到的不少論文都與Caffe有關(R-CNN,DSN,最近還有人用Caffe實現(xiàn)LSTM)
缺點:
  • 曾更新過重要函數(shù)接口。有人反映,偶爾會出現(xiàn)接口變換的情況,自己很久前寫的代碼可能過了一段時間就不能和新版本很好地兼容了。(現(xiàn)在更新速度放緩,接口逐步趨于穩(wěn)定,感謝 評論區(qū)王峰的建議)
  • 對于某些研究方向來說的人并不適合。這個需要對Caffe的結構有一定了解,(后面提到)。
1.2. Caffe代碼層次。
回答里面有人說熟悉Blob,Layer,Net,Solver這樣的幾大類,我比較贊同。我基本是從這個順序開始學習的,這四個類復雜性從低到高,貫穿了整個Caffe。把他們分為三個層次介紹。
  • Blob:是基礎的數(shù)據(jù)結構,是用來保存學習到的參數(shù)以及網(wǎng)絡傳輸過程中產(chǎn)生數(shù)據(jù)的類。
  • Layer:是網(wǎng)絡的基本單元,由此派生出了各種層類。修改這部分的人主要是研究特征表達方向的。
  • Net:是網(wǎng)絡的搭建,將Layer所派生出層類組合成網(wǎng)絡。Solver:是Net的求解,修改這部分人主要會是研究DL求解方向的。

==============================================================

2. Caffe進階
2.1. Blob:

Caffe支持CUDA,在數(shù)據(jù)級別上也做了一些優(yōu)化,這部分最重要的是知道它主要是對protocol buffer所定義的數(shù)據(jù)結構的繼承,Caffe也因此可以在盡可能小的內(nèi)存占用下獲得很高的效率。(追求性能的同時Caffe也犧牲了一些代碼可讀性)
在更高一級的Layer中Blob用下面的形式表示學習到的參數(shù):
vector<shared_ptr<Blob<Dtype> > > blobs_; 這里使用的是一個Blob的容器是因為某些Layer包含多組學習參數(shù),比如多個卷積核的卷積層。
以及Layer所傳遞的數(shù)據(jù)形式,后面還會涉及到這里:
vector<Blob<Dtype>*> &bottom; vector<Blob<Dtype>*> *top 2.2. Layer:
2.2.1. 5大Layer派生類型
Caffe十分強調(diào)網(wǎng)絡的層次性,也就是說卷積操作,非線性變換(ReLU等),Pooling,權值連接等全部都由某一種Layer來表示。具體來說分為5大類Layer
  • NeuronLayer類?定義于neuron_layers.hpp中,其派生類主要是元素級別的運算(比如Dropout運算,激活函數(shù)ReLu,Sigmoid等),運算均為同址計算(in-place computation,返回值覆蓋原值而占用新的內(nèi)存)。
  • LossLayer類?定義于loss_layers.hpp中,其派生類會產(chǎn)生loss,只有這些層能夠產(chǎn)生loss。
  • 數(shù)據(jù)層?定義于data_layer.hpp中,作為網(wǎng)絡的最底層,主要實現(xiàn)數(shù)據(jù)格式的轉(zhuǎn)換。
  • 特征表達層(我自己分的類)定義于vision_layers.hpp(為什么叫vision這個名字,我目前還不清楚),實現(xiàn)特征表達功能,更具體地說包含卷積操作,Pooling操作,他們基本都會產(chǎn)生新的內(nèi)存占用(Pooling相對較小)。
  • 網(wǎng)絡連接層和激活函數(shù)(我自己分的類)定義于common_layers.hpp,Caffe提供了單個層與多個層的連接,并在這個頭文件中聲明。這里還包括了常用的全連接層InnerProductLayer類。
2.2.2. Layer的重要成員函數(shù)
在Layer內(nèi)部,數(shù)據(jù)主要有兩種傳遞方式,正向傳導(Forward)和反向傳導(Backward)。Forward和Backward有CPU和GPU(部分有)兩種實現(xiàn)。Caffe中所有的Layer都要用這兩種方法傳遞數(shù)據(jù)。
virtual void Forward(const vector<Blob<Dtype>*> &bottom, vector<Blob<Dtype>*> *top) = 0; virtual void Backward(const vector<Blob<Dtype>*> &top,const vector<bool> &propagate_down, vector<Blob<Dtype>*> *bottom) = 0; Layer類派生出來的層類通過這實現(xiàn)這兩個虛函數(shù),產(chǎn)生了各式各樣功能的層類。Forward是從根據(jù)bottom計算top的過程,Backward則相反(根據(jù)top計算bottom)。注意這里為什么用了一個包含Blob的容器(vector),對于大多數(shù)Layer來說輸入和輸出都各連接只有一個Layer,然而對于某些Layer存在一對多的情況,比如LossLayer和某些連接層。在網(wǎng)路結構定義文件(*.proto)中每一層的參數(shù)bottom和top數(shù)目就決定了vector中元素數(shù)目。
layers {bottom: "decode1neuron" // 該層底下連接的第一個Layerbottom: "flatdata" // 該層底下連接的第二個Layertop: "l2_error" // 該層頂上連接的一個Layername: "loss" // 該層的名字type: EUCLIDEAN_LOSS // 該層的類型loss_weight: 0 } 2.2.3. Layer的重要成員變量
loss
vector<Dtype> loss_; 每一層又有一個loss_值,只不多大多數(shù)Layer都是0,只有LossLayer才可能產(chǎn)生非0的loss_。計算loss是會把所有層的loss_相加。
learnable parameters
vector<shared_ptr<Blob<Dtype> > > blobs_; 前面提到過的,Layer學習到的參數(shù)。
2.3. Net:
Net用容器的形式將多個Layer有序地放在一起,其自身實現(xiàn)的功能主要是對逐層Layer進行初始化,以及提供Update( )的接口(更新網(wǎng)絡參數(shù)),本身不能對參數(shù)進行有效地學習過程。
vector<shared_ptr<Layer<Dtype> > > layers_; 同樣Net也有它自己的
vector<Blob<Dtype>*>& Forward(const vector<Blob<Dtype>* > & bottom,Dtype* loss = NULL); void Net<Dtype>::Backward(); 他們是對整個網(wǎng)絡的前向和方向傳導,各調(diào)用一次就可以計算出網(wǎng)絡的loss了。
2.4. Solver
這個類中包含一個Net的指針,主要是實現(xiàn)了訓練模型參數(shù)所采用的優(yōu)化算法,它所派生的類就可以對整個網(wǎng)絡進行訓練了。
shared_ptr<Net<Dtype> > net_; 不同的模型訓練方法通過重載函數(shù)ComputeUpdateValue( )實現(xiàn)計算update參數(shù)的核心功能
virtual void ComputeUpdateValue() = 0; 最后當進行整個網(wǎng)絡訓練過程(也就是你運行Caffe訓練某個模型)的時候,實際上是在運行caffe.cpp中的train( )函數(shù),而這個函數(shù)實際上是實例化一個Solver對象,初始化后調(diào)用了Solver中的Solve( )方法。而這個Solve( )函數(shù)主要就是在迭代運行下面這兩個函數(shù),就是剛才介紹的哪幾個函數(shù)。
ComputeUpdateValue(); net_->Update();
==============================================================

至此,從底層到頂層對Caffe的主要結構都應該有了大致的概念。為了集中重點介紹Caffe的代碼結構,文中略去了大量Caffe相關的實現(xiàn)細節(jié)和技巧,比如Layer和Net的參數(shù)如何初始化,proto文件的定義,基于cblas的卷積等操作的實現(xiàn)(cblas實現(xiàn)卷積這一點我的個人主頁GanYuFei中的《Caffe學習筆記5-BLAS與boost::thread加速》有介紹)等等就不一一列舉了。

整體來看Layer部分代碼最多,也反映出Caffe比較重視豐富網(wǎng)絡單元的類型,然而由于Caffe的代碼結構高度層次化,使得某些研究以及應用(比如研究類似非逐層連接的神經(jīng)網(wǎng)絡這種復雜的網(wǎng)絡連接方式)難以在該平臺實現(xiàn)。這也就是一開始說的一個不足。

另外,Caffe基本數(shù)據(jù)單元都用Blob,使得數(shù)據(jù)在內(nèi)存中的存儲變得十分高效,緊湊,從而提升了整體訓練能力,而同時帶來的問題是我們看見的一些可讀性上的不便,比如forward的參數(shù)也是直接用Blob而不是設計一個新類以增強可讀性。所以說性能的提升是以可讀性為代價的。
最后一點也是最重要的一點,我從Caffe學到了很多。第一次看的C++項目就看到這么好的代碼,實在是受益匪淺,在這里也感謝作者賈揚清等人的貢獻。

甘宇飛更新于2/13/2015 編輯于 2015-02-13?36 條評論?感謝? 分享 ?收藏???沒有幫助???舉報???作者保留權利 更多回答 Gein Chen?,Deep Learning/Linux/Vimer yuncheng lu、愛吃麻辣菠蘿、張小璐?等人贊同 樓上的大神回答的都很好了,非常感謝。這里我想說一下我自己學習caffe的方式,限于時間篇幅,并不想深入到具體的實現(xiàn)細節(jié),只是從大的方向上談談,因為講清楚一個細節(jié)都是一篇博客的篇幅了。

1.學習程序的第一步,先讓程序跑起來,看看結果,這樣就會有直觀的感受。
Caffe的官網(wǎng)上Caffe | Deep Learning Framework?提供了很多的examples,你可以很容易地開始訓練一些已有的經(jīng)典模型,如LeNet。我建議先從?LeNet MNIST Tutorial開始,因為數(shù)據(jù)集很小,網(wǎng)絡也很小但很經(jīng)典,用很少的時間就可以跑起來了。當你看到terminal刷拉拉的一行行輸出,看到不斷減少的loss和不斷上升的accuracy,訓練結束你得到了99+%的準確率,感覺好厲害的樣子。你可以多跑跑幾個例子,熟悉一下環(huán)境和接口。

2.單步調(diào)試,跟著Caffe在網(wǎng)絡里流動
當玩了幾天之后,你對Caffe的接口有點熟悉了,對已有的例子也玩膩了,你開始想看看具體是怎么實現(xiàn)的了。我覺得最好的方法是通過單步調(diào)試的方式跟著程序一步一步的在網(wǎng)絡里前向傳播,然后再被當成誤差信息傳回來。

Caffe就像一個你平常編程中Project,你可以使用IDE或者GDB去調(diào)試它,這里我們不細說調(diào)試的過程。你可以先跟蹤前向傳播的過程,無非就是從高層次到低層次的調(diào)用Forward函數(shù), Solver->Net->Layer->Specific Layer (Convolution等...).后向傳播也類似,但因為你對Caffe里面的各種變量運算不熟悉,當你跟蹤完前向傳播時可能已經(jīng)頭暈眼花了,還是休息一下,消化一下整個前向傳播的流程。

剛剛開始你沒有必要對每個Layer的計算細節(jié)都那么較真,大概知道程序的運算流程就好,這樣你才可以比較快的對Caffe有個大體的把握。

3.個性化定制Caffe
到這里,你已經(jīng)可以說自己有用過Caffe了,但是還不能算入門,因為你還不知道怎么修改源碼,滿足自己特定的需求。我們很多時候都需要自己定義新的層來完成特定的運算,這時你需要在Caffe里添加新的層。

你一開肯定無從下手,腦子一片空白。幸運的是Caffe github上的Wiki?Development · BVLC/caffe Wiki · GitHub已經(jīng)有了教程了,而且這是最接近latest Caffe的源碼結構的教程,你在網(wǎng)上搜到的Blog很多是有點過時的,因為Caffe最近又重構了代碼。你可以跟著它的指導去添加自己的層。

雖然你已經(jīng)知道要在哪里添加自己的東西了,但你遇到最核心的問題是如何寫下面這四個函數(shù)。
  • forward_cpu()
  • forward_gpu()
  • backward_cpu()
  • backward_gpu()
你可以先模仿已有的層去實現(xiàn)這四個函數(shù),而且我相信forward函數(shù)很快就可以寫出來了,但backward的還是一頭霧水。這時我們就要補補神經(jīng)網(wǎng)絡里最核心的內(nèi)容了——Backpropagation.

4.理解并實現(xiàn)Backpropagation
這個我覺得是與平臺無關的,不管你是使用Caffe、Torch 7,還是Theano,你都需要深刻理解并掌握的。因為我比較笨,花了好長時間才能夠適應推導中的各種符號。其實也不難,就是誤差順著Chain rule法則流回到前面的層。我不打算自己推導后向傳播的過程,因為我知道我沒有辦法將它表達得很好,而且網(wǎng)上已經(jīng)有很多非常好的教程了。下面是我覺得比較好的學習步驟吧。
  • 從淺層的神經(jīng)網(wǎng)絡(所謂的全連接層)的后向傳播開始,因為這個比較簡單,而且現(xiàn)在我們常說的CNN和LSTM的梯度計算也最終會回歸到這里。
    • 第一個必看的是Ng深入淺出的Ufldl教程UFLDL Tutorial,還有中文版的,這對不喜歡看英語的同學是個好消息。當然你看一遍不理解,再看一遍,忘了,再看,讀個幾遍你才會對推導過程和數(shù)學符號熟悉。我頭腦不大行,來來回回看了好多次。
    • 當然,Ufldl的教程有點短,我還發(fā)現(xiàn)了一個講得更細膩清晰的教程,?Michael Nielsen寫的Neural networks and deep learning。它講得實在太好了,以至于把我的任督二脈打通了。在Ufldl的基礎上讀這個,你應該可以很快掌握全連接層的反向傳播。
    • 最后在拿出standford大牛karpathy的一篇博客Hacker's guide to Neural Networks,這里用了具體的編程例子手把手教你算梯度,并不是推導后向傳播公式的,是關于通用梯度計算的。用心去體會一下。
  • 這時你躍躍欲試,回去查看Caffe源碼里Convolution層的實現(xiàn),但發(fā)現(xiàn)自己好像沒看懂。雖說卷積層和全連接層的推導大同小異,但思維上還是有個gap的。我建議你先去看看Caffe如何實現(xiàn)卷積的,Caffe作者賈揚清大牛在知乎上的回答在 Caffe 中如何計算卷積?讓我茅塞頓開。重點理解im2col和col2im.
  • 這時你知道了Convolution的前向傳播,還差一點就可以弄明白后向傳播怎么實現(xiàn)了。我建議你死磕Caffe中Convolution層的計算過程,把每一步都搞清楚,經(jīng)過痛苦的過程之后你會對反向傳播有了新的體會的。在這之后,你應該有能力添加自己的層了。再補充一個完整的添加新的層的教程Making a Caffe Layer ? Computer Vision Enthusiast。這篇教程從頭開始實現(xiàn)了一個Angle To Sine Cosine Layer,包含了梯度推導,前向與后向傳播的CPU和GPU函數(shù),非常棒的一個教程。
  • 最后,建議學習一下基本的GPU Cuda編程,雖然Caffe中已經(jīng)把Cuda函數(shù)封裝起來了,用起來很方便,但有時還是需要使用kernel函數(shù)等Cuda接口的函數(shù)。這里有一個入門的視頻教程,講得挺不錯的NVIDIA CUDA初級教程視頻

第二個回答,講得還是一樣的亂,謝謝觀看。

發(fā)布于 2016-01-06?21 條評論?感謝? 分享 ?收藏???沒有幫助???舉報???作者保留權利 41贊同 反對,不會顯示你的姓名 米八?,人臉檢測/關鍵點定位/識別 吳昊、白世明、知乎用戶?等人贊同 其實關于怎么用caffe,我一直想寫篇文章,因為給太多人講過怎么用了,也幫很多人基于caffe寫過代碼。14年初因為趕NIPS,開始用caffe,大概用了有一年半了。

先說個大概,知道了神經(jīng)網(wǎng)絡的結構,forward跟backward是怎樣的一個過程,基本上就知道了caffe的結構了。按照神經(jīng)網(wǎng)絡的運行過程看Caffe就好了。

既然說神經(jīng)網(wǎng)絡,那么就得有一個網(wǎng)絡出來,caffe里面就用Net這個類來記錄這個網(wǎng)絡。

那么網(wǎng)絡是由很多個layer構成,自然而然就會有Layer這個類,為了統(tǒng)一管理這些類,自然而然就想要抽象,那么Layer這個抽象類作為一個最基本的單元出現(xiàn)了,接下來就會有實現(xiàn)各種功能的layer出現(xiàn),如:Convolution/ReLU/Softmax等。

Layer間需要連接啊,Layer需要有輸入輸出啊,caffe里面用Bottom來表示輸入,Top表示輸出,前一層Layer的top是后一層layer的bottom,這樣,連接搞掂了,輸入輸出也搞掂了。

網(wǎng)絡搞掂了,layer搞掂了,那就要搞個求解算法啊,那么Solver這個類就出現(xiàn)了,這個就是用來求解網(wǎng)絡的。

就醬紫,有時間再寫得詳細一點。反正就這么一句話:按照神經(jīng)網(wǎng)絡的運行過程看Caffe就好了。
from:?http://www.zhihu.com/question/27982282/answer/39350629 《新程序員》:云原生和全面數(shù)字化實踐50位技術專家共同創(chuàng)作,文字、視頻、音頻交互閱讀

總結

以上是生活随笔為你收集整理的深度学习caffe的代码怎么读?的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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