caffe增長新的layer

---恢復內容開始---html

在caffe中若是想要增長新的功能層,必需要本身在caffe的安裝目錄下(source code)中增長相應的文件git

大致步驟以下:github

  1. 在caffe/src/caffe/proto/caffe.proto中增長對應layer的parameter message,  有兩部分,如今LayerParameter中註冊新層名字,注意選取不重複的ID, 而後寫上新層的message傳遞的參數
  2. 在caffe/include/caffe/layers/中添加相應的新層的hpp文件,看其餘層的實現,仿照着寫
  3. 在caffe/src/caffe/layers/增長相應的.cpp和.cu的文件,進行類的實現, 在文件的末尾仿照着寫個註冊的語句REGISTE....
  4. 在caffe/src/caffe/gtest中增長新層的測試代碼,這樣能夠保證所添加的層是正確的,不會在以後的運行中報錯

參考教程: https://blog.csdn.net/tangwei2014/article/details/46815231api

http://www.javashuo.com/article/p-towekvit-hm.html數組

tensorflow ckpt轉 caffemodel遇到的坑函數

 

龍明盛老師的論文基本都是caffe   能夠看他是怎麼實現的一些層測試

 

一個別人實現的新層例子: spa

https://github.com/luoyetx/OrdinalRegression.net

 

具體實現:3d

  1. 在newlayer.hpp中常定義一些常量或者變量,用來在前傳中存儲中間計算結果,由於若是定義在forward計算過程當中,那麼反傳時還要重複計算,因此定義在hpp文件中比較合適
  2. 在newlayer.cpp中,主要有三個功能須要實現: 
    1. LayerSetUp: 主要是作一些CHECK工做,而後根據bottom和top對類中的數據成員初始化    注意通常都是繼承基類,若是基類實現了就不要再實現了
    2. Forward_cpu: 前傳
    3. backward_cpu: 反傳,計算梯度  
  3. 在newlayer.cu中,實現GPU下的前傳和反傳
  4. 測試代碼
  5. 從新編譯, make all      make test    make runtest

 

 一些基礎知識:

  1. Blob 是一個模板類,至關因而個結構體,主要的成員變量有 data_, diff_, shape_, count_, capacity_,   成員函數主要有Reshape, ReshapeLike, SharedData, Updata
    1. 參考: https://blog.csdn.net/seven_first/article/details/47398613
    2. https://www.jianshu.com/p/59e77efcce83
    3.  

  2. Layer:  卷積層
    1. 參考: https://blog.csdn.net/xizero00/article/details/51049858
    2. 官網api查找:  https://caffe.berkeleyvision.org/doxygen/namespacecaffe.html

 

Kevin 老師幫忙整理的資料

1.  bottom是個blob指針的數組,bottom[0]第一個輸入的指針, bottom[1]第二個輸入指針, top[0]第一個輸出指針

LayerSetUp函數中:

int bottom_batch_size_ = bottom[0]->num();
int bottom_channels_ = bottom[0]->channels();
int bottom_height_ = bottom[0]->height();
int bottom_width_ = bottom[0]->width();

注意,對於指針取數據用->  對於單純blob取數據 用 .

blob<Dtype>*  表示指向blob的指針,其中blob的數據類型是Dtype

可是若是要取blob對應的數據地址要用 ->cpu_data()  這個相似於取數據的地址操做

Forward_cpu函數中:

Dtype* top_data = top[0]->mutable_cpu_data();  //mutable_cpu_data()表示top[0]數據可修改   

const Dtype* bottom_data = bottom[0]->cpu_data();   //-> cpu_data()表示只可讀

 

caffe自帶的數學函數 https://blog.csdn.net/seven_first/article/details/47378697

 

2.  shape操做

vector<int> top_shape = bottom[0]->shape();
top[0]->Reshape(top_shape);

若是top[0]的channel是bottom[0]的channel+bottom[1]的channel,其餘的都同樣,能夠這樣定義:
vector<int> top_shape = bottom[0]->shape();
top_shape[1] = bottom[0]->shape(1)+bottom[0]->shape(1);
top[0]->Reshape(top_shape);

 

若是這個變量是一箇中間變量的話,能夠這樣定義:
Blob<Dtype> conf_permute_; //通常寫在.hpp裏
而後在.cpp中的LayerSetUp或者Reshape中定義 conf_permute_.ReshapeLike(*(bottom[1]));

注意成員函數的參數都是類型的,好比是blob指針,就能夠直接輸bottom[0], 若是要求參數是blob, 

若是有取地址符,那麼只須要傳入實體,這樣也能修改內容

若是是指針的話是 *的形式

 

3. 關於count

const int count = bottom[0]->count();表示 count = bottom[0]的num * channel * height * width
const int count = bottom[0]->count(0, 1); 表示 count = bottom[0]的num * channel
const int count = bottom[0]->count(0, 2); 表示 count = bottom[0]的num * channel* height
const int count = bottom[0]->count(1); 表示 count = bottom[0]的 channel * height * width
const int count = bottom[0]->count(2); 表示 count = bottom[0]的 height * width

const int num = bottom[0]->shape(0); //bottom[0]的batch_size
const int channel = bottom[0]->shape(1); //bottom[0]的channel
const int height = bottom[0]->shape(2); //bottom[0]的height
const int width = bottom[0]->shape(3); //bottom[0]的width


3.printf:
const int count = bottom[0]->count();
printf("count %d\n", count);


4.gdb Debug調試:
https://zhuanlan.zhihu.com/p/28146796

相關文章
相關標籤/搜索