PaddleDetection算法分析(13)

2023-10-30

2021SC@SDUSC

分析完了PaddleDetection的竞赛冠军模型。接下来分析移动端模型

PaddleDetection目前提供一系列针对移动应用进行优化的模型,主要支持以下结构:

 其中大量网络应用了ssd算法 我们接下来进行对其中ssd算法的分析

链接介绍:

SSD github : https://github.com/weiliu89/caffe/tree/ssd

SSD paper : https://arxiv.org/abs/1512.02325

SSD 动态PPT: https://docs.google.com/presentation/d/1rtfeV_VmdGdZD5ObVVpPDPIODSDxKnFSU0bsN_rgZXc/pub?start=false&loop=false&delayms=3000&slide=id.g179f601b72_0_51

SSD PPT:http://www.cs.unc.edu/~wliu/papers/ssd_eccv2016_slide.pdf

目标检测|SSD原理与实现:https://zhuanlan.zhihu.com/p/33544892

论文阅读:SSD: Single Shot MultiBox Detector : https://blog.csdn.net/u010167269/article/details/52563573

一、SSD网络总体架构

 

 

图1 SSD网络架构(精简版)

图2 SSD网络架构(细节版)
SSD采用VGG16作为基础模型,并且做了以下修改,如图1所示

分别将VGG16的全连接层FC6和FC7转换成 3x3 的卷积层 Conv6和 1x1 的卷积层Conv7
去掉所有的Dropout层和FC8层
同时将池化层pool5由原来的 stride=2 的 2x2 变成stride=1的 3x3 (猜想是不想reduce特征图大小)
添加了Atrous算法(hole算法),目的获得更加密集的得分映射
然后在VGG16的基础上新增了卷积层来获得更多的特征图以用于检测


二、算法细节


1、多尺度特征映射

 

图3 单层feature map预测和多层特征金字塔预测对比


       如图3所示,左边的方法针对输入的图片获取不同尺度的特征映射,但是在预测阶段仅仅使用了最后一层的特征映射;而SSD(右图)不仅获得不同尺度的特征映射,同时在不同的特征映射上面进行预测,它在增加运算量的同时可能会提高检测的精度,因为它具有更多的可能性。

 


 图4 SSD与Faster-rcnn比较


        如图4所示,对于BB(bounding boxes)的生成,Faster-rcnn和SSD有不同的策略,但是都是为了同一个目的,产生不同尺度,不同形状的BB,用来检测物体。对于Faster-rcnn而言,其在特定层的Feature map上面的每一点生成9个预定义好的BB,然后进行回归和分类操作来进行初步检测,然后进行ROI Pooling和检测获得相应的BB;而SSD则在不同的特征层的feature map上的每个点同时获取6个(有的层是4个)不同的BB,然后将这些BB结合起来,最后经过NMS处理获得最后的BB。

 

原因剖析:

 


图5 不同卷积层的feature map
       如上图所示,输入一幅汽车的图片,我们将其输入到一个卷积神经网络中,在这期间,经历了多个卷积层和池化层,我们可以看到在不同的卷积层会输出不同大小的feature map(这是由于pooling层的存在,它会将图片的尺寸变小),而且不同的feature map中含有不同的特征,而不同的特征可能对我们的检测有不同的作用。总的来说,浅层卷积层对边缘更加感兴趣,可以获得一些细节信息(位置信息),而深层网络对由浅层特征构成的复杂特征更感兴趣,可以获得一些语义信息,对于检测任务而言,一幅图像中的目标有复杂的有简单的,对于简单的patch我们利用浅层网络的特征就可以将其检测出来,对于复杂的patch我们利用深层网络的特征就可以将其检测出来,因此,如果我们同时在不同的feature map上面进行目标检测,理论上面应该会获得更好的检测效果。

2、Default box 和 Prior box(先验框)


      图片被送进网络之后先生成一系列 feature map,传统框架会在 feature map(或者原图)上进行 region proposal 提取出可能有物体的部分然后进行分类,这一步可能非常费时,所以 SSD 就放弃了 region proposal,而选择直接生成一系列 defaul box(筛选出prior boxes投入训练),然后以prior box 为初始bbox,将bboxes回归到正确的GT位置上去,预测出的定位信息实际上是回归后的bboxes和回归前的(prior box)的相对坐标。整个过程通过网络的一次前向传播就可以完成。

