caffe多任务学习之多标签分类

转载 2018年04月16日 09:46:17
最近在参加一个识别的竞赛,项目里涉及了许多类别的分类,原本打算一个大的类别训练一个分类模型,但是这样会比较麻烦,对于同一图片的分类会重复计算分类网络中的卷积层,浪费计算时间和效率。后来发现现在深度学习中的多任务学习可以实现多标签分类,所有的类别只需要训练一个分类模型就行,其不同属性的类别之间是共享卷积层的。我所有的项目开发都是基于caffe框架的,默认的,Caffe中的Data层只支持单维标签,不支持多标签分类。我也是参考了大牛的博客修改了caffe里面的源码,使得caffe支持多标签分类。下面介绍怎么在caffe中修改源码支持多标签,包括训练和测试过程的修改。
  Caffe源码修改:
  需要修改Caffe中的convert_imageset.cpp以支持多标签,convert_imageset.cpp是在caffe的根目录下的tools文件下。我是直接下载了修改后的convert_imageset.cpp替换了我原来的convert_imageset.cpp。然后需要重新编译caffe,进入caffe目录下,输入指令:
  make clean
  make –j4
  make pycaffe
好了,到了这里如果没有出错caffe就可以支持多标签分类了,接下来就是根据自己的数据和多标签类别数目训练网络模型。
注:基于好多人找我要convert_imageset.cpp,我把它上传了:
http://download.csdn.net/detail/xjz18298268521/9776275
需要的可以自己去下载。
 修改代码如下:
 std::ifstream infile(argv[2]);
    std::vector<std::pair<std::string, std::vector<float>> > lines;
    std::string filename;
    std::string label_count_string = argv[5];
    int label_count = std::atoi(label_count_string.c_str());
    std::vector<float> label(label_count);
    while (infile >> filename)
    {
        for (int i = 0; i < label_count;i++)
            infile >> label[i];
        lines.push_back(std::make_pair(filename, label));
    }
    // Create new DB
    scoped_ptr<db::DB> db_image(db::GetDB(FLAGS_backend));
    scoped_ptr<db::DB> db_label(db::GetDB(FLAGS_backend));
    db_image->Open(argv[3], db::NEW);
    db_label->Open(argv[4], db::NEW);
    scoped_ptr<db::Transaction> txn_image(db_image->NewTransaction());
scoped_ptr<db::Transaction> txn_label(db_label->NewTransaction());
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

训练模型:
  上面我们就有了多任务的深度学习的基础部分数据输入。为了向上兼容Caffe框架,我也是参考了大牛的博客,摒弃了部分开源实现增加Data层标签维度选项并修改Data层代码的做法,直接使用两个Data层将数据读入,即分别读入数据和多维标签。接下来详细介绍训练所需要做的步骤以及和修改。
 

1. Lmdb的数据制作
   由于篇幅的原因,我只贴了部分主要的代码图,注意下图标红的部分,第一个是你多标签所需要的类别数目,第二个是一些数据的路径。
  由于现在为了支持多标签,把数据和标签分开了,以前的单标签在data层数据和标签在一起的对应的(自己的理解)。所以第三和第四初标红的是test和train最后用于训练的lmdb数据和对应多维标签。这制作lmdb脚本文件我会放在我的博客资源上:
  http://download.csdn.net/detail/xjz18298268521/9708564
  你们可以根据自己的需求下载后自己修改,执行脚本文件后,相对应的路径下会生成对应的四个lmdb数据文件。到这里lmdb的数据制作完毕,后面的均值文件的制作和原来的是一样的。
  这里写图片描述
2.修改训练网络模型train_val.prototxt

