深度學習caffe的代碼怎麼讀?

Caffe的代碼結構是什麼樣的?從代碼結構上來看,Caffe在實現Deep Learning上有什麼優點和缺點?


我是從Torch7轉移到Caffe的人,僅供參考,當你閱讀前你應該具備一些有關DL的基礎知識,本文集中寫Caffe代碼結構而非介紹DL知識。
我是去年底開始看Caffe代碼的,看代碼的時間加在一起也不到一個月,也算半個新手,我的回答是從新手角度作一個入門階段的經驗分享。

本文只涉及Caffe結構的相關問題,不涉及具體實現技巧等細節。

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

1. 初識Caffe
1.1. Caffe相對與其他DL框架的優點和缺點:
優點:

  • 速度快。Google Protocol Buffer數據標準為Caffe提升了效率。
  • 學術論文採用此模型較多。不確定是不是最多,但接觸到的不少論文都與Caffe有關(R-CNN,DSN,最近還有人用Caffe實現LSTM)

缺點:

  • 曾更新過重要函數介面。有人反映,偶爾會出現介面變換的情況,自己很久前寫的代碼可能過了一段時間就不能和新版本很好地兼容了。(現在更新速度放緩,介面逐步趨於穩定,感謝 評論區王峰的建議)
  • 對於某些研究方向來說的人並不適合。這個需要對Caffe的結構有一定了解,(後面提到)。

1.2. Caffe代碼層次。
回答裡面有人說熟悉Blob,Layer,Net,Solver這樣的幾大類,我比較贊同。我基本是從這個順序開始學習的,這四個類複雜性從低到高,貫穿了整個Caffe。把他們分為三個層次介紹。

  • Blob:是基礎的數據結構,是用來保存學習到的參數以及網路傳輸過程中產生數據的類。
  • Layer:是網路的基本單元,由此派生出了各種層類。修改這部分的人主要是研究特徵表達方向的。
  • Net:是網路的搭建,將Layer所派生出層類組合成網路。Solver:是Net的求解,修改這部分人主要會是研究DL求解方向的。

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

2. Caffe進階
2.1. Blob:
Caffe支持CUDA,在數據級別上也做了一些優化,這部分最重要的是知道它主要是對protocol buffer所定義的數據結構的繼承,Caffe也因此可以在儘可能小的內存佔用下獲得很高的效率。(追求性能的同時Caffe也犧牲了一些代碼可讀性)
在更高一級的Layer中Blob用下面的形式表示學習到的參數:

vector& &> &> blobs_;

這裡使用的是一個Blob的容器是因為某些Layer包含多組學習參數,比如多個卷積核的卷積層。
以及Layer所傳遞的數據形式,後面還會涉及到這裡:

vector&*&> bottom;
vector&*&> *top

2.2. Layer:
2.2.1. 5大Layer派生類型
Caffe十分強調網路的層次性,也就是說卷積操作,非線性變換(ReLU等),Pooling,權值連接等全部都由某一種Layer來表示。具體來說分為5大類Layer

  • NeuronLayer類 定義於neuron_layers.hpp中,其派生類主要是元素級別的運算(比如Dropout運算,激活函數ReLu,Sigmoid等),運算均為同址計算(in-place computation,返回值覆蓋原值而佔用新的內存)。
  • LossLayer類 定義於loss_layers.hpp中,其派生類會產生loss,只有這些層能夠產生loss
  • 數據層 定義於data_layer.hpp中,作為網路的最底層,主要實現數據格式的轉換。
  • 特徵表達層(我自己分的類)定義於vision_layers.hpp(為什麼叫vision這個名字,我目前還不清楚),實現特徵表達功能,更具體地說包含卷積操作,Pooling操作,他們基本都會產生新的內存佔用(Pooling相對較小)。
  • 網路連接層和激活函數(我自己分的類)定義於common_layers.hpp,Caffe提供了單個層與多個層的連接,並在這個頭文件中聲明。這裡還包括了常用的全連接層InnerProductLayer類。

2.2.2. Layer的重要成員函數
在Layer內部,數據主要有兩種傳遞方式,正向傳導(Forward)反向傳導(Backward)。Forward和Backward有CPU和GPU(部分有)兩種實現。Caffe中所有的Layer都要用這兩種方法傳遞數據。

virtual void Forward(const vector&*&> bottom,
vector&*&> *top) = 0;
virtual void Backward(const vector&*&> top,
const vector& propagate_down,
vector&*&> *bottom) = 0;

