1. 程式人生 > >caffe入門指南

caffe入門指南

作者:Gein Chen
連結:https://www.zhihu.com/question/27982282/answer/80242005
來源:知乎
著作權歸作者所有。商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。

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->SpecificLayer (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、Torch7,還是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初級教程視訊

個人總結:

第一階段: 用別人資料跑別人模型階段:

1:安裝官方caffe,執行caffe自帶例子mnist;(這一階段不涉及caffe原始碼閱讀,修改)

目標:  

1:熟悉訓練網路的整體流程;

2:熟悉solver.protxt,train-test.ptototxt的引數意義

3:熟悉典型網路結構各層的意義;

第二階段:微調模型階段

2:用自己的資料finetuning別人的模型;

目標:

1:知道如何構建資料庫,並知道調整網路的資料層來適應我們的資料;

2:知道如何調節solver.prototxt和train-test.prototxt等引數來訓練網路;(由於訓練時間很長,建議謹慎修改引數;)

3:知道分析loss曲線和accaracy曲線,並以此為依據調節引數;

4:可以閱讀部分層的原始碼,並稍作修改來解決問題;

第三階段:從零訓練模型階段;

3:用自己的資料來訓練別人的模型;

目標: 這一階段和第二階段類似;

第四階段: 自己的資料;自己的模型

4:能夠依據自己的問題,設計模型;

目標:

1:能夠根據自己的需要設計模型;

2:能夠梳理caffe的原始碼;

3:實現caffe中沒有的layer;