❶ 深度學習caffe的代碼怎麼讀
樓上的大神回答的都很好了,非常感謝。這里我想說一下我自己學習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解決回歸問題
如何在Caffe中配置每一個層的結構最近剛在電腦上裝好Caffe,由於神經網路中有不同的層結構,不同類型的層又有不同的參數,所有就根據Caffe官網的說明文檔做了一個簡單的總結。1.VisionLayers1.1卷積層(Convolution)類型:CONVOLUTION例子layers{name:"conv1"type:CONVOLUTIONbottom:"data"top:"conv1"blobs_lr:1#_lr:2#_decay:1#_decay:0#_param{num_output:96#learn96filterskernel_size:11#eachfilteris11x11stride:4#_filler{type:"gaussian"#:0.01#distributionwithstdev0.01(defaultmean:0)}bias_filler{type:"constant"#initializethebiasestozero(0)value:0}}}blobs_lr:學習率調整的參數,在上面的例子中設置權重學習率和運行中求解器給出的學習率一樣,同時是偏置學習率為權重的兩倍。weight_decay:卷積層的重要參數必須參數:num_output(c_o):過濾器的個數kernel_size(orkernel_handkernel_w):過濾器的大小可選參數:weight_filler[defaulttype:'constant'value:0]:參數的初始化方法bias_filler:偏置的初始化方法bias_term[defaulttrue]:指定是否是否開啟偏置項pad(orpad_handpad_w)[default0]:指定在輸入的每一邊加上多少個像素stride(orstride_handstride_w)[default1]:指定過濾器的步長group(g)[default1]:Ifg>1,.Specifically,,els.通過卷積後的大小變化:輸入:n*c_i*h_i*w_i輸出:n*c_o*h_o*w_o,其中h_o=(h_i+2*pad_h-kernel_h)/stride_h+1,w_o通過同樣的方法計算。1.2池化層(Pooling)類型:POOLING例子layers{name:"pool1"type:POOLINGbottom:"conv1"top:"pool1"pooling_param{pool:MAXkernel_size:3#poolovera3x3regionstride:2#steptwopixels(inthebottomblob)betweenpoolingregions}}卷積層的重要參數必需參數:kernel_size(orkernel_handkernel_w):過濾器的大小可選參數:pool[defaultMAX]:pooling的方法,目前有MAX,AVE,和STOCHASTIC三種方法pad(orpad_handpad_w)[default0]:指定在輸入的每一遍加上多少個像素stride(orstride_handstride_w)[default1]:指定過濾器的步長通過池化後的大小變化:輸入:n*c_i*h_i*w_i輸出:n*c_o*h_o*w_o,其中h_o=(h_i+2*pad_h-kernel_h)/stride_h+1,w_o通過同樣的方法計算。1.3LocalResponseNormalization(LRN)類型:LRNLocalResponseNormalization是對一個局部的輸入區域進行的歸一化(激活a被加一個歸一化權重(分母部分)生成了新的激活b),有兩種不同的形式,一種的輸入區域為相鄰的channels(crosschannelLRN),另一種是為同一個channel內的空間區域(withinchannelLRN)計算公式:對每一個輸入除以可選參數:local_size[default5]:對於crosschannelLRN為需要求和的鄰近channel的數量;對於withinchannelLRN為需要求和的空間區域的邊長alpha[default1]:scaling參數beta[default5]:指數norm_region[defaultACROSS_CHANNELS]:選擇哪種LRN的方法ACROSS_CHANNELS或者WITHIN_CHANNEL2.LossLayers深度學習是通過最小化輸出和目標的Loss來驅動學習。2.1Softmax類型:SOFTMAX_LOSS2.2Sum-of-Squares/Euclidean類型:EUCLIDEAN_LOSS2.3Hinge/Margin類型:HINGE_LOSS例子:#L1Normlayers{name:"loss"type:HINGE_LOSSbottom:"pred"bottom:"label"}#L2Normlayers{name:"loss"type:HINGE_LOSSbottom:"pred"bottom:"label"top:"loss"hinge_loss_param{norm:L2}}可選參數:norm[defaultL1]:選擇L1或者L2范數輸入:n*c*h*wPredictionsn*1*1*1Labels輸出1*1*1*1ComputedLoss2.4SigmoidCross-Entropy類型:SIGMOID_CROSS_ENTROPY_LOSS2.5Infogain類型:INFOGAIN_LOSS2.6AccuracyandTop-k類型:ACCURACY用來計算輸出和目標的正確率,事實上這不是一個loss,而且沒有backward這一步。3.激勵層(Activation/NeuronLayers)一般來說,激勵層是element-wise的操作,輸入和輸出的大小相同,一般情況下就是一個非線性函數。3.1ReLU/Rectified-LinearandLeaky-ReLU類型:RELU例子:layers{name:"relu1"type:RELUbottom:"conv1"top:"conv1"}可選參數:negative_slope[default0]:指定輸入值小於零時的輸出。ReLU是目前使用做多的激勵函數,主要因為其收斂更快,並且能保持同樣效果。標準的ReLU函數為max(x,0),而一般為當x>0時輸出x,但x<=0時輸出negative_slope。RELU層支持in-place計算,這意味著bottom的輸出和輸入相同以避免內存的消耗。3.2Sigmoid類型:SIGMOID例子:layers{name:"encode1neuron"bottom:"encode1"top:"encode1neuron"type:SIGMOID}SIGMOID層通過sigmoid(x)計算每一個輸入x的輸出,函數如下圖。3.3TanH/HyperbolicTangent類型:TANH例子:layers{name:"encode1neuron"bottom:"encode1"top:"encode1neuron"type:SIGMOID}TANH層通過tanh(x)計算每一個輸入x的輸出,函數如下圖。3.3AbsoluteValue類型:ABSVAL例子:layers{name:"layer"bottom:"in"top:"out"type:ABSVAL}ABSVAL層通過abs(x)計算每一個輸入x的輸出。3.4Power類型:POWER例子:layers{name:"layer"bottom:"in"top:"out"type:POWERpower_param{power:1scale:1shift:0}}可選參數:power[default1]scale[default1]shift[default0]POWER層通過(shift+scale*x)^power計算每一個輸入x的輸出。3.5BNLL類型:BNLL例子:layers{name:"layer"bottom:"in"top:"out"type:BNLL}BNLL(binomialnormalloglikelihood)層通過log(1+exp(x))計算每一個輸入x的輸出。4.數據層(DataLayers)數據通過數據層進入Caffe,數據層在整個網路的底部。數據可以來自高效的資料庫(LevelDB或者LMDB),直接來自內存。如果不追求高效性,可以以HDF5或者一般圖像的格式從硬碟讀取數據。4.1Database類型:DATA必須參數:source:包含數據的目錄名稱batch_size:一次處理的輸入的數量可選參數:rand_skip:在開始的時候從輸入中跳過這個數值,這在非同步隨機梯度下降(SGD)的時候非常有用backend[defaultLEVELDB]:選擇使用LEVELDB或者LMDB4.2In-Memory類型:MEMORY_DATA必需參數:batch_size,channels,height,width:指定從內存讀取數據的大小,withoutingit.Inordertouseit,onemustcallMemoryDataLayer::Reset(fromC++)orNet.set_input_arrays(fromPython)(as4Drowmajorarray),whichisreadonebatch-sizedchunkatatime.4.3HDF5Input類型:HDF5_DATA必要參數:source:需要讀取的文件名batch_size:一次處理的輸入的數量4.4HDF5Output類型:HDF5_OUTPUT必要參數:file_name:輸出的文件名HDF5的作用和這節中的其他的層不一樣,它是把輸入的blobs寫到硬碟4.5Images類型:IMAGE_DATA必要參數:source:text文件的名字,每一行給出一張圖片的文件名和labelbatch_size:一個batch中圖片的數量可選參數:rand_skip:在開始的時候從輸入中跳過這個數值,這在非同步隨機梯度下降(SGD)的時候非常有用shuffle[defaultfalse]new_height,new_width:把所有的圖像resize到這個大小4.6Windows類型:WINDOW_DATA4.7Dummy類型:DUMMY_DATADummy層用於development和debugging。具體參數DummyDataParameter。5.一般層(CommonLayers)5.1全連接層InnerProct類型:INNER_PRODUCT例子:layers{name:"fc8"type:INNER_PRODUCTblobs_lr:1#_lr:2#_decay:1#_decay:0#_proct_param{num_output:1000weight_filler{type:"gaussian"std:0.01}bias_filler{type:"constant"value:0}}bottom:"fc7"top:"fc8"}必要參數:num_output(c_o):過濾器的個數可選參數:weight_filler[defaulttype:'constant'value:0]:參數的初始化方法bias_filler:偏置的初始化方法bias_term[defaulttrue]:指定是否是否開啟偏置項通過全連接層後的大小變化:輸入:n*c_i*h_i*w_i輸出:n*c_o*1*15.2Splitting類型:SPLITSplitting層可以把一個輸入blob分離成多個輸出blobs。這個用在當需要把一個blob輸入到多個輸出層的時候。5.3Flattening類型:FLATTENFlattening是把一個輸入的大小為n*c*h*w變成一個簡單的向量,其大小為n*(c*h*w)*1*1。5.4Concatenation類型:CONCAT例子:layers{name:"concat"bottom:"in1"bottom:"in2"top:"out"type:CONCATconcat_param{concat_dim:1}}可選參數:concat_dim[default1]:0代表鏈接num,1代表鏈接channels通過全連接層後的大小變化:輸入:從1到K的每一個blob的大小n_i*c_i*h*w輸出:如果concat_dim=0:(n_1+n_2++n_K)*c_1*h*w,需要保證所有輸入的c_i相同。如果concat_dim=1:n_1*(c_1+c_2++c_K)*h*w,需要保證所有輸入的n_i相同。通過Concatenation層,可以把多個的blobs鏈接成一個blob。5.(currentlynumorchannelonly)withgivensliceindices.5.6ElementwiseOperations類型:ELTWISE5.7Argmax類型:ARGMAX5.8Softmax類型:SOFTMAX5.9Mean-VarianceNormalization類型:MVN6.參考Caffe
❸ caffe中怎麼固定前面的網路參數,訓練後面層的參數
1、會更新,finetune的過程相當於繼續訓練,跟直接訓練的區別是初始化的時候:
a. 直接訓練是按照網路定義指定的方式初始化(如高斯隨機初始化)
b. finetune是用你已經有的參數文件來初始化(就是之前訓練好的caffemodel)
2、嗯,這個問題有兩種情況:比如有4個全連接層A->B->C->D
a. 你希望C層的參數不會改變,C前面的AB層的參數也不會改變,這種情況也就是D層的梯度不往前反向傳播到D層的輸入blob(也就是C層的輸出blob 沒有得到梯度),你可以通過設置D層的propagate_down為false來做到。
propagate_down的數量與輸入blob的數量相同,假如你某個層有2個輸入blob,那麼你應該在該layer的Param裡面寫上兩行:
propagate_down : 0 # 第1個輸入blob不會得到反向傳播的梯度
propagate_down : 0 # 第2個輸入blob不會得到反向傳播的梯度
這樣的話,你這個layer的梯度就不會反向傳播啦,前面的所有layer的參數也就不會改變了
b. 你希望C層的參數不會改變,但是C前面的AB層的參數會改變,這種情況,只是固定了C層的參數,C層得到的梯度依然會反向傳播給前面的B層。只需要將對應的參數blob的學習率調整為0:
你在layer裡面加上param { lr_mult: 0 }就可以了,比如全連接層裡面:
layer {
type: "InnerProct"
param { # 對應第1個參數blob的配置,也就是全連接層的參數矩陣的配置
lr_mult: 0 # 學習率為0,其他參數可以看caffe.proto裡面的ParamSpec這個類型
}
param { # 對應第2個參數blob的配置,也就是全連接層的偏置項的配置
lr_mult: 0 # 學習率為0
}
}
不知道這樣說你能不能理解
❹ 深度學習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初級教程視頻。
作者:Gein Chen
來源:知乎
❺ caffe怎麼把全連接層轉成convolutional層
首先將原模型載入進來fc_param,然後把全conv的配置文件和模型載入conv_param,然後將fc_param進行flat並賦值給conv_param,當然在flat時會按照conv_param的格式進行賦值。然後我們就完成了全conv的模型生成,此時再把模型保存下來,就完成了模型轉換為全conv的模型的過程。
然後在我們使用full conv模型時,只要載入就可以了。
❻ caffe訓練網路的時候學習率應該怎麼設置
1、會更新,finetune的過程相當於繼續訓練,跟直接訓練的區別是初始化的時候:
a. 直接訓練是按照網路定義指定的方式初始化(如高斯隨機初始化)
b. finetune是用你已經有的參數文件來初始化(就是之前訓練好的caffemodel)
2、嗯,這個問題有兩種情況:比如有4個全連接層A->B->C->D
a. 你希望C層的參數不會改變,C前面的AB層的參數也不會改變,這種情況也就是D層的梯度不往前反向傳播到D層的輸入blob(也就是C層的輸出blob 沒有得到梯度),你可以通過設置D層的propagate_down為false來做到。
propagate_down的數量與輸入blob的數量相同,假如你某個層有2個輸入blob,那麼你應該在該layer的Param裡面寫上兩行:
propagate_down : 0 # 第1個輸入blob不會得到反向傳播的梯度
propagate_down : 0 # 第2個輸入blob不會得到反向傳播的梯度
這樣的話,你這個layer的梯度就不會反向傳播啦,前面的所有layer的參數也就不會改變了
b. 你希望C層的參數不會改變,但是C前面的AB層的參數會改變,這種情況,只是固定了C層的參數,C層得到的梯度依然會反向傳播給前面的B層。只需要將對應的參數blob的學習率調整為0:
你在layer裡面加上param { lr_mult: 0 }就可以了,比如全連接層裡面:
layer {
type: "InnerProct"
param { # 對應第1個參數blob的配置,也就是全連接層的參數矩陣的配置
lr_mult: 0 # 學習率為0,其他參數可以看caffe.proto裡面的ParamSpec這個類型
}
param { # 對應第2個參數blob的配置,也就是全連接層的偏置項的配置
lr_mult: 0 # 學習率為0
}
}
不知道這樣說你能不能理解
❼ 如何在Caffe中配置每一個層的結構
如何在Caffe中配置每一個層的結構
最近剛在電腦上裝好Caffe,由於神經網路中有不同的層結構,不同類型的層又有不同的參數,所有就根據Caffe官網的說明文檔做了一個簡單的總結。
1. Vision Layers
1.1 卷積層(Convolution)
類型:CONVOLUTION
例子
layers {
name: "conv1"
type: CONVOLUTION
bottom: "data"
top: "conv1"
blobs_lr: 1 # learning rate multiplier for the filters
blobs_lr: 2 # learning rate multiplier for the biases
weight_decay: 1 # weight decay multiplier for the filters
weight_decay: 0 # weight decay multiplier for the biases
convolution_param {
num_output: 96 # learn 96 filters
kernel_size: 11 # each filter is 11x11
stride: 4 # step 4 pixels between each filter application
weight_filler {
type: "gaussian" # initialize the filters from a Gaussian
std: 0.01 # distribution with stdev 0.01 (default mean: 0)
}
bias_filler {
type: "constant" # initialize the biases to zero (0)
value: 0
}
}
}
blobs_lr: 學習率調整的參數,在上面的例子中設置權重學習率和運行中求解器給出的學習率一樣,同時是偏置學習率為權重的兩倍。
weight_decay:
卷積層的重要參數
必須參數:
num_output (c_o):過濾器的個數
kernel_size (or kernel_h and kernel_w):過濾器的大小
可選參數:
weight_filler [default type: 'constant' value: 0]:參數的初始化方法
bias_filler:偏置的初始化方法
bias_term [default true]:指定是否是否開啟偏置項
pad (or pad_h and pad_w) [default 0]:指定在輸入的每一邊加上多少個像素
stride (or stride_h and stride_w) [default 1]:指定過濾器的步長
group (g) [default 1]: If g > 1, we restrict the connectivityof each filter to a subset of the input. Specifically, the input and outputchannels are separated into g groups, and the ith output group channels will beonly connected to the ith input group channels.
通過卷積後的大小變化:
輸入:n * c_i * h_i * w_i
輸出:n * c_o * h_o * w_o,其中h_o = (h_i + 2 * pad_h - kernel_h) /stride_h + 1,w_o通過同樣的方法計算。
1.2 池化層(Pooling)
類型:POOLING
例子
layers {
name: "pool1"
type: POOLING
bottom: "conv1"
top: "pool1"
pooling_param {
pool: MAX
kernel_size: 3 # pool over a 3x3 region
stride: 2 # step two pixels (in the bottom blob) between pooling regions
}
}
卷積層的重要參數
必需參數:
kernel_size (or kernel_h and kernel_w):過濾器的大小
可選參數:
pool [default MAX]:pooling的方法,目前有MAX, AVE, 和STOCHASTIC三種方法
pad (or pad_h and pad_w) [default 0]:指定在輸入的每一遍加上多少個像素
stride (or stride_h and stride_w) [default1]:指定過濾器的步長
通過池化後的大小變化:
輸入:n * c_i * h_i * w_i
輸出:n * c_o * h_o * w_o,其中h_o = (h_i + 2 * pad_h - kernel_h) /stride_h + 1,w_o通過同樣的方法計算。
1.3 Local Response Normalization (LRN)
類型:LRN
Local ResponseNormalization是對一個局部的輸入區域進行的歸一化(激活a被加一個歸一化權重(分母部分)生成了新的激活b),有兩種不同的形式,一種的輸入區域為相鄰的channels(cross channel LRN),另一種是為同一個channel內的空間區域(within channel LRN)
計算公式:對每一個輸入除以
可選參數:
local_size [default 5]:對於cross channel LRN為需要求和的鄰近channel的數量;對於within channel LRN為需要求和的空間區域的邊長
alpha [default 1]:scaling參數
beta [default 5]:指數
norm_region [default ACROSS_CHANNELS]: 選擇哪種LRN的方法ACROSS_CHANNELS 或者WITHIN_CHANNEL
2. Loss Layers
深度學習是通過最小化輸出和目標的Loss來驅動學習。
2.1 Softmax
類型: SOFTMAX_LOSS
2.2 Sum-of-Squares / Euclidean
類型: EUCLIDEAN_LOSS
2.3 Hinge / Margin
類型: HINGE_LOSS
例子:
# L1 Norm
layers {
name: "loss"
type: HINGE_LOSS
bottom: "pred"
bottom: "label"
}
# L2 Norm
layers {
name: "loss"
type: HINGE_LOSS
bottom: "pred"
bottom: "label"
top: "loss"
hinge_loss_param {
norm: L2
}
}
可選參數:
norm [default L1]: 選擇L1或者 L2范數
輸入:
n * c * h * wPredictions
n * 1 * 1 * 1Labels
輸出
1 * 1 * 1 * 1Computed Loss
2.4 Sigmoid Cross-Entropy
類型:SIGMOID_CROSS_ENTROPY_LOSS
2.5 Infogain
類型:INFOGAIN_LOSS
2.6 Accuracy and Top-k
類型:ACCURACY
用來計算輸出和目標的正確率,事實上這不是一個loss,而且沒有backward這一步。
3. 激勵層(Activation / Neuron Layers)
一般來說,激勵層是element-wise的操作,輸入和輸出的大小相同,一般情況下就是一個非線性函數。
3.1 ReLU / Rectified-Linear and Leaky-ReLU
類型: RELU
例子:
layers {
name: "relu1"
type: RELU
bottom: "conv1"
top: "conv1"
}
可選參數:
negative_slope [default 0]:指定輸入值小於零時的輸出。
ReLU是目前使用做多的激勵函數,主要因為其收斂更快,並且能保持同樣效果。
標準的ReLU函數為max(x, 0),而一般為當x > 0時輸出x,但x <= 0時輸出negative_slope。RELU層支持in-place計算,這意味著bottom的輸出和輸入相同以避免內存的消耗。
3.2 Sigmoid
類型: SIGMOID
例子:
layers {
name: "encode1neuron"
bottom: "encode1"
top: "encode1neuron"
type: SIGMOID
}
SIGMOID 層通過 sigmoid(x) 計算每一個輸入x的輸出,函數如下圖。
3.3 TanH / Hyperbolic Tangent
類型: TANH
例子:
layers {
name: "encode1neuron"
bottom: "encode1"
top: "encode1neuron"
type: SIGMOID
}
TANH層通過 tanh(x) 計算每一個輸入x的輸出,函數如下圖。
3.3 Absolute Value
類型: ABSVAL
例子:
layers {
name: "layer"
bottom: "in"
top: "out"
type: ABSVAL
}
ABSVAL層通過 abs(x) 計算每一個輸入x的輸出。
3.4 Power
類型: POWER
例子:
layers {
name: "layer"
bottom: "in"
top: "out"
type: POWER
power_param {
power: 1
scale: 1
shift: 0
}
}
可選參數:
power [default 1]
scale [default 1]
shift [default 0]
POWER層通過 (shift + scale * x) ^ power計算每一個輸入x的輸出。
3.5 BNLL
類型: BNLL
例子:
layers {
name: "layer"
bottom: "in"
top: "out"
type: BNLL
}
BNLL (binomial normal log likelihood) 層通過 log(1 + exp(x)) 計算每一個輸入x的輸出。
4. 數據層(Data Layers)
數據通過數據層進入Caffe,數據層在整個網路的底部。數據可以來自高效的資料庫(LevelDB 或者 LMDB),直接來自內存。如果不追求高效性,可以以HDF5或者一般圖像的格式從硬碟讀取數據。
4.1 Database
類型:DATA
必須參數:
source:包含數據的目錄名稱
batch_size:一次處理的輸入的數量
可選參數:
rand_skip:在開始的時候從輸入中跳過這個數值,這在非同步隨機梯度下降(SGD)的時候非常有用
backend [default LEVELDB]: 選擇使用 LEVELDB 或者 LMDB
4.2 In-Memory
類型: MEMORY_DATA
必需參數:
batch_size, channels, height, width: 指定從內存讀取數據的大小
The memory data layer reads data directly from memory, without ing it. In order to use it, one must call MemoryDataLayer::Reset (from C++) or Net.set_input_arrays (from Python) in order to specify a source of contiguous data (as 4D row major array), which is read one batch-sized chunk at a time.
4.3 HDF5 Input
類型: HDF5_DATA
必要參數:
source:需要讀取的文件名
batch_size:一次處理的輸入的數量
4.4 HDF5 Output
類型: HDF5_OUTPUT
必要參數:
file_name: 輸出的文件名
HDF5的作用和這節中的其他的層不一樣,它是把輸入的blobs寫到硬碟
4.5 Images
類型: IMAGE_DATA
必要參數:
source: text文件的名字,每一行給出一張圖片的文件名和label
batch_size: 一個batch中圖片的數量
可選參數:
rand_skip:在開始的時候從輸入中跳過這個數值,這在非同步隨機梯度下降(SGD)的時候非常有用
shuffle [default false]
new_height, new_width: 把所有的圖像resize到這個大小
4.6 Windows
類型:WINDOW_DATA
4.7 Dummy
類型:DUMMY_DATA
Dummy 層用於development 和debugging。具體參數DummyDataParameter。
5. 一般層(Common Layers)
5.1 全連接層Inner Proct
類型:INNER_PRODUCT
例子:
layers {
name: "fc8"
type: INNER_PRODUCT
blobs_lr: 1 # learning rate multiplier for the filters
blobs_lr: 2 # learning rate multiplier for the biases
weight_decay: 1 # weight decay multiplier for the filters
weight_decay: 0 # weight decay multiplier for the biases
inner_proct_param {
num_output: 1000
weight_filler {
type: "gaussian"
std: 0.01
}
bias_filler {
type: "constant"
value: 0
}
}
bottom: "fc7"
top: "fc8"
}
必要參數:
num_output (c_o):過濾器的個數
可選參數:
weight_filler [default type: 'constant' value: 0]:參數的初始化方法
bias_filler:偏置的初始化方法
bias_term [default true]:指定是否是否開啟偏置項
通過全連接層後的大小變化:
輸入:n * c_i * h_i * w_i
輸出:n * c_o * 1 *1
5.2 Splitting
類型:SPLIT
Splitting層可以把一個輸入blob分離成多個輸出blobs。這個用在當需要把一個blob輸入到多個輸出層的時候。
5.3 Flattening
類型:FLATTEN
Flattening是把一個輸入的大小為n * c * h * w變成一個簡單的向量,其大小為 n * (c*h*w) * 1 * 1。
5.4 Concatenation
類型:CONCAT
例子:
layers {
name: "concat"
bottom: "in1"
bottom: "in2"
top: "out"
type: CONCAT
concat_param {
concat_dim: 1
}
}
可選參數:
concat_dim [default 1]:0代表鏈接num,1代表鏈接channels
通過全連接層後的大小變化:
輸入:從1到K的每一個blob的大小n_i * c_i * h * w
輸出:
如果concat_dim = 0: (n_1 + n_2 + ... + n_K) *c_1 * h * w,需要保證所有輸入的c_i 相同。
如果concat_dim = 1: n_1 * (c_1 + c_2 + ... +c_K) * h * w,需要保證所有輸入的n_i 相同。
通過Concatenation層,可以把多個的blobs鏈接成一個blob。
5.5 Slicing
The SLICE layer is a utility layer that slices an input layer to multiple output layers along a given dimension (currently num or channel only) with given slice indices.
5.6 Elementwise Operations
類型:ELTWISE
5.7 Argmax
類型:ARGMAX
5.8 Softmax
類型:SOFTMAX
5.9 Mean-Variance Normalization
類型:MVN
6. 參考
Caffe
❽ 在caffe上怎麼做到各個卷積層權值參數共享
通過設置param {name : xxx}參數,如果名字相同就共享,不相同就不共享
❾ 如何針對自己的需要修改caffe的網路
你說的可能是finetune,它有幾個步驟
根據自己的數據分類類別,修改原有網路的最後一層全連接層
將前面各層均凍結參數,僅打開最後一層全連接層的參數更新
載入模型已有參數,如caffenet,vgg等
根據自己的數據對模型進行微調訓練。
微調成功後,可選擇打開所有層進行小步長參數更新。
我在網上講caffe,感興趣可以搜搜我的名字。