原版caffe不支持多標籤,會報錯,如下:
注:這裏讀取數據的method是ImageData,即 type:ImageData
此方法直接從txt中獲取圖片路徑和label,進行讀取,txt如下所示:
——————————————————————–正文————————————————————-
需要更改兩個文件分別是
第一: caffe-master/include/caffe/layers 下的 image_data_layer.hpp
第二:caffe-master/src/caffe/layers 下的image_data_layer.cpp
第一步: image_data_layer.hpp
頭文件 image_data_layer.hpp,改動較少,僅一行;
將:
vector<std::pair<std::string, int> > lines_;
改成:
vector<std:pair<std::string, vector<float>>> lines_;
原本label是用int類型,但我的任務是迴歸任務,因此修改爲vector
第二步: image_data_layer.cpp
改動有三處,分別是
1. 讀取label;
2. label_shape;
3. top_shape
1.讀取label
原版label定義爲整型 ,並且只有一個label值,原版label讀取是這樣的:
第42行起
int label;
while (std::getline(infile, line)) {
pos = line.find_last_of(' ');
label = atoi(line.substr(pos + 1).c_str());
lines_.push_back(std::make_pair(line.substr(0, pos), label));
}
infile就是txt文件,line就是txt當中的一行,pos爲了尋找標籤的位置,lines_存儲讀取的txt數據
從42行開始更改,更改爲如下:
int pos; // int pos ;
int label_dim = 0 ;
bool gfirst = true;
while (std::getline(infile, line)) {
if(line.find_last_of(' ')==line.size()-2) line.erase(line.find_last_not_of(' ')-1);
pos = line.find_first_of(' ');
string img_path = line.substr(0, pos);
int p0 = pos + 1;
vector<float> label_vec;
while (pos != -1){
pos = line.find_first_of(' ', p0);
float v = atof(line.substr(p0, pos).c_str());
label_vec.push_back(v);
p0 = pos + 1;
}
if (gfirst){
label_dim = label_vec.size();
gfirst = false;
LOG(INFO) << "label dim: " << label_dim;
}
CHECK_EQ(label_vec.size(), label_dim) << "label dim not match in: " << lines_.size()<<", "<<lines_[lines_.size()-1].first;
lines_.push_back(std::make_pair(img_path, label_vec));
}
label不再是int類型,而定義爲vector<float>
類型 ,並在 while(pos!=-1)裏面循環讀取
2.label_shape
在94行開始,原版是這樣的
vector<int> label_shape(1, batch_size);
top[1]->Reshape(label_shape);
改爲
vector<int> label_shape(2, batch_size);
label_shape[1] = label_dim;
top[1]->Reshape(label_shape);
3. top_shape
在134行,原版是這樣
// Reshape batch according to the batch_size.
top_shape[0] = batch_size;
batch->data_.Reshape(top_shape);
修改爲
// Reshape batch according to the batch_size.
top_shape[0] = batch_size;
batch->data_.Reshape(top_shape);///////////////////////////////////////////////
vector<int> top_shape1(4);
top_shape1[0] = batch_size;
top_shape1[1] = lines_[0].second.size();
top_shape1[2] = 1;
top_shape1[3] = 1;
batch->data_.Reshape(top_shape);
重新 make 就可以使用多標籤輸入了;
prototxt中的data_layer是這樣的:
image_data_layer.hpp
image_data_layer.cpp
上傳到了:
http://download.csdn.net/download/u011995719/10235806