Defalut box:

 


图6 SSD的default box
       Default box是指在feature map的每个单元格(cell)上都有一系列固定大小的box。SSD 训练图像中的 groundtruth 需要赋予到那些固定输出的 boxes 上,看下节Prior box概念。如上图所示,每个单元格使用了4个不同的Defalut box(虚线框,仔细看格子的中间有比格子还小的一个box),图片a中猫和狗分别采用最适合它们形状的Defalut box来进行训练。假设每个feature map cell有k个default box,那么对于每个default box都需要预测C(包括背景)个类别score和4个offset,因此如果一个feature map的大小是m*n,那么这个feature map就一共有K*m*n个default box,每个default box需要预测4个坐标相关的值和C(包括背景)个类别概率,则在m*n的特征图上面将会产生(C+4)* K * m * n个输出。这些输出个数的含义是:采用3×3的卷积核对该层的feature map卷积时卷积核的个数,包含两部分,实际code是分别用不同数量的3*3卷积核对该层feature map进行卷积:比如数量为C*K的卷积核对应confidence输出,表示每个default box的confidence,也就是类别的概率;数量为4*K的卷积核对应localization输出,表示每个default box回归后的坐标)。作者的实验也表明default box的shape数量越多,效果越好。

Defalut box分析:

 


图7 Defalut box分析
       SSD的一个核心是同时采用lower和upper的feature maps做检测。SSD中的Defalut box和Faster-rcnn中的anchor机制很相似。就是预设一些目标预选框,后续通过softmax分类+bounding box regression获得真实目标的位置。对于不同尺度的feature map 上使用不同的Default boxes。如上图所示,我们选取的feature map包括38x38x512、19x19x1024、10x10x512、5x5x256、3x3x256、1x1x256。具体怎么得到的看下面的表。我们总共可以获得8732个box,然后我们将这些box送入NMS模块中,获得最终的检测结果。
       以上的操作都是在特征图上面的操作,即我们在不同尺度的特征图上面产生很多的bbox,如果映射到原始图像中,我们会获得一个密密麻麻的bbox集合,如下图所示:

 


  图8 原始图像中生成的BB
Prior box概念:

       训练中还有一个东西:Prior box,是指实际中选择的要投入训练过程的Default box(每一个feature map cell 不是k个Default box都取)。
      也就是说Default box是一种概念,Prior box则是实际的选取。训练中一张完整的图片送进网络获得各个feature map,对于正样本训练来说,需要先将prior box与ground truth box做匹配,匹配成功说明这个prior box所包含的是个目标,但离完整目标的ground truth box还有段距离,训练的目的是保证default box的分类confidence的同时将prior box尽可能回归到ground truth box。
       举个列子:假设一个训练样本中有2个ground truth box,所有的feature map中获取的prior box一共有8732个。那可能分别有10、20个prior box能分别与这2个ground truth box匹配上。

Defalut box生成规则:

       以feature map上每个点的中点为中心(offset=0.5),生成一些列同心的Defalut box(然后中心点的坐标会乘以step,相当于从feature map位置映射回原图位置)
       正方形prior box最小边长为:,最大边长为:
每在prototxt设置一个aspect ratio,会生成2个长方形,长宽为: 和 

 


图9 default box的生成
而每个feature map对应Prior box的min_size和max_size由以下公式决定,公式中m是使用feature map的数量(SSD 300中m=6)

使用不同的ratio值,[1, 2, 3, 1/2, 1/3],通过下面的公式计算 default box 的宽度w和高度h:

而对于ratio=1的情况,指定的scale如下所示,即总共有 6 中不同的 default box

     第一层feature map对应的min_size=S1,max_size=S2;第二层min_size=S2,max_size=S3;其他类推。在原文中,Smin=0.2,Smax=0.95。但是在SSD 300中prior box设置并不能和paper中上述公式对应:

        不过依然可以看出,SSD使用低层feature map检测小目标,使用高层feature map检测大目标,这也应该是SSD的突出贡献了。每一层中每一个点对应的prior box的个数,是由PriorBox这一层的配置文件决定的。其中SSD 300在conv4_3生成prior box的conv4_3_norm_priorbox层prototxt定义如下:

