Caffe(9)--实现多label输入

本文介绍如何在Caffe中实现多标签训练,包括修改ImageDataLayer支持多标签、创建多标签LMDB及使用不同数据格式的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

方法1:把图像和label分开,各自做成lmdb,最后把label的lmdb用slice层分开
https://blog.youkuaiyun.com/u013010889/article/details/53098346

方法2:使用hdf5
https://note.youdao.com/web/#/file/879598B7BE5D4B6AAFDE5FD48C25B834/note/WEB0f0ea12658b06e9e55f23e99d68187fc/
使用脚本create_caffeyolo_lmdb_and_hdf5.py

方法3:修改ImageDataLayer
ImageDataLayer是直接读取原图进行分类,只能在train.txt中放置单label,需要修改ImageataLayer的代码来实现多label。
https://blog.youkuaiyun.com/u013010889/article/details/54614067

方法4:修改lmdb为支持多标签
目前Caffe源码与链接中相比变动比较大,不太好改了
https://blog.youkuaiyun.com/sinat_14916279/article/details/56489601?locationNum=10&fps=1

方法5:使用caffe-ssd中的脚本create_annoset.py


方法3实现

ImageDataLayer格式如下:

name: "CaptchaNet"
layer {
  name: "data"
  type: "ImageData"
  top: "data"
  top: "label"
  include {
    phase: TRAIN
  }
  transform_param {
    mirror: false 
    mean_value: 104
    mean_value: 117
    mean_value: 123   
  }
  image_data_param {
    source: "D:/BU5/caffe-windows/examples/captcha/captcha_train.txt"
    root_folder: "D:/BU5/caffe-windows/examples/captcha/captcha_train/"
    batch_size: 8
    shuffle: false
    new_height: 227 
    new_width : 227
    label_dim: 4
  }
}

修改Caffe源码
主要涉及3个文件

caffe/src/caffe/proto/caffe.proto
caffe/include/caffe/layers/image_data_layer.hpp
caffe/src/caffe/layers/image_data_layer.cpp

1、修改caffe.proto
约788行,定位到message ImageDataParameter
添加一个参数

optional uint32 label_dim = 13 [default = 1]; // 多label

2、修改image_data_layer.hpp

// string对应那个train.txt中的图片名称,in对应label,我们把int改为int*,实现多label
// vector<std::pair<std::string, int> > lines_;
vector<std::pair<std::string, int *> > lines_;

3、修改image_data_layer.cpp
(1)修改DataLayerSetUp

/*
  std::ifstream infile(source.c_str());
  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));
  }
  */

  // 多label修改后
  // 加载图片名称和label
  std::ifstream infile(source.c_str());
  string filename;
  // 获取label的种类
  int label_dim = this->layer_param_.image_data_param().label_dim();
  // 注意这里默认每个label直接以空格隔开,每个图片名称及其label占一行
  while (infile >> filename) {
	  int* labels = new int[label_dim];
	  for (int i = 0; i < label_dim; ++i) {
		  infile >> labels[i];
	  }
	  lines_.push_back(std::make_pair(filename, labels));
  }

(2)修改输出label

// label
  /*
  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);
  }
  */
  // 修改后
  vector<int> label_shape(2);
  label_shape[0] = batch_size;
  label_shape[1] = label_dim;
  top[1]->Reshape(label_shape); // label的输出shape batch_size*label_dim
  for (int i = 0; i < this->prefetch_.size(); ++i) {
	this->prefetch_[i]->label_.Reshape(label_shape);
  }

(3)修改load_batch
在函数一开始先获取下label_dim参数,添加下面语句:

int label_dim = this->layer_param_.image_data_param().label_dim();

然后修改:

// 预取label
// prefetch_label[item_id] = lines_[lines_id_].second;
// 改为
for (int i = 0; i < label_dim; ++i) {
 // lines_[lines_id_].second就是最开始改为的int*,多label
	prefetch_label[item_id * label_dim + i] = lines_[lines_id_].second[i];
}

4、3个文件修改完后,重新编译
5、修改AlexNet,进行验证码识别,验证Caffe的多标签输入
https://blog.youkuaiyun.com/lwplwf/article/details/82684933

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值