Layer類派生出來的層類通過這實現這兩個虛函數,產生了各式各樣功能的層類。Forward是從根據bottom計算top的過程,Backward則相反(根據top計算bottom)。注意這裡為什麼用了一個包含Blob的容器(vector),對於大多數Layer來說輸入和輸出都各連接只有一個Layer,然而對於某些Layer存在一對多的情況,比如LossLayer和某些連接層。在網路結構定義文件(*.proto)中每一層的參數bottom和top數目就決定了vector中元素數目。

layers {
bottom: "decode1neuron" // 該層底下連接的第一個Layer
bottom: "flatdata" // 該層底下連接的第二個Layer
top: "l2_error" // 該層頂上連接的一個Layer
name: "loss" // 該層的名字
type: EUCLIDEAN_LOSS // 該層的類型
loss_weight: 0
}

2.2.3. Layer的重要成員變數
loss

vector& loss_;

每一層又有一個loss_值,只不多大多數Layer都是0,只有LossLayer才可能產生非0的loss_。計算loss是會把所有層的loss_相加。
learnable parameters

vector& &> &> blobs_;

前面提到過的,Layer學習到的參數。
2.3. Net:
Net用容器的形式將多個Layer有序地放在一起,其自身實現的功能主要是對逐層Layer進行初始化,以及提供Update( )的介面(更新網路參數),本身不能對參數進行有效地學習過程。

vector& &> &> layers_;

同樣Net也有它自己的

vector&*&> Forward(const vector&* &> bottom,
Dtype* loss = NULL);
void Net&::Backward();

他們是對整個網路的前向和方向傳導,各調用一次就可以計算出網路的loss了。
2.4. Solver
這個類中包含一個Net的指針,主要是實現了訓練模型參數所採用的優化演算法,它所派生的類就可以對整個網路進行訓練了。

shared_ptr& &> net_;

不同的模型訓練方法通過重載函數ComputeUpdateValue( )實現計算update參數的核心功能

virtual void ComputeUpdateValue() = 0;

最後當進行整個網路訓練過程(也就是你運行Caffe訓練某個模型)的時候,實際上是在運行caffe.cpp中的train( )函數,而這個函數實際上是實例化一個Solver對象,初始化後調用了Solver中的Solve( )方法。而這個Solve( )函數主要就是在迭代運行下面這兩個函數,就是剛才介紹的哪幾個函數。

ComputeUpdateValue();
net_-&>Update();

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

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

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

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

甘宇飛更新於2/13/2015


樓上的大神回答的都很好了,非常感謝。這裡我想說一下我自己學習caffe的方式,限於時間篇幅,並不想深入到具體的實現細節,只是從大的方向上談談,因為講清楚一個細節都是一篇博客的篇幅了。

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

2.單步調試,跟著Caffe在網路里流動
當玩了幾天之後,你對Caffe的介面有點熟悉了,對已有的例子也玩膩了,你開始想看看具體是怎麼實現的了。我覺得最好的方法是通過單步調試的方式跟著程序一步一步的在網路里前向傳播,然後再被當成誤差信息傳回來。

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

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

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

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

雖然你已經知道要在哪裡添加自己的東西了,但你遇到最核心的問題是如何寫下面這四個函數。

  • forward_cpu()
  • forward_gpu()
  • backward_cpu()
  • backward_gpu()

你可以先模仿已有的層去實現這四個函數,而且我相信forward函數很快就可以寫出來了,但backward的還是一頭霧水。這時我們就要補補神經網路里最核心的內容了——Backpropagation.

4.理解並實現Backpropagation
這個我覺得是與平台無關的,不管你是使用Caffe、Torch 7,還是Theano,你都需要深刻理解並掌握的。因為我比較笨,花了好長時間才能夠適應推導中的各種符號。其實也不難,就是誤差順著Chain rule法則流回到前面的層。我不打算自己推導後向傳播的過程,因為我知道我沒有辦法將它表達得很好,而且網上已經有很多非常好的教程了。下面是我覺得比較好的學習步驟吧。

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

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


總結了下本人在閱讀Caffe代碼時在互聯網上搜索的一些資源以及自己和網上一些同學對代碼的中文注釋,其中注釋主要集中在Solver、Net、Layer、Blob類的頭文件及實現文件,github地址:GitHub - BUPTLdy/Caffe_Code_Analysis: Caffe_Code_Analysis。Caffe運行的大概流程可以參考Caffe Source Code Analysis

網上一些對Caffe代碼分析的優秀博客:

All Posts – Xuesong"s Blog

GanYuFei (甘宇飛)

Caffe源碼解析之Layer

Caffe源碼(一):math_functions 分析

感謝互聯網。