layer {  
  name: "conv4_3_norm_mbox_priorbox"  
  type: "PriorBox"  
  bottom: "conv4_3_norm"  
  bottom: "data"  
  top: "conv4_3_norm_mbox_priorbox"  
  prior_box_param {  
    min_size: 30.0  
    max_size: 60.0  
    aspect_ratio: 2  
    flip: true  
    clip: false  
    variance: 0.1  
    variance: 0.1  
    variance: 0.2  
    variance: 0.2  
    step: 8  
    offset: 0.5  
  }  
}  


PS: min_size是必须要有的参数,否则不会进入对应的框的生成过程。论文跟实际代码是有一些出入的,Git上也有人在讨论这个,基本都选择无视论文。。。

这里还有一个比较关键的参数,就是step,在conv4-3中设置为8,这个又是怎么来的呢?


实际就是原图与特征图 大小的比值,比如conv4_3 width = 38 ,输入的大小为300,那么scale=7.8,所以这里设置的step=8。这一部分的计算过程可以在 prior_box_layer.cpp的Forward_cpu中看到。

Prior box如何使用:

     知道了Prior box如何产生,接下来分析Prior box如何使用。这里以conv4_3为例进行分析。


图10
   在conv4_3 feature map网络pipeline分为了3条线路,如上图:

      1、经过一次batch norm+一次卷积后,生成了[1, num_class*num_priorbox, layer_height, layer_width]大小的feature用于softmax分类目标和非目标(其中num_class是目标类别,SSD 300的VOC数据集中num_class = 21)
      2、经过一次batch norm+一次卷积后,生成了[1, 4*num_priorbox, layer_height, layer_width]大小的feature用于bounding box regression(即每个点一组偏移量[dxmin,dymin,dxmax,dymax])
      3、生成了[1, 2, 4*num_priorbox]大小的prior box blob,其中2个channel分别存储prior box的4个点坐标和对应的4个variance。4个variance,这实际上是一种bounding regression中的权重。
      后续通过softmax分类+bounding box regression即可从priox box中预测到目标。熟悉Faster RCNN的读者应该对上述过程应该并不陌生。其实pribox box的与Faster RCNN中的anchor非常类似,都是目标的预设框,没有本质的差异。区别是每个位置的prior box一般是4~6个,少于Faster RCNN默认的9个anchor;同时prior box是设置在不同尺度的feature maps上的,而且大小不同。

       有一个细节是只有conv4_3层后加了一个Normalization 操作,其他的几层都没有,具体原因参考另一篇文章:Normalization on conv4_3 in SSD :https://blog.csdn.net/ytusdc/article/details/86612355

       还有一个细节就是上面prototxt中的4个variance,这实际上是一种bounding regression中的权重。在图4线路(2)中,网络输出[dxmin,dymin,dxmax,dymax],即对应下面代码中bbox;然后利用如下方法进行针对prior box的位置回归:

decode_bbox->set_xmin(  
    prior_bbox.xmin() + prior_variance[0] * bbox.xmin() * prior_width);  
decode_bbox->set_ymin(  
    prior_bbox.ymin() + prior_variance[1] * bbox.ymin() * prior_height);  
decode_bbox->set_xmax(  
    prior_bbox.xmax() + prior_variance[2] * bbox.xmax() * prior_width);  
decode_bbox->set_ymax(  
    prior_bbox.ymax() + prior_variance[3] * bbox.ymax() * prior_height);  
       上述代码可以在SSD box_utils.cpp的void DecodeBBox()函数见到。

Permute,Flatten And Concat Layers:

      上一节以conv4_3 层分析了如何检测到目标的真实位置,但是SSD 300是使用包括conv4_3在内的共计6个feature maps一同检测出最终目标的。在网络运行的时候显然不能一个feature map单独计算一次softmax socre+box regression(虽然原理如此,但是不能如此实现)。那么多个feature maps如何协同工作?这时候就要用到Permute,Flatten和Concat这3种层了。其中conv4_3_norm_mbox_conf_perm的prototxt定义如下:

layer {  
  name: "conv4_3_norm_mbox_conf_perm"  
  type: "Permute"  
  bottom: "conv4_3_norm_mbox_conf"  
  top: "conv4_3_norm_mbox_conf_perm"  
  permute_param {  
    order: 0  
    order: 2  
    order: 3  
    order: 1  
  }  
}  


Permute是SSD中自带的层,Permute相当于交换blob中的数据维度。在正常情况下blob的顺序为:

                                     bottom blob = [batch_num, channel, height, width]
