為 Caffe 新增新的 DataLayer

2021-07-15 12:50:28 字數 2218 閱讀 5415

復現 deepid 用 caffe 實現人臉識別時,網路的訓練的框架往往是這樣的:

就是說 image list 中的資料是按對整理好的,類內 (intra class) 類間 (inter class) 資料交替排列。這樣就可以直接利用 imagedatalayer 獲得乙個個均勻的 batch。現在只要對 loss layer 簡單做一下修改,網路已經可以正常訓練了,相當簡單。

但簡單的代價也相當明顯:

所以如果能把資料整理這一步整合到 datalayer 中,將會得到更大程度的簡化。而且可以額外附加一些功能,比如隨機抽取類內類間資料;類內資料抽取區別較大的組合,類間資料則抽取區別較小的組合,如果計算速度允許的話。

於是新的訓練框架應該是下面這樣的,datalayer 的名字都取好了,叫 tripletdatalayer!

tripletdatalayer 會在每次迭代過程中抽取乙個 batch 的資料,batch 中的資料等分為 idenities a, idenities p, idenities n 三個部分, 分別代表 facenet 1 中提出的 anchor, positive, negative。anchor 與 positive 是類內組合,anchor 與 negative 是類間組合,後面都用這種方式表示。可以看到由於 batch 內的資料是有序的,對應的 loss layer 就不需要 label 資訊了(softmax loss 除外)。

為 caffe 新增新資料層的步驟 ( 以 tripletdatalayer 為例 ) 如下:

在 src/caffe/proto/caffe.proto 中定義相關的引數

在 src/caffe/layers/ 目錄下新增 triplet_data_layer.cpp

在 include/caffe/layers/ 目錄下新增 triplet_data_layer.hpp

在 src/caffe/test 目錄下新增 test_triplet_data_layer.cpp (可選)

第 2, 3 步就是實現 tripletdatalayer 類,最為重要。然後把需要定製的引數新增到 caffe.proto 檔案中。準確地完成這兩步的話,新增 datalayer 層的工作就算完成了。如果不能確定,最好在 src/caffe/test 目錄下寫乙個測試用例。

我的實現原則是對 caffe 原始碼做最少的修改。縱觀現有的 datalayer 最佳參考的是 imagedatalayer 。理所當然地應該分析一下它的實現,下面是我畫的乙個非常粗糙的 imagedatalayer 類圖:

可以看到,imagedatalayer 與普通的 layer 不同,它不需要實現 .cu 檔案。因為 gpu 的操作已經在高層的類中實現了,同樣資料預取操作 (經典的生產者消費者問題,每次預取 3 個 batch) 也已在高層類中實現。所以我們只要重寫 load_batch() 函式即可。

在 imagedataparameter 的基礎上修改。雖然結構名的選擇是自由的,但最好按 caffe 的風格來寫,即結構名與類名對應。有關 protobuf 的語法請自行 google。

message tripletdataparameter 

同樣,為了統一性引數名照樣與類名相關。應注意標識號不能與前面的字段重複。

message layerparameter
然後在 tripletdatalayer 類中就可以讀取這些引數了 ( caffe.pb.cc 與 caffe.pb.h 會在 caffe 編譯過程中自動編譯出來 )。比如我們想讀取配置檔案中的 batch_size 引數,可以這樣做:

int batch_size_ = this->layer_param_.triplet_data_param().batch_size();
待續。。。

caffe下新增新的loss層

caffe的使用當中,最神秘的就是caffe的原始碼,而我們要做一些創新點的話,基本上都是要修改caffe的原始碼。小魚和大家分享怎麼在caffe下新增新的層。比如要新增乙個新的loss函式 euclidean loss norm layer 1 需要編寫相應的euclidean loss norm...

在caffe中新增新的Layer

參考github上面的答案 here s roughly the process i follow.大致過程翻譯 然後在對應的hpp標頭檔案中新增該層的類的定義。包括內聯實現type和 blob 方法指定blob的數字,如果你只是實現cpu部分的 則忽略 gpu的宣告 2.實現你要新增的層 應該指的...

在caffe中新增新的Layer

參考github上面的答案 here s roughly the process i follow.大致過程翻譯 然後在對應的hpp標頭檔案中新增該層的類的定義。包括內聯實現type和 blob 方法指定blob的數字,如果你只是實現cpu部分的 則忽略 gpu的宣告 2.實現你要新增的層 應該指的...