其實關於怎麼用caffe,我一直想寫篇文章,因為給太多人講過怎麼用了,也幫很多人基於caffe寫過代碼。14年初因為趕NIPS,開始用caffe,大概用了有一年半了。

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

既然說神經網路,那麼就得有一個網路出來,caffe裡面就用Net這個類來記錄這個網路。

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

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

網路搞掂了,layer搞掂了,那就要搞個求解演算法啊,那麼Solver這個類就出現了,這個就是用來求解網路的。

就醬紫,有時間再寫得詳細一點。反正就這麼一句話:按照神經網路的運行過程看Caffe就好了。


深度學習源碼解讀-ch0-talk is cheap - 黑客與畫家 - 知乎專欄
深度學習源碼解讀-ch1-JSON is awesome - 黑客與畫家 - 知乎專欄
深度學習源碼解讀-ch2-Caffe is coming - 黑客與畫家 - 知乎專欄
深度學習源碼解讀-ch3-Caffe is brewing - 黑客與畫家 - 知乎專欄
深度學習源碼解讀-ch4-Caffe 中的設計模式 - 黑客與畫家 - 知乎專欄


我貼一個我自己看的源碼分析的鏈接。博客:一畝半分地


其實深度學習的東西,邏輯上模塊還是很清晰的,跟搭積木一樣,但是要把基礎的模塊弄清楚,而基礎模塊屬於深度學習理論的東西,跟具體的庫關係不大,無論你是用theano torch還是別的,具體的就是一些基本模塊,比如卷積 全連接矩陣 吉布斯採樣 數來數去也不是很多,主要要把矩陣玩的很熟,他裡面都是各個矩陣轉來轉去的,比如卷積就是把二維圖像矩陣通過某種操作變成另外一堆二維矩陣,這個過程就是一個小積木,然後所有的積木都是通過矩陣運算拼到一起去,變成一個大的構建,這個大構建上面有很多未知的參數,然後弄一個演算法比如梯度下降把這些參數確定出來

如果題主完全是門外漢,建議用一下keras這個庫,看幾個例子就明白深度學習大概怎麼玩了

至於並發方面 都是最後求解的事情,有了架子之後,理解怎麼分散式去算並不是很難


正好最近的工作與Caffe相關,就把網上已有的一些資料以及自己
讀代碼時候的親身經歷簡單地整理了一下,希望能對大家有所幫助~
================================================================
Caffe"s Abstract Framework:
就像樓上一些回答里說到的,要讀懂caffe,首先要熟悉Blob,Layer,Net,Solver這幾個大類。這四個大類自下而上,環環相扣,貫穿了整個caffe的結構,下面先分別簡單地介紹一下這四個類的主要作用。

  • Blob:作為數據傳輸的媒介,無論是網路權重參數,還是輸入數據,都是轉化為Blob數據結構來存儲
  • Layer:作為網路的基礎單元,神經網路中層與層間的數據節點、前後傳遞都在該數據結構中被實現,層類種類豐富,比如常用的卷積層、全連接層、pooling層等等,大大地增加了網路的多樣性
  • Net:作為網路的整體骨架,決定了網路中的層次數目以及各個層的類別等信息
  • Solver:作為網路的求解策略,涉及到求解優化問題的策略選擇以及參數確定方面,修改這個模塊的話一般都會是研究DL的優化求解的方向。

================================================================
Caffe"s Concrete Framework:
1. Blob:
1.1. Blob的類型描述
Caffe內部採用的數據類型主要是對protocol buffer所定義的數據結構的繼承,因此可以在儘可能小的內存佔用下獲得很高的效率,雖然追求性能的同時Caffe也會犧牲了一些代碼可讀性。
直觀來說,可以把Blob看成一個有4維的結構體(包含數據和梯度),而實際上,它們只是一維的指針而已,其4維結構通過shape屬性得以計算出來。
1.2. Blob的重要成員函數和變數

shared_ptr& data_ //數據
shared_ptr& diff_ //梯度

void Blob&::Reshape(const int num, const int channels, const int height,
const int width)

重新修改Blob的形狀(4維),並根據形狀來申請動態內存存儲數據和梯度。

inline int count(int start_axis, int end_axis) const

計算Blob所需要的基本數據單元的數量。2. Layer:
2.1. Layer的類型描述
Layer是網路模型和計算的核心,在數據存儲上,主要分成bottom_vecs、top_vecs、weightsbias三個部分;在數據傳遞上,也主要分為LayerSetUp、Reshape、Forward、Backward四個過程,符合直觀上對層與層之間連接的理解,貼切自然。
2.2. Layer的重要成員函數和變數

vector& loss_ //每一層都會有一個loss值,但只有LossLayer才會產生非0的loss
vector& &> &> blobs_ //Layer所學習的參數,包括權值和偏差

