Press "Enter" to skip to content

目标检测之PVANET

本站内容均来自兴趣收集,如不慎侵害的您的相关权益,请留言告知,我们将尽快删除.谢谢.

引言

最早接触这篇文章是2016年,那时候目标检测还是以RCNN系列、YOLO V1、SSD为主,当时这篇文章标题很是吸引我,所以在那个时候就撸起袖子开干,但是一直未对它进行总结.虽然现在网上也有很多关于pvanet的文章,今天我将结合caffe中的源码来讲解这篇文章.
该网络结构是在faster-rcnn基础上改进的,它的独特之处 更多的层,更少的channel,但计算量不到采用 ResNet-101 网络的 10% ,我的显卡是TiTan,基本上可以达到15-17fps,我检测用的是c++来写的.

简介

PipeLine

它的网络结构如下(这个图片是从网上找来的,原谅我太懒),具体的处理步骤我就不啰嗦,网上一搜一大堆,而且下面的网络结构图也非常清晰

实现细节

相比与faster-rcnn,它做了哪些改进呢? 四大护法:引入改进的C.ReLu、使用Inception、使用HyperNet、引入残差连接训练更深的网络

改进的C.ReLu

  • C.ReLu简介
    普通的C.ReLu主要抓住了低层的卷积层中的一些滤波器核存在着负相关程度很高的滤波器核(如人的眼睛是对称等)特性,直接减少一半输出通道(output channels)的数量,通过简单的连接相同的输出和negation使其变成双倍,即达到原来输出的数量,这使得2倍的速度提升而没有损失精度。
    与原始的C.ReLU相比,我们增加了scaling and shifting(缩放和移动,即下图中红色区域)在concatenation(串联)之后,这允许每个channel(通道)的斜率和激活阈值与其相反的channel不同。
  • caffe中C.ReLu的层定义
    这里我只给出第一层的C.ReLu层结构定义,感兴趣的自己去看相应的prototxt文件,下面的截取的部分就是对应上图中的C.ReLu结构图
layer {
  name: "conv1_1/conv"
  type: "Convolution"
  bottom: "data"
  top: "conv1_1/conv"
  param {
    lr_mult: 0.1
    decay_mult: 0.1
  }
  convolution_param {
    num_output: 16
    bias_term: false
    weight_filler {
      type: "xavier"
    }
    pad_h: 3
    pad_w: 3
    kernel_h: 7
    kernel_w: 7
    stride_h: 2
    stride_w: 2
  }
}
layer {
  name: "conv1_1/bn"
  type: "BatchNorm"
  bottom: "conv1_1/conv"
  top: "conv1_1/conv"
  param {
    lr_mult: 0
    decay_mult: 0
  }
  param {
    lr_mult: 0
    decay_mult: 0
  }
  param {
    lr_mult: 0
    decay_mult: 0
  }
  batch_norm_param {
    use_global_stats: true
  }
}
layer {
  name: "conv1_1/neg"
  type: "Power"
  bottom: "conv1_1/conv"
  top: "conv1_1/neg"
  power_param {
    power: 1
    scale: -1.0
    shift: 0
  }
}
layer {
  name: "conv1_1/concat"
  type: "Concat"
  bottom: "conv1_1/conv"
  bottom: "conv1_1/neg"
  top: "conv1_1"
}
layer {
  name: "conv1_1/scale"
  type: "Scale"
  bottom: "conv1_1"
  top: "conv1_1"
  param {
    lr_mult: 0.1
    decay_mult: 0
  }
  param {
    lr_mult: 0.2
    decay_mult: 0
  }
  scale_param {
    bias_term: true
  }
}
layer {
  name: "conv1_1/relu"
  type: "ReLU"
  bottom: "conv1_1"
  top: "conv1_1"
}
对于取反层(neg),其具体操作为,其中x为输入的数据,y为输出的数据,本质上就是一个幂次计算;
对于Scale层,其具体操作为,其中x为输入数据,y为输出数据.(这里我就不把c++的实现源码搬出来,感兴趣的童学自己看)
  • C.ReLu的作用
    可以减少计算量, 因为它只用了一半的卷积操作,减少了卷积的计算量 .

