说明:

Caffe自带的图像转LMDB接口只支持单label,对于多label的任务,可以使用HDF5的格式,也可以通过修改caffe代码来实现.本篇文章介绍怎么通过修改DataLayer来实现带Multilabel的lmdb格式数据输入的分类任务.

--- 本文参考自 :


1. 总体介绍

共修改5个文件:

  1. $CAFFE_ROOT/src/caffe/proto/caffe.proto
  2. $CAFFE_ROOT/src/caffe/layers/data_layer.cpp
  3. $CAFFE_ROOT/src/caffe/util/io.cpp
  4. $CAFFE_ROOT/include/caffe/util/io.hpp
  5. $CAFFE_ROOT/tools/convert_imageset.cpp

其中$CAFFE_ROOT为caffe根目录,即git clone 目录, 如图:

修改完成后,执行:

make clean
make all –j8

-------______

具体的文件修改内容如下:

2.1 caffe.proto

vim /src/caffe/proto/caffe.proto

在message Datum { }里中添加一行代码,即添加一个labels,是repeated类型的,以便接受多标签数据集。

 repeated float labels = 8;

message Datum {
optional int32 channels = 1;
optional int32 height = 2;
optional int32 width = 3;
// the actual image data, in bytes
optional bytes data = 4;
optional int32 label = 5;
// Optionally, the datum could also hold float data.
repeated float float_data = 6;
// If true data contains an encoded image that need to be decoded
optional bool encoded = 7 [default = false];
//////////////////////////////////
repeated float labels = 8;
//////////////////////////////////
}

2.2 data_layer.cpp (两处)

// label
/*
if (this->output_labels_) {
vector<int> label_shape(1, batch_size);
top[1]->Reshape(label_shape);
for (int i = 0; i < this->prefetch_.size(); ++i) {
this->prefetch_[i]->label_.Reshape(label_shape);
}
}
*/
/////////////////////////////////////////////////
if (this->output_labels_){
top[1]->Reshape(batch_size, 4, 1, 1);
for (int i = 0; i < this->prefetch_.size(); ++i) {
this->prefetch_[i]->label_.Reshape(batch_size, 4, 1, 1);
}
}
//////////////////////////////////////////////////
// Copy label.
/*
if (this->output_labels_) {
Dtype* top_label = batch->label_.mutable_cpu_data();
top_label[item_id] = datum.label();
}
*/
///////////////////////////////////////////////
if (this->output_labels_) {
Dtype* top_label = batch->label_.mutable_cpu_data();
for (int i = 0; i < 4; i++)
top_label[item_id * 4 + i] = datum.labels(i);
}
///////////////////////////////////////////////

2.3 io.cpp(两处)

修改两个函数,替换成下面修改后的代码即可,

vim /src/caffe/util/io.cpp

ReadImageToDatum()

bool ReadImageToDatum(const string& filename, const vector<float> label,
const int height, const int width, const bool is_color,
const std::string & encoding, Datum* datum) {
cv::Mat cv_img = ReadImageToCVMat(filename, height, width, is_color);
if (cv_img.data) {
if (encoding.size()) {
if ( (cv_img.channels() == 3) == is_color && !height && !width &&
matchExt(filename, encoding) )
return ReadFileToDatum(filename, label, datum);
std::vector<uchar> buf;
cv::imencode("."+encoding, cv_img, buf);
datum->set_data(std::string(reinterpret_cast<char*>(&buf[0]),
buf.size())); datum->clear_labels();
for (int i = 0; i < label.size(); i++){
datum->add_labels(label[i]);
}
datum->set_encoded(true);
return true;
}
CVMatToDatum(cv_img, datum); datum->clear_labels();
for (int i = 0; i < label.size(); i++){
datum->add_labels(label[i]);
}
return true;
} else {
return false;
}
}

ReadFileToDatum()

//////////////////////////////////////////////////////////////////////
bool ReadFileToDatum(const string& filename, const vector<float> label,
Datum* datum) {
std::streampos size; fstream file(filename.c_str(), ios::in|ios::binary|ios::ate);
if (file.is_open()) {
size = file.tellg();
std::string buffer(size, ' ');
file.seekg(0, ios::beg);
file.read(&buffer[0], size);
file.close();
datum->set_data(buffer); datum->clear_labels();
for (int i = 0; i < label.size(); i++){
datum->add_labels(label[i]);
}
datum->set_encoded(true);
return true;
} else {
return false;
}
}

2.4 io.hpp

在其中新加入/////// ..... ///////内的两个成员函数声明,不删除原来的任何代码,下面的前两个函数声明是原来文件中就有的,可以看到,原来代码中的label参数是int类型,只能处理单标签字符;新增的两个成员函数就是参考上面两个函数,将const int label参数改成了std::vector labels,以接受多标签字符。

bool ReadImageToDatum(const string& filename, const int label,
const int height, const int width, const bool is_color,
const std::string & encoding, Datum* datum);
bool ReadFileToDatum(const string& filename, const int label, Datum* datum);
//////////////////////////////////////////
bool ReadImageToDatum(const string& filename, std::vector<float> labels,
const int height, const int width, const bool is_color,
const std::string & encoding, Datum* datum);
bool ReadFileLabelsToDatum(const string& filename, std::vector<float> labels,
Datum* datum);
///////////////////////////////////

