A. 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
}
}
不知道這樣說你能不能理解
B. 如何修改caffe源碼
首先,利用Understanding軟體,可以方便的查看到caffe源碼的目錄結構,如下圖所示。
這個文件涉及到最底層的數據讀寫工作。
C. 如何利用Caffe訓練ImageNet分類網路
1.下載好來自ImageNet的training和validation數據集合;分別存放在如下的格式:
/path/to/imagenet/train/n01440764/n01440764_10026.JPEG
/path/to/imagenet/val/ILSVRC2012_val_00000001.JPEG
2. 進行一些預處理操作:
cd $CAFFE_ROOT/data/ilsvrc12/
./get_ilsvrc_aux.sh
3.訓練數據和測試數據分別放在train.txt和val.txt中,裡面有他們的文件和相對應的標簽;
4. 最後作者把1000類的類名用0--999表示,他們相對應的類別名稱則用synset_words.txt 來存儲他們之間的映射。
5.作者提到怎麼去是否應該先把圖像都歸一化到256*256中,作者提到用Maprece去加快這種過程;
也可以直接這么做:
for name in /path/to/imagenet/val/*.JPEG; do
convert -resize 256x256\! $name $name
Done
6.在 create_imagenet.sh中設置訓練的參數,並在裡面指定訓練和測試的資料庫路徑,如果圖像沒有提前歸一化到相同的大小,則需要加」RESIZE=true「,設置」GLOG_logtostderr=1 「表示了可以參考更多的信息,
在執行 ./create_imagenet.sh 之後會有新的數據文件生成:
ilsvrc12_train_leveldb 和 ilsvrc12_val_leveldb
7. 因為模型需要我們減去圖像的均值,所以我們需要計算圖像均值,在工具
tools/compute_image_mean.cpp 實現了這種操作,
或者可以直接用:
./make_imagenet_mean.sh 腳本來進行計算圖像均值,並生成:
data/ilsvrc12/imagenet_mean.binaryproto 文件
8.定義網路的結構:imagenet_train_val.prototxt .
裡面有兩行指定了資料庫和圖像的路徑
source: "ilvsrc12_train_leveldb"
mean_file:"../../data/ilsvrc12/imagenet_mean.binaryproto"
並且指定了 include { phase: TRAIN } or include { phase: TEST } .來區分訓練和測試
9.關於輸入層的不同:
訓練數據中,,data項來自 ilsvrc12_train_leveldb 並且進行了隨機鏡像操作,測試數據中data項來自於ilsvrc12_val_leveldb 而沒有進行隨機鏡像操作;
10.輸出層的不同:
輸出層都為 softmax_loss 層,在訓練網路當中,用來計算損失函數,並且用來初始化BP過程,測試網路同樣有一個第二個輸出層,accuracy,它用來報告測試的精度,在訓練的過程中,測試網路將實例化並且測試准確率,產成的命令行為:Test score #0: xxx and Test score #1: xxx 等。
11.運行網路,其中設置
每批batch為256個,運行450000次迭代,接近90次epoch;
每1000次迭代,就在用測試集進行測試;
設置初始的學習率為0.01,並且每100000次迭代中進行學習率下降,大概進行20次epoch;
每20次epoch就顯示出一些數據信息;
網路訓練的動量為0.9,權重衰減因子為0.0005,
每10000次迭代中,就生成當前狀態的快照;
這些設置在 examples/imagenet/imagenet_solver.prototxt .中進行設置,並且同樣我們需要指定文件的路徑:
net: "imagenet_train_val.prototxt"
12.開始訓練網路:
./train_imagenet.sh
13. 在K20中,每20個迭代花費36s,所以,一幅圖像的一次前饋+反饋(FW+BW)大概需要7ms,前饋花費2.5ms,剩下的是反饋,
可以在 examples/net_speed_benchmark.cpp 中進行時間的查看;
14.因為我們有保存了快照,所以我們可以通過
./resume_training.sh 來進行resume恢復,腳本caffe_imagenet_train_1000.solverstate 保留了要恢復的所有信息,
15.總結,Caffe可以很方便進行通過設置文件的方式來進行設置不同的網路結構。
D. caffe網路配置文件中layer和layers的區別
Here's roughly the process I follow.
Add a class declaration for your layer to the appropriate one of common_layers.hpp, data_layers.hpp,loss_layers.hpp, neuron_layers.hpp,
or vision_layers.hpp. Include an inline implementation oftype and
the *Blobs() methods to specify blob number requirements. Omit the *_gpu declarations
if you'll only be implementing CPU code.
Implement your layer in layers/your_layer.cpp.
SetUp for initialization: reading parameters, allocating buffers, etc.
Forward_cpu for the function your layer computes
Backward_cpu for its gradient
(Optional) Implement the GPU versions Forward_gpu and Backward_gpu in layers/your_layer.cu.
Add your layer to proto/caffe.proto, updating the next available ID. Also declare
parameters, if needed, in this file.
Make your layer createable by adding it to layer_factory.cpp.
Write tests in test/test_your_layer.cpp. Use test/test_gradient_check_util.hpp to
check that your Forward and Backward implementations are in numerical agreement.
上面是一個大致的流程,我就直接翻譯過來吧,因為我自己琢磨出來的步驟跟這個是一樣的。在這
里,我們就添加一個Wtf_Layer,然後作用跟Convolution_Layer一模一樣。注意這里的命名方式,Wtf第一個字母大寫,剩下的小
寫,算是一個命名規范吧,強迫症表示很舒服。
1. 首先確定要添加的layer的類型,是common_layer 還是
data_layer 還是loss_layer, neuron_layer, vision_layer
,這里的Wtf_Layer肯定是屬vision_layer了,所以打開vision_layers.hpp
然後復制convolution_layer的相關代碼,把類名還有構造函數的名字改為WtfLayer,如果沒有用到GPU運算,那麼把裡面的帶GPU
的函數都刪掉
2. 將Wtf_layer.cpp 添加到src\caffe\layers文件夾中,代碼內容復制convolution_layer.cpp 把對應的類名修改(可以搜一下conv關鍵字,然後改為Wtf)
3. 假如有gpu的代碼就添加響應的Wtf_layer.cu (這里不添加了)
4. 修改proto/caffe.proto文件,找到LayerType,添加WTF,並更新ID(新的ID應該是34)。假如說Wtf_Layer有參數,比如Convolution肯定是有參數的,那麼添加WtfParameter類
5. 在layer_factory.cpp中添加響應的代碼,就是一堆if ... else的那片代碼
6. 這個可以不做,但是為了結果還是做一個,就是寫一個測試文件,檢查前向後向傳播的數據是否正確。gradient_check的原理可以參考UFLDL教程的對應章節
之後我會更新我自己寫的maxout_layer的demo,在這立一個flag以鞭策自己完成吧╮(╯▽╰)╭
(二) 如何添加maxout_layer
表示被bengio的maxout給搞郁悶了,自己擺出一個公式巴拉巴拉說了一堆,結果用到卷積層的maxout卻給的另一種方案,吐槽無力,不過後來又想了下應該是bengio沒表述清楚的問題。
我的maxout的演算法思路是這樣的,首先要確定一個group_size變數,表示
最大值是在group_size這樣一個規模的集合下挑選出來的,簡而言之就是給定group_size個數,取最大。確定好group_size變數,
然後讓卷積層的output_num變為原來的group_size倍,這樣輸出的featuremap的個數就變為原來的group_size倍,然後
以group_size為一組劃分這些featuremap,每組裡面挑出響應最大的點構成一個新的featuremap,這樣就得到了maxout層的
輸出。
E. 如何調用caffe已經訓練好的net
我不了解你是怎麼訓練的,但是對於二分類問題最後准確率是0.5,有可能是因為最終結果都分到同一類上面去了,這個你需要調用caffe看看網路最終的輸出來判斷
對於二分類問題,一般訓練的時候,正負樣本要混合在一起訓練(一般在輸入層那裡設置shuffle來做到),如果沒有shuffle,並且你的輸入數據正好是前面的是正樣本,後面的是負樣本,那麼就會造成你的網路最開始一直傾向於輸出1,在輸入一直是正樣本的時候,loss的確會下降,然後到負樣本的時候,loss一下子跳很高,由於後面全是負樣本,網路訓練使得它傾向於輸出0,就又慢慢降下來了,最終你的網路基本上就是輸出值都是1或者都是0了
如果是這種情況,可以在輸入層那裡設置shuffle為true
當然具體情況具體分析,我也不了解你的情況,只是告訴你有這個可能而已
F. 如何修改caffe上lenet模型
1 cifar10資料庫
60000張32*32 彩色圖片 共10類
50000張訓練
10000張測試
下載cifar10資料庫
這是binary格式的,所以我們要把它轉換成leveldb格式。
2 在../caffe-windows/examples/cifar10文件夾中有一個 convert_cifar_data.cpp
將他include到MainCaller.cpp中。如下:編譯....我是一次就通過了 ,在bin文件夾里出現convert_cifar_data.exe。然後 就可以進行格式轉換。binary→leveldb
可以在bin文件夾下新建一個input文件夾。將cifar10.binary文件放在input文件夾中,這樣轉換時就不用寫路徑了。
cmd進入bin文件夾
執行後,在output文件夾下有cifar_train_leveldb和cifar_test_leveldb兩個文件夾。裡面是轉化好的leveldb格式數據。
當然,也可以寫一個bat文件處理,方便以後再次使用。
3 下面我們要求數據圖像的均值
編譯../../tools/comput_image_mean.cpp
編譯成功後。接下來求mean
cmd進入bin。
執行後,在bin文件夾下出現一個mean.binaryproto文件,這就是所需的均值文件。
4 訓練cifar網路
在.../examples/cifar10文件夾里已經有網路的配置文件,我們只需要將cifar_train_leveldb和cifar_test_leveldb兩個文件夾還有mean.binaryproto文件拷到cifar0文件夾下。
修改cifar10_quick_train.prototxt中的source: "cifar-train-leveldb" mean_file: "mean.binaryproto" 和cifar10_quick_test.prototxt中的source: "cifar-test-leveldb"
mean_file: "mean.binaryproto"就可以了,
後面再訓練就類似於MNIST的訓練。寫一個train_quick.bat,內容如下:
[plain] view plain
..\\..\\bin\\MainCaller.exe ..\\..\\bin\\train_net.exe
SET GLOG_logtostderr=1
"../../bin/train_net.exe" cifar10_quick_solver.prototxt
pause
先編譯一遍 train_net.cpp
運行train_quick.bat
G. 如何針對自己的需要修改caffe的網路
你說的可能是finetune,它有幾個步驟
根據自己的數據分類類別,修改原有網路的最後一層全連接層
將前面各層均凍結參數,僅打開最後一層全連接層的參數更新
載入模型已有參數,如caffenet,vgg等
根據自己的數據對模型進行微調訓練。
微調成功後,可選擇打開所有層進行小步長參數更新。
我在網上講caffe,感興趣可以搜搜我的名字。
H. caffe安裝在ubuntu中哪裡
Ubuntu 14.04 64位機上用Caffe+MNIST訓練Lenet網路操作步驟
將終端定位到Caffe根目錄;
2.MNIST資料庫並解壓縮:$ ./data/mnist/get_mnist.sh
3.將其轉換成Lmdb資料庫格式:$ ./examples/mnist/create_mnist.sh
執行完此shell腳本後,會在./examples/mnist下增加兩個新目錄,mnist_test_lmdb和mnist_train_lmdb
4.train model:$ ./examples/mnist/train_lenet.sh
(1)、使用LeNet網路(《Gradient-BasedLearning Applied to Document Recognition》);
(2)、使用./examples/mnist/lenet_train_test.prototxtmodel;
(3)、使用./examples/mnist/lenet_solver.prototxtmodel;
(4)、執行train_lenet.sh腳本,會調用./build/tools目錄下的caffe執行文件,此執行文件的實現是./tools目錄下的caffe.cpp文件;
(5)、執行此腳本後,會生成幾個文件,其中./examples/mnist/lenet_iter_10000.caffemodel則是最終訓練生成的model文件;
(6)、以上默認的是在GPU模式下運行,如果想讓其在CPU模式下運行,只需將lenet_solver.prototxt文件中的solver_mode欄位值由原來的GPU改為CPU即可。