经过conv4_3_norm_mbox_conf_perm后的blob为:

                                     top blob = [batch_num, height, width, channel]
而Flattlen和Concat层都是caffe自带层。所有操作相当于各层输出中把channel放到了最后一个维度然后逆序相乘再总的相加。具体这两个层的细节参考另一篇文章:

深度学习中Concat层和Flatten层作用 :https://blog.csdn.net/ytusdc/article/details/86610897。

加入这几个层的原因分析:

      SSD的 XX_conf 和 XX_loc层的输出,是用通道来保存特征向量的,所以这里需要将通道数调整到最后,也就是 permute所做的事情。通过该层后,数据的顺序被换成了 NHWC,再通过 flatten拉成一列。

Feature map合并方法:


图11 SSD中部分层caffe blob shape变化
       现在以conv4_3和fc7为例分析SSD是如何将不同size的feature map组合在一起进行prediction。上图展示了conv4_3和fc7合并在一起的过程中shape变化(其他层类似)。
       1、对于conv4_3 feature map,conv4_3_norm_priorbox(priorbox层)设置了每个点共有4个prior box。由于SSD 300共有21个分类,所以conv4_3_norm_mbox_conf的channel值为num_priorbox * num_class = 4 * 21 = 84;而每个prior box都要回归出4个位置变换量[dx,dy,dx,dymax],所以conv4_3_norm_mbox_loc的channel值为4 * 4 = 16。
       2、fc7每个点有6个prior box,其他feature map同理。
       3、经过一系列图展示的shape变化后,最后拼接成mbox_conf和mbox_loc。而mbox_conf后接reshape,再进行softmax(为何在softmax前进行reshape,Faster RCNN有提及)。
      4、最后这些值输出detection_out_layer,获得检测结果。

 

以上是本篇博客介绍的内容 接下来继续剩余部分的讲解
 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

PaddleDetection算法分析(13) 的相关文章

  • 减少数据打拍翻转的低功耗设计方法

    在流水设计中 时常会遇到对某一路数据打多拍从而对齐另一路数据的场景 而除了最后一拍是真正需要的 中间的打拍从功耗上来看是有点浪费的 举个例子 对8bit in data打4拍 总共需要用到4个8bit寄存器 常规打拍方法传输4个数据 D0
  • android 屏幕适配--------解决方案

    以下是Demo首页的预览图 demo下载 http www eoeandroid com forum php mod attachment aid NjE0Njh8ZTIyZDA2M2N8MTMzODgyOTQxN3w1NzAwOTV8MT