2.5 convert_imageset.cpp

/*
std::ifstream infile(argv[2]);
std::vector<std::pair<std::string, int> > lines;
std::string line;
size_t pos;
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));
}
*/
////////////////////////////
std::ifstream infile(argv[2]);
std::vector<std::pair<std::string, vector<float> > > lines;
std::string filename;
vector<float> labels(4);
while (infile >> filename >> labels[0] >> labels[1] >> labels[2] >> labels[3]){
lines.push_back(std::make_pair(filename, labels));
}
///////////////////////////

多标签caffe重新编译的更多相关文章

  1. 深度学习框架Caffe的编译安装

    深度学习框架caffe特点,富有表达性.快速.模块化.下面介绍caffe如何在Ubuntu上编译安装. 1. 前提条件 安装依赖的软件包: CUDA 用来使用GPU模式计算. 建议使用 7.0 以上最 ...

  2. 64位win10+cuda8.0+vs2013+cuDNN V5下Caffe的编译安装教程并配置matlab2014a 接口

    一.需要安装的软件 1)vs2013,我是在http://www.52pojie.cn/thread-492326-1-1.html这个网址安装的.我之前用的是vs2012,按照网上的配置教程会爆各种 ...

  3. caffe windows编译

    MicroSoft维护的caffe已经作为官方的caffe分支了,编译方式也改了,刚好最近重装了一次caffe windows, 记录一下里面的坑 https://github.com/BVLC/ca ...

  4. caffe make 编译

    其实嘛,出现这个的原因在于,已经编译过啦,没有任何改动,那还烦劳编译啥呢. 那Linux又是如何知道已经编译过了呢? 那就要看makefile的规则啦.makefile的规则是所想产生的文件需要依赖很 ...

  5. Caffe: gflag编译出现问题汇总

    1. 使用Unicode字符集: 出现问题 E:\CodeBase\ML\Caffe\ThirdPartySrc\gflags-master\src\gflags.cc(1340): error C2 ...

  6. caffe安装编译问题-ImportError: No module named google.protobuf.internal

    问题描述 ~/Downloads/caffe$ python Python (default, Dec , ::) [GCC ] on linux2 Type "help", &q ...

  7. caffe安装编译问题-ImportError: No module named skimage.io

    问题描述 >>> import caffe Traceback (most recent call last): File , in <module> File , in ...

  8. caffe安装编译问题-ImportError: libopencv_core.so.3.4: cannot open shared object file: No such file or directory

    问题描述 >>> import caffe Traceback (most recent call last): File , in <module> File , in ...

  9. caffe安装编译问题-ImportError: No module named caffe

    问题描述 ~/Downloads/caffe$ python Python (default, Dec , ::) [GCC ] on linux2 Type "help", &q ...

随机推荐

  1. MyISAM与InnoDB的区别是什么?

    1. 存储结构 MyISAM:每个MyISAM在磁盘上存储成三个文件.第一个文件的名字以表的名字开始,扩展名指出文件类型..frm文件存储表定义.数据文件的扩展名为.MYD (MYData).索引文件 ...

  2. Intellij IDEA 4种配置热部署的方法【转】【补】

    热加载 热加载可以使代码修改后无须重启服务器,就可以加载更改的代码.(其实分java和非java代码,本处可以让java代码立即生效且不重启服务) 第1种:修改服务器配置,使得IDEA窗口失去焦点时, ...

  3. 34 springboot项目之间依赖导致bean 无法加载问题

    方式一(OK) 模块A引入模块B ,但是模块B的bean一直注入不进来 原因: A模块的Application是在com.xx.xx包下,那么势必只能扫描到这个包下的bean, B模块的Applica ...

  4. Repeater取不到服务端控件

    <td>      <asp:Button ID="Button1" runat="server" Text="查看" O ...

  5. Ubuntu18.04应用程序安装集锦

    整理网上的资源: Python Web开发工具箱 ubuntu美化及超NB的zsh配置 api文档查询工具:zeal,dash(收费)

  6. centos6.5 配置静态IP

    1.修改网卡配置 编辑:vi /etc/sysconfig/network-scripts/ifcfg-eth0 DEVICE=eth0 BOOTPROTO=static HWADDR=08:00:2 ...

  7. python复习1

    比如常用的数学常数π就是一个常量.在Python中,通常用全部大写的变量名表示常量: Python支持多种数据类型,在计算机内部,可以把任何数据都看成一个“对象”,而变量就是在程序中用来指向这些数据对 ...

  8. 论文翻译:BinaryConnect: Training Deep Neural Networks with binary weights during propagations

    目录 摘要 1.引言 2.BinaryConnect 2.1 +1 or -1 2.2确定性与随机性二值化 2.3 Propagations vs updates 2.4 Clipping 2.5 A ...

  9. LeetCode第十九题-链表节点的删除

    Remove Nth Node From End of List 问题简介;给定链表,从链表末尾删除第n个节点并返回其头部 例: 给定链表:1-> 2-> 3-> 4-> 5, ...

  10. Django学习笔记(二)视图函数

    一.url映射 1.为什么回去urls.py文件中找映射? 在‘settings.py’文件中配置了‘ROOT_URLCONF’为‘urls.py’.所有的django回去urls.py中寻找. 2. ...