virtual void LayerSetUp(const vector&*&> bottom,
const vector&*&> top)

通過bottom Blob對象的形狀以及LayerParameter(從prototxt讀入)來確定Layer的學習參數(以Blob類型存儲)的形狀。

virtual void Reshape(const vector&*&> bottom,
const vector&*&> top)

通過bottom Blob對象的形狀以及Layer的學習參數的形狀來確定top Blob對象的形狀。

virtual void Forward(const vector&*&> bottom,
vector&*&> *top) = 0

Layer內部數據正向傳播,從bottom到top方向。

virtual void Backward(const vector&*&> top,
const vector& propagate_down,
vector&*&> *bottom) = 0

Layer內部梯度反向傳播,從top到bottom方向。
3. Net:
3.1. Net的類型描述
Net用容器的形式將多個Layer有序地放在一起,其自身實現的功能主要是對逐層Layer進行初始化,以及提供Update( )的介面(更新網路參數),本身不能對參數進行有效地學習過程。
3.2. Net的重要成員函數和變數

vector& &> &> layers_ //構成該net的layers
vector&*&> &> bottom_vecs_ //每一層layer中的bottom Blobs
vector&*&> &> top_vecs_ //每一層layer中的top Blobs
vector& &> &> params_ //整個net中的learnable parameter

void Init(const NetParameter param)

根據NetParameter進行net初始化,簡單的來說就是先把網路中所有層的bottom Blobstop Blobs(無重複)實例化,並從輸入層開始,逐層地進行Setup的工作,從而完成了整個網路的搭建,為後面的數據前後傳輸打下基礎。

vector&*&> Forward(const vector&* &> bottom,
Dtype* loss = NULL)
void Net&::Backward()

是對整個網路的前向和方向傳導,各調用一次就可以計算出網路的loss了。
4. Solver
4.1. Solver的類型描述
Solver類中包含一個Net的指針,主要是實現了訓練模型參數所採用的優化演算法,根據優化演算法的不同會派生不同的類,而基於這些子類就可以對網路進行正常的訓練過程。
4.2. Solver的重要成員函數和變數

shared_ptr& &> net_ //net對象

void Step(int iters)

對已初始化後的網路進行固定次數的訓練迭代過程。

ComputeUpdateValue();
net_-&>Update();

不同的模型訓練方法通過重載函數ComputeUpdateValue( )實現計算update參數的核心功能。
===============================================================
說到這兒,大家可能已經對Caffe的自底向上的主要結構有了一個大致的了解~
除了這些之外呢,Caffe裡面還涉及到了許多特色模塊,比如google的輕量級高效數據傳輸工具protobuf、負責stream輸出模塊的glog和負責命令行便捷輸入的gflags、factory宏定義等等...
最後想在這裡向caffe的contributors以及caffe blog的博主們表示深深的感激~ 由於本人的C++經驗不多,所以是花了較長的時間才大致理解caffe的實現(嗚嗚TT),但現在回頭想來確實收穫很大,不管是在代碼架構方面,還是在實現細節方面,caffe都有很多值得借鑒的地方,相信大家在閱讀完caffe之後也一定會受益匪淺~~~


來膜拜下樓上的caffe大神們,我玩了好久的caffe都還是不溜。說下像我這種菜鳥怎麼入門吧,先多玩幾個examples,然後分析下簡單的example代碼流程。看caffe源碼最好從底層往頂層看,也就是caffe.proto,blob,layer,net,solver依次。另外玩轉caffe最主要還是多接觸點課題,根據課題需要去探索caffe。熟悉的應用caffe無非也就幾個注意的:1、把數據集轉換成caffe可以讀入的格式,比如lmdb,hdf5等等。這方面谷歌可以搜出很多教程。2、輸入、輸出定義好,也就明白了具體怎麼利用caffe,想好你的模型的結構,如何輸入,輸出的分類器或者優化函數是什麼。3、根據自己需要去改loss_function對應的layer。4、一些小的深度學習設置技巧都直接做成了介面。

------------------------分割線---------------------------
謝謝@甘宇飛 的博客帶我入門。


作為一個caffe的初學者,感覺上邊幾位高票的答案已經寫的非常的好了。
但是我發現有一個普林斯頓大學Vision Group的caffe tutorial PPT做的很不錯,因此想和大家分享下。
鏈接: http://robots.princeton.edu/courses/COS598/2015sp/slides/Caffe/caffe_tutorial.pdf
p.s. 感覺nsight IDE不錯,nvidia出品。安裝也很簡單:

sudo apt-get install nvidia-nsight

