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,比較有借鑒價值:
講解:http://blog.csdn.net/baobei0112/article/details/47606559
工程:https://gitcafe.com/lxiongh/Caffe_for_Multi-label
本人工程將稍後上傳到github,之後再公布給大家