2. 修改數據層方法函數
3. 修改convert_imageset.cpp測試
vector<int> label_shape(batch_size, datum.label_size())
vector<int> label_shape(datum.label_size());
label_shape[0] = batch_size;
label_shape[1] = datum.label_size();
caffe 自己並不支持 多類標的輸入, 該框架主要用於解決圖片分類的問題,而目前,兩個重要的問題須要多標籤的輸入:
多任務學習(multi-task)和多標籤分類(multi-label),本文針對這兩個問題,實現了多標籤的輸入
目前,網上流行的多標籤輸入方法主要有如下四種:
1. 最簡單,使用mxnet,它自己支持了多標籤分類的問題,所以也自帶了多標籤的輸入
2. 用HDF5 + Slice Layer的方法完成,這種方法實現上沒有什麼難度,可是當數據量很大時,HDF5的存儲方式會產生數十倍於圖片的硬盤消耗,並且生成的過程也很是緩慢,本人一開始就主要使用這種方法,每每事倍功半
3. 用兩個data的輸入(兩個LMDB),一個只輸出圖片,一個只輸出標籤,這種方法相對前面兩種要難一些,不過應該效果也不錯
4. 直接修改caffe的網絡使其知足多標籤的輸入,
爲了方便之後的實驗,本人實現了這種方法
方法描述:注意到caffe的大多數數據轉換都是從./.build_release/tools/convert_imageset 這種方法開始的,所以,從convert_iamgeset開始入手應該是正確的選擇,經過跟蹤數據的輸入,依次修改了convert_imageset.cpp、io.hpp、 io.cpp、data_layers.hpp、caffe.proto、data_layer.cpp、image_data_layer.cpp、memory_data_layer.cpp等。由於本次是工程須要,所以我直接在py-faster-rcnn的caffe上進行修改
主要方法:
(該博客上全部圖片,左邊是修改後的,右邊是原有的)
1. 修改convert_imageset:lines是讀入的信息,包括圖片路徑和label,這裏改爲vector以支持多標籤輸入
2. 修改io.hpp:
下圖裏面,主要就是各類label改成vector
3. 同理修改io.cpp:主要修改ReadImageToDatum和ReadFileToDatum兩個函數,主要是set_label要逐個set進去
4. 修改caffe.proto,主要須要知足多標籤輸入,以及增長一些輸入網絡層的參數
5. 修改data_layer.cpp,實現Data這種網絡層類型的多標籤輸入,主要修改DataLayerSetup和load_batch兩個函數
6. 修改data_layer.hpp,主要是修改部分網絡的參數,增長標籤數量的變量等
7. 修改image_data_layer.cpp
8. 修改memory_data_layer.cpp
至此,完成全部修改,編譯以後進行測試:
從實驗結果能夠看出,輸入的標籤和train.txt的一致。
總結:本文經過修改caffe的內部代碼,實現了caffe的多標籤輸入,
主要實現了DataLayer、ImageDataLayer、MemoryDataLayer三種輸入層,可是須要注意,本人僅在DataLayer和ImageDataLayer下進行過測試,未對MemoryDataLayer或其餘的輸入類型進行測試
最後,感謝實驗室的大神師兄lxionghao,在實現過程當中,本人主要經過不斷編譯定位錯誤逐個修改以及借鑑他的修改方法完成任務。
下面貼出他的blog,比較有借鑑價值:
講解:
/content/8782995.html
工程:
https://gitcafe.com/lxiongh/Caffe_for_Multi-label 本人工程將稍後上傳到github,以後再公佈給你們