原版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