caffe层解读系列——slice和concat实现MultiTask

版权声明:本文为博主原创文章,转载请注明出处 https://blog.csdn.net/shuzfan/article/details/54565776

最近一段时间MultiTask网络比较流行,比如做人脸检测的时候,一个网络完成(人脸和非人脸)二分类任务的同时也要进行boudingbox回归或者人脸关键点回归。

以人脸检测MTCNN为例,一个网络包含三个任务。训练的时候,一个batch中的图片,一部分用于二分类、一部分用于boundingbox 回归,一部分用于关键点回归。这种较复杂的样本组合完全可以通过slice和concat层来快速实现。

———————— Concat —————————

concat层实现输入数据的拼接。
该层有两个相同作用的参数:

message ConcatParameter {
  //指定拼接的维度,默认为1即以channel通道进行拼接;支持负索引,即-1表示最后一个维度
  optional int32 axis = 2 [default = 1];

  // 以后会被弃用,作用同axis一样,但不能指定为负数
  optional uint32 concat_dim = 1 [default = 1];
}

caffe中数据通常为4个维度,即 \(num\times channels \times height \times width \),因此默认值1表示channels通道进行拼接。

使用方法如下

layer {
  name: "data_all"
  type: "Concat"
  bottom: "data_classfier"
  bottom: "data_boundingbox"
  bottom: "data_facialpoints"
  top: "data_all"
  concat_param {
    axis: 0
  }
}

除了拼接维度外的其它维度都必须相等。比如上面,输入图像均为 \(24\times 24\times 3\),用于分类的有150张图片,用于boundingbox回归的有50张,用于关键点回归的也有50张,则最后拼接的结果就是 \((150+50+50)\times 3\times 24 \times 24\)

————————— Slice —————————

既然有合并,那么相应的也有拆分。slice层共有三个参数:

message SliceParameter {
  // 下面两个指定沿哪个维度进行拆分,默认拆分channels通道
  optional int32 axis = 3 [default = 1];
  optional uint32 slice_dim = 1 [default = 1];

  // 指定拆分点
  repeated uint32 slice_point = 2;
}

现在我们就要把之前concat合并的数据按照原样拆分:

layer {
  name: "data_each"
  type: "Slice"
  bottom: "data_all"
  top: "data_classfier"
  top: "data_boundingbox"
  top: "data_facialpoints"
  slice_param {
    axis: 0
    slice_point: 150
    slice_point: 200
  }
}

其中slice_point的个数必须等于top的个数减一。输入的data_all维度为 \(250\times 3\times 24 \times 24\),拆分后的3个输出的维度依次为 \(150\times 3\times 24 \times 24\), \(50\times 3\times 24 \times 24\), \(50\times 3\times 24 \times 24\)

————————— MultiTask —————————

下面直接给一张网络结构图,大家就应该知道怎么实现多数据MultiTask了。

这里写图片描述

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页