随机推荐

  • Spring Boot实现QQ邮件发送,用户注册功能——前后端分离版

    1 准备工作 我们需要前往我们的QQ邮箱开启相关功能 登录QQ邮箱后 点击进入 设置 在账户在一栏中 我们可以找到这个界面 然后点击开启 POP3 SMTP服务 他们会让我们用QQ的密保手机发送一条短信 我们照着即可 验证成功之后 会获得一
  • ISP记1

    目录 0 参考 1 噪声分类 1 1 空间区域 1 1 1 高斯噪声 1 1 2 瑞利噪声 1 1 3 伽马噪声 1 1 4 均匀分布噪声 1 1 5 泊松噪声 1 1 6 加性噪声 乘性噪声 0 参考 数字图像滤波算法的研究及应用 倪层敏
  • anaconda+pytorch安装说明

    第一步 anconda的安装 大家可以参考以下博文 写的比较简约 看起来比较清爽 https blog csdn net ITLearnHall article details 81708148 Anacond的介绍 Anaconda指的是
  • chisel线网(wire)和寄存器(reg)详解(更新)

    主体内容摘自 https blog csdn net qq 34291505 article details 87714172 在Verilog里 模块内部主要有 线网 wire 和 四态变量 reg 两种硬件类型 它们用于描述数字电路的组
  • QVariant的使用

    在有些情况下 我们希望把数据存储在一个变量中 例如 我有一个数组 既希望存整数 又希望存浮点数 还希望存string 想了一个方法 创建一个object类 这是一个很大的类 里面几乎包含了所有类型的数据 如下 class Object pu
  • Java合并两个有序数组

    合并排序 将两个已经排序的数组合并成一个数组 其中一个数组能容下两个数组的所有元素 public class MergeArray public MergeArray public static ArrayList
  • 【APB协议详解】

    APB协议详解 APB Advanced Peripheral Bus 作为高级外设总线是AMBA协议之一 也是最基本的总线协议 按照ARM官方定义 APB是一种低成本的接口协议 可以实现低功耗以及精简的接口设计 降低接口设计的复杂度 AP
  • adb操作提示Read-only file system问题

    Android adb调试时 经常会遇到权限问题 failed for system lib libmm test so Read only file system 即使Root设备 在向 system等系统文件夹操作时 比如push rm
  • Shell基础—正则表达式(通配符、模式表达式)详解【附例】

    Shell基础 正则表达式 正则表达式是一种可以用于模式匹配和替换的工具 通过正则表达式 Shell可以使用一系列的特殊字符构建匹配模式 然后将匹配模式与待比较字符串或文件进行比较 根据比较对象中是否包含匹配模式 执行相应的程序 1 通配符
  • 【环境搭建】Notepad++显示16十六进制编码

    环境搭建 Notepad 显示16十六进制编码 by 041 打开插件 gt 插件管理 找到HEX Editor 安装 重启Notepad 选择插件 gt HEX Editor gt View in HEX 即可显示16进制文件
  • ubuntu18.04使用Mysql指令

    前言 在使用Ubuntu中 对MySQL不熟悉 在实践中不断总结 不断更新 目录 前言 在使用Ubuntu中 对MySQL不熟悉 在实践中不断总结 不断更新 一 安装MySQL 1 更新 2 安装数据库 3 查看版本 二 sql语句 1 启
  • F - Tickets

    F Ticketshttps vjudge csgrandeur cn problem Gym 101911F 暴力 超时 时间复杂度 2 1e5 1e6 别忘了还有查询 include
  • TCP-服务器监听

    package main import fmt net func process conn net Conn 这里我们循环的接收客户端发送的数据 defer conn Close 关闭conn for 创建一个新的切片 buf make b
  • Java抽象类和接口

    一 抽象类 在面向对象的概念中 所有对象都是通过类来描绘的 但并不是所有类都是用来描绘对象的 如果一个类中没有足够的属性和行为来描绘一个完整具体的对象 Java 提供了一个语法 抽象类 例如我们需要一个描述形状的类 成员方法可以输出当前的形
  • Python获取电脑信息

    我做了一个Python获取电脑信息的程序 小部分代码是网上找的 本来想把这个做成一个坑人小程序的 到后面没有灵感了 有想法的可以帮我做一下 私聊发代码给我 代码 pycharm运行通过 coding utf 8 import wmi imp
  • C++数据结构X篇_08_C++实现栈的顺序存储与链式存储

    本篇参考C 实现栈的顺序存储与链式存储整理 先搞懂结构框架 后期根据视频利用c对内容实现 也可以对c有更高的提升 文章目录 1 栈的顺序存储 2 栈的链式存储 栈是一种特殊的数据结构 栈中数据先进后出 且栈中数据只能从头部出栈 能直接访问的
  • 数据库删除数据的方式

    数据库删除数据的方式主要是有三种 drop delete truncate 他们之间的区别在于 1 删除的内容不同 drop 用于删除数据库 数据表 以及 删除数据表中的字段 删除数据库 drop database 数据库名 删除数据表 d
  • Numpy、Pandas使用大全与各参数详解

    目录 一 numpy 1 属性 方法与操作 1 属性 2 方法 3 操作 2 文件读取与保存 1 文件读取 2 文件保存 3 矩阵生成 二 Pandas 1 属性与方法 1 属性 2 方法 2 数据选取 1 取行 2 取列 3 数据处理 1
  • 遇到问题----shrio------shiro登录,多个项目session被覆盖问题---两个web项目会导致shiro的session污染

    情况 遇到问题 shrio shiro登录 多个项目session被覆盖问题 一个项目两个web模块会导致shiro的session污染 表现为 我在同一台机子上部署了两个都使用了shiro管理的web项目 它们的访问路径除了端口不一样 i
  • PaddleDetection算法分析(13)

    2021SC SDUSC 分析完了PaddleDetection的竞赛冠军模型 接下来分析移动端模型 PaddleDetection目前提供一系列针对移动应用进行优化的模型 主要支持以下结构 其中大量网络应用了ssd算法 我们接下来进行对其