沒錯,我又來水經驗了。在深度學習網路框架caffe中新增乙個簡單的新層,用來實現原框架中所沒有的功能:輸出一句話,以及乙個看起來似乎並沒有什麼實際作用的引數,下面詳細展開來說。
1. 首先,本文實現的layer名稱為allpasslayer,這裡不能和已有的層同名,功能為將輸入到該層的資料不做任何改變直接輸出到下一層(其間輸出一句話和乙個引數,證明資料確實經過了這個層)。allpasslayer層的forward和backwark實現非常容易,直接將輸入的blob資料複製到輸出的blob中,因此基本可以加入到任何已有網路中,不影響訓練和測試的結果。
2. 新增新的層aallpasslayer的實現,需要同其他的layer類一樣,分成宣告和實現兩個部分,對應放在.hpp和.cpp檔案中,如果用到gpu的話,還應該有相應的.cu檔案。其中.hpp標頭檔案放在/caffe-windows/include/caffe/layers/資料夾下,而 .cpp 和 .cu 放入/caffe-windows/src/caffe/layers下。這裡僅實現cpu上的**。
all_pass_layer.hpp
#ifndef caffe_all_pass_layer_hpp_
#define caffe_all_pass_layer_hpp_
#include #include "caffe/blob.hpp"
#include "caffe/layer.hpp"
#include "caffe/proto/caffe.pb.h"
#include "caffe/layers/neuron_layer.hpp"
namespace caffe
virtual inline const char* type() const
protected:
virtual void forward_cpu(const vector*>& bottom,
const vector*>& top);
virtual void forward_gpu(const vector*>& bottom,
const vector*>& top);
virtual void backward_cpu(const vector*>& top,
const vector& propagate_down, const vector*>& bottom);
virtual void backward_gpu(const vector*>& top,
const vector& propagate_down, const vector*>& bottom);
};} // namespace caffe
#endif // caffe_all_pass_layer_hpp_
正如所看到的那樣,上面只是一些函式的宣告,並沒有具體的實現,實現的話要寫在.cpp檔案中。
all_pass_layer.cpp
#include #include #include "caffe/layers/all_pass_layer.hpp"
#include using namespace std;
#define debug_ap(str) cout& bottom,
const vector*>& top)
caffe_copy(count, bottom_data, top_data);
//注意:獲取引數的兩個變數 "all_pass_param" 和 "key"
debug_ap("here is all pass layer, forwarding.");
debug_ap(this->layer_param_.all_pass_param().key());
}template void allpasslayer::backward_cpu(const vector*>& top,
const vector& propagate_down,
const vector*>& bottom)
caffe_copy(count, top_diff, bottom_diff);
}//同上
debug_ap("here is all pass layer, backwarding.");
debug_ap(this->layer_param_.all_pass_param().key());
}#ifdef cpu_only
stub_gpu(allpasslayer);
#endif
//注意:下面2行對層進行註冊,必不可少;注意巨集引數不能弄錯
instantiate_class(allpasslayer); // 類的名稱 allpasslayer
register_layer_class(allpass); // 層的名稱 allpass
} // namespace caffe
3.修改caffe.proto檔案
由於我們新新增的層是帶有引數的,因此需要在caffe.proto中進行相應的註冊和修改。
首先開啟caffe/src/caffe/proto/
caffe.proto檔案,找到message layerparameter{},在這裡我們要為新新增的層註冊乙個類似於id的東西。
順便更改一下這個:
我們需要為新新增的層創造乙個message函式:
message allpassparameter
另外還要找到message v1layerparameter裡enum layertype處加入id,如下圖:
在message v1layerparameter的最後加入id:
如果新增的層引數用到之前沒有定義的引數變數,我們還要在message v0layerparameter{}加入定義,我們定義的有乙個引數key,因此需要在v0layerparameter中新增如下:
4. 另外還有乙個要修改的在~\caffe-master\src\caffe\util\內upgrade_proto.cpp裡const char* upgradev1layertype(const v1layerparameter_layertype type) {
這裡allpass與v1layerparameter內的type名稱要保持一致。
5. 最後一步,對於windows下來說,也是最重要的一部,找到caffe/windows/libcaffe/下的libcaffe.vcxproj和libcaffe.vcxproj.filters進行修改,加入.hpp,.cpp,.cu(如果有的話)檔案的路徑:
第一步,在libcaffe.vcxproj加入
第二步:在libcaffe.vcxproj.filters加入
最後再重新編譯caffe就可以了
以測試mnist為例,我將成功加入的層新增在了data層和第一層卷積層之間:
下面是用一張手寫體數字進行測試的結果:
可以看到成功輸出了一句話和乙個引數,說明新增新層成功了。^_^
在新版caffe中新增center loss層
準備工作 1,首先你需要有乙個可以make編譯通過的caffe 這個過程在第一篇blog中已經寫出 和乙個帶有center loss層的caffe face 可以直接在github上clone下來 caffe face git clone git新增原因 1,在分類問題上,center loss可以...
在 DataGridView中新增乙個統計行的技巧
dim mtalbe as new datatable mtalbe mbl.getlist pstrsql tables 0 dim dr as datarow mtalbe.newrow dr.item 0 mtalbe.rows.count dr.item 9 mtalbe.compute s...
在caffe中新增新的Layer
參考github上面的答案 here s roughly the process i follow.大致過程翻譯 然後在對應的hpp標頭檔案中新增該層的類的定義。包括內聯實現type和 blob 方法指定blob的數字,如果你只是實現cpu部分的 則忽略 gpu的宣告 2.實現你要新增的層 應該指的...