關於nsight IDE如何進行caffe的調試,可以參見這裡:Build and Debug Caffe in Eclipse Nsight


Caffe 都已經不更新了,好么。逐層訓練等方法都沒有。


Caffe 作者現在在幫Google 開發 Tensorflow了。


TensorLayer 功能最全


個人覺得caffe的代碼CPU的相對比較好讀一點。讀之前先去了解一下protocol buffer。大概來說就是他用blob來代表各種維度的層,有點像theno的N-D tensor。然後每個數據層做對應的操作。你可以看看幾個簡單的,比如Euclidian_loss_layer這種就明白了。caffe的數據抓取是通過開一個單獨的線程按照順序從db裡面抓取的。

caffe的優點是代碼結構不錯,我自己給caffe寫過幾個數據層讀我自己的數據,他那種工廠模式我很喜歡。寫起來很方便而且不害怕錯(這就是工廠的一大好處,算是吧。。。耦合度不高)還有個最大的優點是github上都star了7000多了,這種actively-developed代碼上哪兒找去?自己調BUG時間都省了。缺點是因為全部都是用一種模式寫的所以效率不是很高,對比其他效率最高的代碼而言。


一點tip,多翻caffe的issue看,開發者在裡面對caffe的框架設計、演化討論很詳細


關於IO系統系列文章,非常好!!!
Physcal - 博客園


首先應該了解下幾個大的類,比如blob,net,layer,solver,然後看怎麼從proto文件中初始化創建網路,blob, layer, net這幾層關係中數據是如何傳遞的。至於不同的layer,用到那種layer的時候再看就ok。


單步調試,理解執行過程
推薦QT進行界面調試,適用於新手:
https://www.zhihu.com/question/27987666/answer/80728225


米8的答案邏輯很清楚了。就按照怎麼訓練神經網路,就按什麼順序看代碼。看的過程中可以先不要太在意實現細節,搞清楚函數的功能即可,最後再仔細過一遍會有更深刻全面的理解。

caffe代碼是好多個人寫的吧,裡面有些代碼風格都不一樣。
還有些函數又臭又長,沒記錯的話有個函數貌似寫了幾百行。。: (


可以參考一下本人總結的介紹caffe的運行流程來理解下http://blog.csdn.net/BVL10101111/article/details/74787586


不邀自來~

在我們的日常工作中發現TensorFlow是目前最強大的機器學習框架,沒有之一,而且有Google公司的支持,有最龐大的社區,一旦有什麼新模型都會有TensorFlow的實現可以使用(得益於TensorFlow的架構設計)。用TensorFlow來進行快速實驗是非常好的選擇。

但是我們也發現TensorFlow有兩個比較大的問題,第一個問題是TensorFlow的單機執行效率低,尤其是和Caffe相比,對於資金並不是很充足的創業公司,在有一定量數據的情況下,並無法支撐一個可以快速運行TensorFlow訓練的集群,這個時候Caffe以及其各種改版往往是更好的選擇,而我們日常工作的實驗場景就被此局限,因此更偏向於實際使用Caffe。

第二個問題是TensorFlow過於龐大,實際開發產品SDK的時候,我們希望訓練出來的模型能夠直接放到產品中使用,因此訓練和產品SDK使用的深度學習框架往往是一致或者可以互相轉換的。而TensorFlow過於龐大複雜,還需要使用專門的構建工具,在實際產品應用集成中往往要使用能夠完全掌控的工具和框架並進行修改,TensorFlow的複雜性正和這種要求背道而馳。當然也可能是我們的工作場景和人員限制導致我們沒有人力對TensorFlow進行深度研究、裁剪和維護,這也就是我們產品中使用Caffe的原因。


了解更多深度學習知識來StuQ上錄播課吧~

3個月深入學習 《深度神經網路實戰》課,帶你叩開深度學習的大門~

添加二維碼了解更多課程信息,也可以登錄StuQ官網了解更多課程信息~


http://weixin.qq.com/r/M9vk-BjEUUUurVyf944h (二維碼自動識別)


請問各位大牛,Caffe為什麼好像沒有進行逐層訓練,直接整個網路進行微調


正開始學習,mark大牛的分享


推薦閱讀:

機器學習中常常提到的正則化到底是什麼意思?
有哪些現代分析方法可以用於解決「紅樓夢續寫爭議」?有哪些例子?
神經網路,人工智慧這塊怎麼入門?
如何看待國人的論文SARM作者將論文從nips撤稿?
對於 Quant 來說, Financial Modeling 和傳統的機器學習方法有什麼聯繫和區別?

TAG:機器學習 | 深度學習(Deep Learning) |