使用Inception

  • Inception网络结构
    本论文中在该结构模块中引入了残差连接(shortcut),具体的结构图如下:

这里就不贴caffe中Inception层的定义,因为实在太长了,直接去prototxt文件中查看

  • Inception的作用
    该结构可以同时 捕获大目标和小目标 。为了捕获图像中的大目标,需要足够大的感受野,这个可以通过堆叠3×3的滤波器来达到。但是为了捕获小目标,则需要小一点的感受野,1×1的卷积核正好合适。可以避免大卷积核造成的参数冗余问题。
    从上图可以发现该论文在使用Inception的同时引入了残差连接,目的是稳定网络框架的后半部分,加速网络训练

使用了HyperNet

  • HyperNet的网络结构
    论文中的HyperNet是用于连接conv3_4、conv4_4、conv5_4三层的特征,其具体的网络结构如下(画的有点丑,将就看吧),实际代码中后面还接着几个层(convrf),在下图中我没有展示
  • caffe中HyperNet层的定义
    在提取特征层的时候,由于每层特征层的feature map大小不一样,所以HyperNet中对低层的特征图采用下采样,对高层的特征图采用上采样
layer {
  name: "downsample"
  type: "Pooling"
  bottom: "conv3_4"
  top: "downsample"
  pooling_param { kernel_size: 3 stride: 2 pad: 0 pool: MAX }
}
layer {
    name: "upsample"
    type: "Deconvolution"
    bottom: "conv5_4"
    top: "upsample"
    param { lr_mult: 0 decay_mult: 0}
    convolution_param {
        num_output: 384 kernel_size: 4 pad: 1 stride: 2 group: 384
        weight_filler: {type: "bilinear" }
        bias_term: false
    }
}
layer {
  name: "concat"
  bottom: "downsample"
  bottom: "conv4_4"
  bottom: "upsample"
  top: "concat"
  type: "Concat"
  concat_param { axis: 1 }
}
layer {
  name: "convf_rpn"
  type: "Convolution"
  bottom: "concat"
  top: "convf_rpn"
  param { lr_mult: 1.0 decay_mult: 1.0 }
  param { lr_mult: 2.0 decay_mult: 0 }
  convolution_param {
    num_output: 128 kernel_size: 1 pad: 0 stride: 1
    weight_filler { type: "xavier" std: 0.1 }
    bias_filler { type: "constant" value: 0.1 }
  }
}
layer {
  name: "reluf_rpn"
  type: "ReLU"
  bottom: "convf_rpn"
  top: "convf_rpn"
}
layer {
  name: "convf_2"
  type: "Convolution"
  bottom: "concat"
  top: "convf_2"
  param { lr_mult: 1.0 decay_mult: 1.0 }
  param { lr_mult: 2.0 decay_mult: 0 }
  convolution_param {
    num_output: 384 kernel_size: 1 pad: 0 stride: 1
    weight_filler { type: "xavier" std: 0.1 }
    bias_filler { type: "constant" value: 0.1 }
  }
}
layer {
  name: "reluf_2"
  type: "ReLU"
  bottom: "convf_2"
  top: "convf_2"
}
layer {
  name: "concat_convf"
  bottom: "convf_rpn"
  bottom: "convf_2"
  top: "convf"
  type: "Concat"
  concat_param { axis: 1 }
}

这里面其实都是一些常用的层,这里不展开细说.

  • HyperNet层的作用
    本质是多尺度相融合,即细粒度细节与高度概括的语义信息的结合有助于随后的region proposal网络和分类网络检测不同尺度的目标

备注:除上述外,论文海通过权重衰减策略采用plateau detection(一定迭代次数内loss不再下降,则将学习速率降低常数倍)、 batch normalization等可以实现高效的训练

总结

  • PVANET网络相比faster-rcnn检测速度提升了,整个网络结构变得 “瘦长” (更少的channels,更多的layers),在网络结构方面使用了C.ReLu、Inception、HyoerNet、Shortcut(残差连接)、batch normalization;在训练阶段,采用了权重衰减策略
  • 相比SSD网络,它对小目标的检测结果更好.(当然这个结论是我的数据实验中得证的)

Be First to Comment

发表评论

电子邮件地址不会被公开。 必填项已用*标注