#训练数据层
name: "CaffeNet"
layer {
  name: "data"
  type: "Data"
  top: "data"  #原来的是两层top
  include {
    phase: TRAIN
  }
  transform_param {
    mirror: true
    crop_size: 227
    mean_file: "/home/xjz/multiple-caffe/caffe-master/examples/multiple-lable/caffenet/mean.binaryproto"
  }
  data_param {
    source: "/home/xjz/multiple-caffe/caffe-master/examples/multiple-lable/caffenet/ten_classes_train_lmdb"
    batch_size: 128
    backend: LMDB
  }
}
#训练数据标签层
layer {
  name: "data"
  type: "Data"
  top: "label"
  include {
    phase: TRAIN
  }
  data_param {
    source: "/home/xjz/multiple-caffe/caffe-master/examples/multiple-lable/caffenet/ten_classes_train_label_lmdb"
    batch_size: 128
    backend: LMDB
  }
}
#测试数据层
layer {
  name: "data"
  type: "Data"
  top: "data"
  include {
    phase: TEST
  }
  transform_param {
    mirror: false
    crop_size: 227
    mean_file: "/home/xjz/multiple-caffe/caffe-master/examples/multiple-lable/caffenet/mean.binaryproto"
  }
  data_param {
    source: "/home/xjz/multiple-caffe/caffe-master/examples/multiple-lable/caffenet/ten_classes_val_lmdb"
    batch_size: 100
    backend: LMDB
  }
}
#测试数据标签层
layer {
  name: "data"
  type: "Data"
  top: "label"
  include {
    phase: TEST
  }
  data_param {
    source: "/home/xjz/multiple-caffe/caffe-master/examples/multiple-lable/caffenet/ten_classes_val_label_lmdb"
    batch_size: 100
    backend: LMDB
  }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67

  修改完网络模型的data层,后面需要将标签数据库中的内容进行切分,拆分成各个属性的标签,需要添加Slice层,Slice层是将一个输入层根据切割指标给定的维度(现在只有num和channel)切割成多个输出层,如下图所示。有几类标签就定义几类top并命名不同,用于连接最后的accuracy层。对于slice层的参数:

  • slice_dim: 目标维度,0 for num and 1for channel,一般选1;
  • slice_point:指定选定维数的索引(索引的数量必须等于blob数量减去一),我一共是4,所以减一为3。
               这里写图片描述
    3.最后的损失函数的设计
       以前单标签的时候,只需要设计一个损失函数,现在是多标签分类需要设计多个损失函数层,使得每一大类别对应一个损失函数层,下图是一个类别的损失函数层和对应的test层:
    对于Accuracy层中的两个bottom:第一个需要连接对应的全连接层,第二个需要连接前面用slice层切割对应的标签层。
      对于softmaxwithloss层的两个bottom:第一个需要连接对应的全连接层,第二个需要连接前面用slice层切割对应的标签层。Loss_weight:需要填写这个损失函数的损失值在最终总的损失函数值中所占的权重值,一般的,建议所有任务的权重值相加为1,如果这个数值不设置,可能会导致网络收敛不稳定,这是因为多任务学习中对不同任务的梯度进行累加,导致梯度过大,甚至可能引发参数溢出错误导致网络训练失败。
             这里写图片描述
      这里还有一个问题,就是以前单标签的时候,最后一层的全连接层fc8层的out_num是固定的,大小是根据单标签分类的类别数目来定的,而现在多标签中的每一个标签的类别属性大小是不同一的。所以这里在每一标签对应的损失函数前添加一个全连接层,对应的输出out_num大小等于对应标签的类别数目。添加的所有全连接层都连接到原来的第二个全连接层,即fc7层,如下图所示,到这里训练基本的都准备完毕,后面的训练的步骤和原来单标签的训练基本是一样的,接下来就可以训练了。
              这里写图片描述
    测试过程
      修改deploy.prototxt文件,前面的网络层是不需要修改的,只需要修改对应的最后一层全连接层和损失函数层,修改的方式和前面训练trian_val.prototxt的是一样的,每一个标签类别需要一个属于自己的全连接层和损失函数层,如下图所示:
              这里写图片描述

Skinning Your Application

Skinning Your Application Larry RoofTonked.comDecember 11, 2001Knock, knock.Whos there?Angry develop...
  • sonicdater
  • sonicdater
  • 2002-02-18 12:08:00
  • 508

几种分类问题的区别:多类分类,多标签分类,多示例学习,多任务学习

多类分类(Multiclass Classification) 一个样本属于且只属于多个类中的一个,一个样本只能属于一个类,不同类之间是互斥的。 典型方法: One-vs-All or One-...
  • demon7639
  • demon7639
  • 2014-12-08 15:49:21
  • 2693

caffe 实现多标签输入(multilabel、multitask)

caffe 本身并不支持 多类标的输入, 该框架主要用于解决图片分类的问题,而目前,两个重要的问题需要多标签的输入:多任务学习(multi-task)和多标签分类(multi-label),本文针对这...
  • hubin232
  • hubin232
  • 2016-03-23 08:26:32
  • 19485

多任务深度学习(MultiTask Learning)

多任务学习给出多个监督信息(标签),利用任务之间的相关性互相促进。案例1-人脸识别香港中文大学汤晓鸥组发表在NIPS14的论文《Deep Learning Face Representation by...
  • u012938704
  • u012938704
  • 2016-09-29 16:48:10
  • 9368

caffe2实现多任务学习

caffe2实现多任务
  • chenriwei2
  • chenriwei2
  • 2017-07-27 01:24:49
  • 1847

多任务学习有用的资料

条件:有n个任务t=1,2,...,n,每个任务给予m个样本:(xt1,yt1),...,(xtm,ytm)。 目的:得出一个X到Y的函数ft,t=1,2,...,n。 当这些任务是相关的...
  • u011792913
  • u011792913
  • 2017-07-04 21:13:40
  • 295

Learning中的多类分类,多标签分类,多示例学习,多任务学习,

 多类分类(Multiclass Classification) 一个样本属于且只属于多个类中的一个,一个样本只能属于一个类,不同类之间是互斥的。 典型方法: One-vs-All or ...
  • langb2014
  • langb2014
  • 2016-10-31 15:16:33
  • 1772

深度学习之多任务训练

最近,做基于caffe的多任务学习,所以写下这篇博客如何修改网络使其支持多任务学习。    一般地,一个卷积神经网络只是对某一个特定的目标进行学习训练。其实,也可以使一个网络并行地对两个或两个以上的...
  • xjc864588399
  • xjc864588399
  • 2016-12-28 17:29:00
  • 2448

修改caffe源码满足多标签输入--多标签lmdb

近期因项目需要,要完成一个多标签的回归任务,hdf5格式在图像预处理方面确实不方便,于是,看了网上几篇关于修改caffe源码使得输入多标签的,五花八门,一个是修改完之后影响了很多的模块的使用,编译出好...
  • wuzhiyang95_xiamen
  • wuzhiyang95_xiamen
  • 2016-12-08 16:20:59
  • 1161

多任务学习代码

转载自:多任务学习代码 Convex Multi-task Feature Learning 是一篇比较经典的文章,代码点击这里可以下载。 还有一篇是Multi-Task Feature Learn...
  • alwaystry
  • alwaystry
  • 2016-09-06 16:17:55
  • 577
收藏助手
不良信息举报
您举报文章:caffe多任务学习之多标签分类
举报原因:
原因补充:

(最多只允许输入30个字)