看到題目,可能有的朋友還不太理解這一篇博文主要是要幹嘛的,下面我先來舉一個簡單的例子。
先做一個簡單的假設:假設你已經看了我之前的博文:用 caffe 做迴歸(下),即使上面的假設不成立,也沒有關係。該博文主要是講解用caffe做迴歸任務的時候對data_layer.cpp的修改。此處我想讓大家關注的是,裡面用到的一個變數聲明:
int labelNum = 4; //表示標籤的數量為4
對於“強迫症”來說,在裡面寫這樣的一個聲明是很不美觀的。另外,當標籤的數量發生變化的時候(比如變成10),還需要在這裡把4修改為10,然後重新編譯caffe。這樣對於使用的人來說是很不友好的。
於是我又看到了這樣的一句代碼:
const int batch_size = this->layer_param_.data_param().batch_size();
這裡的batch_size 不就是我們的網路結構設定檔(比如:train_test.prototxt)中的data_param 中的參數嗎。
那我能不能有下面的代碼:
const int labelNum = this->layer_param_.data_param().label_num();
這樣一來,我是不是直接在原來的 train_test.prototxt 檔案中:
data_param { source: "examples/mnist/mnist_train_lmdb" batch_size: 64 backend: LMDB }
增加label_num: 4 一項,即:
data_param { source: "examples/mnist/mnist_train_lmdb" batch_size: 64 backend: LMDB label_num: 4 }
是不是就可以解決我上面遇到的問題了呢。當我需要把標籤的數量從4改為10的時候,也只需要在 train_test.prototxt 檔案中修改,並不需要開啟 data_later.cpp,也不需要重新編譯caffe。
經過一番驗證,上面的猜想是完全可行的。哈哈,說的自己好像是第一個發現一樣,其實早就有很多人這麼做~~
那麼下面我就來說一說具體的做法(其實很簡單):
要想在data_param 中添加 label_num 這個參數,需要在 src/caffe/proto/caffe.proto 檔案中對應的位置上加上對label_num 這一參數的聲明: 開啟caffe.proto 檔案,ctrl+F找到對message DataParameter 部分的定義,到這裡會發現,原來我們在train_test.prototxt的資料層中看到的batch_size mean_file crop_size 等等這些熟悉的“面孔”都是在這裡最初聲明的(到這裡似乎已經明白了什麼,對的往下看); 我們只需要在
optional uint32 prefetch = 10 [default = 4];
的後面加上:
optional uint32 label_num = 11;
就完成了對caffe.proto 的修改。 最後在重新在caffe的根目錄下重新make編譯一下caffe,就可以像上面說的那樣使用label_num了。
下面還有一些需要注意的地方: 如果定義的參數是float類型或者bool類型的,記得要將uint32改成相應的類型; 建議定義參數的時候使用小寫字母。也就是像label_num ,而不要label_Num 。我在實際使用的時候發現如果使用大寫,則在後面的train_test.prototxt中也需要用大寫,而在data_layer.cpp中使用的時候反而要用小寫函數名比如:label_num() 。貌似是這個規律~~
另外,這邊博文的思想可以使用到我的另外一篇博文中:
在 caffe 的 data_later.cpp 中做資料增強
如果在做資料增強過程中需要用到某些參數,也可以直接通過data_param 傳遞。
大概就是這樣了~