【论文阅读】CenterNet

news2024/12/29 13:16:00

论文题目:Objects as Points(CVPR2019)

论文地址:https://arxiv.org/pdf/1904.07850.pdf

发布时间:2019.4.16

机构:UT Austin,UC Berkeley

代码:https://github.com/xingyizhou/CenterNet

【论文】

【others翻译、论文解析】 

目标检测之CenterNet:属于Anchor-free系列的目标检测,与之前的CornerNet相比较,使用中心点表示物体,从而增强其对内部信息的感知能力

CenterNet目标检测器是一种关键点估计网络,找到目标的中心,回归出他们的尺寸。同样作为Anchor-free的方法,CenterNet则针对CornerNet对内部语义缺失的问题,提出了对中心点进行估计的方法。

Introduction:本文的方法通过中心点来呈现目标,从而将目标检测问题转换为关键点的估计问题。通过提取得到一个热图,而热图的峰值点即为中心点,利用峰值点位置来预测目标的宽高信息。这种简洁的方法也使得CenterNet能够达到很高的速度。

Related Work:本文的方法接近于anchor-based one-stage的方法,但也有一些不同点。首先,CenterNet是基于位置设置锚点,而非box overlap,且没有进行人工设置阈值做前后景分类。其次,每一个目标上仅有一个正的锚点,因此不需要NMS处理,且仅提取关键点热图的局部峰值点。第三,与传统的目标检测器相比较,使用更大分辨率的输出图像,因此不需要多重锚点。        之前也有基于关键点估计的方法,比如ECCV2018中Detecting Objects as Paired Keypoints所提出的CornerNet就首次应用了以关键点估计为导向的目标检测方法,同时还包括CVPR2019中的Bottom-up Object Detection by Grouping Extreme and Center Points中提出的ExtremeNet。然而这些方法在关键点检测之后都需要一个combinatorial grouping stage

 Implementation:作者实验了四种结构:ResNet-18,ResNet-101,DLA-34,Hourglass-104。其中,利用deformable convolution layers修改ResNet和DLA-34,对Hourglass则按照原样使用。



anchor-free之CenterNet的浅析与实现:CenterNet没有用到什么花里胡哨的东西,不过是将keypoints思想和encoder-decoder结构用在了目标检测任务中来,整篇文章看起来的最大感受就是:干净。每次有小任务的时候,我都会优先考虑用它来做,而不是YOLO,毕竟少了调anchor box的麻烦。【作者也提供了自己的项目代码,但是有改动,ResNet18/SPP/512x512】

CenterNet中的YOLO思想

(1)检测中心点:YOLO的特色就在于只考虑中心点作为positive samples,在YOLO中,只有中心点所在的网格点会被考虑,其他均视为负例,而CenterNet则没有直接抛弃掉周围的点,而是赋予了更小的权重,权重的计算就是简单的用高斯函数(确定中心点选取的方差用的就是CornerNet的代码,默认两个方差一样,画出来的高斯区域是个圆[向下取整])

从高斯函数可以看出,中心点的权重就是1,周围逐渐降低,达到了“软阈值”的目的。再补充一点,这个阈值是针对中心点的heatmap的,至于offset和wh的学习,只有中心点这一个正样本去回归offset和wh,其他被软化的样本都不会去回归offset和wh,所以,这种“软阈值”的办法只是针对中心点的位置本身的。(根据阈值定中心点,然后根据中心点去回归其他量),CenterNet是在更大分辨率的feature上做检测的。相较于YOLO那种硬阈值确定中心点的方法,在这种大尺度分辨率的feature上做预测,软化要更好。

(2)学习偏差offset:和YOLO一样,由于降采样和feature map坐标是整数,因此在feature map算出来的中心点坐标都是整数,小数点都被舍掉,从而在反解的时候,就会有很大偏差,这种偏差会随着stride的增大和增大,因此,CenterNet也要去学这个偏差,这和YOLO一样,只是YOLO当时并没有去强调这个,而CenterNet在论文里把这个事拿出来说了,还有模有样的。按照CenterNet的官方代码来看,这个offset使用线性输出+L1损失函数来学习的,遵从YOLO的方式,因为offset是在01之间的,因此自然而然地选择了sigmoid函数,也就自然而然地选择了BCE损失函数

另一方面,CenterNet本身是anchor box free的方法,即不使用任何的先验框,直接回归bounding box的wh,不使用先验框,也就意味着不能像anchor box based的方法那样,通过先验框本身的尺度信息就能自动分配到FPN的各个尺度上去。所以,如果想用FPN的话,就得需要考虑一下如何设定一个决策方式,将各个框分配到各个尺度上去,比如FCOS,FoveaBox等。   不过,CenterNet并不想这么麻烦,因为它把OD问题视为关键点的回归,因此就用了encoder-decoder的方式,在一张很大的feature map上去回归,原文中用的是stride=4的feature map,这么大的feature map其实很精细了,大部分的小目标信息都能回归出来。CenterNet是采用Deconv来做上采样的,不同尺度的特征没有进行融合。其实,这里也可以参考Hourglass的做法, 使用上采样操作+融合来得到大分辨率的feature map.

CenterNet的思想与很多主流检测器RetinaNet、FCOS和YOLO等是不同的。后者们是一种分而治之的方式,即采用多个不同尺度的feature map去检测不同尺度的物体,不同尺度相当于不同的焦距,从而聚焦于不同大小的物体上。// 而CenterNet则是合而治之的方式,我们通过这么大的feature map去回归,既能有小物体,也能有大物体,所有物体的尺度信息都在一个feature map上就OK了,这和TridentNet有异曲同工之妙,只不过TridentNet最后还是分支了。在没有一个可靠的理论解释前,实验结果有很大说服力的,从CenterNet在COCO上的表现就可以看出,这种单级检测的合而治之的方式完全不比的多级检测的分而治之的方式要差,整体的框架还更加简洁。over

在推理的时候,CenterNet也不使用NMS操作,而是用一个 3×3 的maxpooling核去在输出的map上筛选出全是峰值点的map,然后拿这个map和输出的map做对应,就只有峰值点的map了,之所以这么做,是因为筛选的时候,步长为1,那么同一个峰值点会出现在不同的地方,因此,筛选出来的是用不了的,得和原来的输出的map做一下对应才行(作者更爱用5x5的pooling核)。但是,这种方法还是会有冗余,尤其是很大的物体,仅靠这么小的maxpooling核是很容易筛选出多个峰值点的,所以,后面再加上NMS,还是有好处的,从论文中的结果也能看出来,用了NMS不亏,只是,提升可以忽略不计,因为,也就没必要加NMS了。(如果你的数据集中大物体很多,并且你没法容忍重复框,那我还是建议加上NMS)

作者代码网络图
作者采用ResNet18实现的CenterNet网络图

 实验过程:①关于两次topk的处理;②ResNet18这一版还是不够强,重复框挺严重的,所以nms抑制一下也是很有必要,时间上的开销几乎可以忽略不计;③Conv2d和DeConv2d以及SPP代码;④label制作☆以及2/2a效果比对⑤

《目标检测》-第23章-CenterNet-plus

补充内容:

1、NMS(non_max_suppression):IoU 的全称为交并比(Intersection over Union)计算的是 “预测的边框” 和 “真实的边框” 的交集和并集的比值。(通常用于测试阶段)        在预测任务中,会出现很多冗余的预测框,通过NMS操作可以有效的删除冗余检测的结果。非极大值抑制(NMS)顾名思义就是抑制不是极大值的元素,搜索局部的极大值。这个局部代表的是一个邻域,邻域有两个参数可变,一是邻域的维数,二是邻域的大小。 IoU 的阈值是一个可优化的参数,一般范围为0~0.5,可以使用交叉验证来选择最优的参数。

对于任意的检测框,设定两个框的IoU阈值作为两者是否合并的评判依据,并执行NMS操作来删除冗余的检测框。(针对单类别例如在行人检测中,滑动窗口经提取特征,经分类器分类识别后,每个窗口都会得到一个分数。但是滑动窗口会导致很多窗口与其他窗口存在包含或者大部分交叉的情况。这时就需要用到NMS来选取那些邻域里分数最高(是行人的概率最大),并且抑制那些分数低的窗口。

一个形象的演示       precision是在你认为的正样本中,有多大比例真的是正样本,recall则是在真正的正样本中,有多少被你找到了(可以反应漏检的情况)。[关于mAP说明在link中]

2、Conv2d和DeConv2d以及SPP代码

class Conv2d(nn.Module):
    def __init__(self, in_channels, out_channels, ksize, padding=0, stride=1, dilation=1, leakyReLU=False):
        super(Conv2d, self).__init__()
        self.convs = nn.Sequential(
            nn.Conv2d(in_channels, out_channels, ksize, stride=stride, padding=padding, dilation=dilation),
            nn.BatchNorm2d(out_channels),
            nn.LeakyReLU(0.1, inplace=True) if leakyReLU else nn.ReLU(inplace=True)
        )

    def forward(self, x):
        return self.convs(x)

class DeConv2d(nn.Module):
    def __init__(self, in_channels, out_channels, ksize, stride=2, leakyReLU=False):
        super(DeConv2d, self).__init__()
        # deconv basic config
        if ksize == 4:
            padding = 1
            output_padding = 0
        elif ksize == 3:
            padding = 1
            output_padding = 1
        elif ksize == 2:
            padding = 0
            output_padding = 0

        self.convs = nn.Sequential(
            nn.ConvTranspose2d(in_channels, out_channels, ksize, stride=stride, padding=padding, output_padding=output_padding),
            nn.BatchNorm2d(out_channels),
            nn.LeakyReLU(0.1, inplace=True) if leakyReLU else nn.ReLU(inplace=True)
        )

    def forward(self, x):
        return self.convs(x)

class SPP(nn.Module):
    """
        Spatial Pyramid Pooling
    """
    def __init__(self):
        super(SPP, self).__init__()

    def forward(self, x):
        x_1 = F.max_pool2d(x, 5, stride=1, padding=2)
        x_2 = F.max_pool2d(x, 9, stride=1, padding=4)
        x_3 = F.max_pool2d(x, 13, stride=1, padding=6)
        x = torch.cat([x, x_1, x_2, x_3], dim=1)

        return x

【代码】


【待阅读】


CenterNet-plus(评论区讨论)

第一卷-目标检测入门科普教程

Cornernet/Centernet代码里面GT heatmap里面如何应用高斯散射核

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/168408.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

小程序事件基础

小程序事件--基础小程序事件事件简介小程序事件—事件传参事件对象属性target和currentTarget事件对象属性获取和设置data数据获取&设置data获取和设置data数据—进阶小程序的渲染层与逻辑层小程序事件 事件简介 事件是视图层到逻辑层的通讯方式。负责将用户对于的页面的操…

云上的米开朗基罗:在不确定时代,寻找建筑般的确定性

文艺复兴三杰之一的米开朗基罗,被称为“天才建筑师”。其实他一生留下的建筑并不多,仅仅有美第奇礼拜堂、卡比多广场、圣彼得大教堂穹顶等寥寥几座。但米开朗基罗却凭借对建筑层次与结构的精妙把握,影响了此后数百年的建筑风格。很多人认为&a…

【代码随想录】动态规划:关于01背包问题,你该了解这些!(滚动数组)

01 背包 有n件物品和一个最多能背重量为w的背包 第i件物品的重量是weight[i], 得到的价值是value[i] , 每件物品只能用一次,求解将哪些物品装入背包里物品价值总和最大。 每一件物品其实只有两个状态,取或者不取,所以…

win下编译opencv+libjpeg-turbo

文章目录前言编译环境下载opencv和jpeg-turbo源码编译jpeg-turbo编译opencv失败?那就直接调用jpeg-turbo库进行编解码前言 opencv默认自带第三方jpeg编解码库,但其性能一般,对高性能需求的程序来说是不适合的,因此我们可以把jpeg…

设计模式学习(八):Proxy代理模式

一、什么是Proxy模式 Proxy是“代理人”的意思,它指的是代替别人进行工作的人。当不一定需要本人亲自进行工作时,就可以寻找代理人去完成工作。但代理人毕竟只是代理人,能代替本人做的事情终究是有限的。因此,当代理人遇到无法自己…

文件上传oss,并查询上传进度(SpringBoot+Redis+Oss+Swagger3)

文章目录诉求技术选型pom配置项目结构文件树图示结构代码实现配置相关配置文件yamlSwagger3配置跨域问题配置oss相关ServiceControllerApplicationSwagger接口操作获取上传文件标识号获取文件上传进度小结诉求 将文件上传到oss,并实时监听上传进度,并将进…

【javaSE】中基本类型和引用类型对象的比较及PriorityQueue中的比较方法

写博客是为了提升自己,也是为了展现自己的学习成果,坚持!坚持!坚持!未来是什么样的,闯一闯就知道啦。喜欢就留个关注吧!!! 目录 一、java对象的比较 1.1java中基本类型的比较 1.2引用对象的比较 1.3引用…

使用云端的GPU进行yolov5的训练

前言本文介绍了使用云端GPU进行yolov5训练环境配置的过程一、创建实例这里使用的是恒源云的GPU服务器,官方网址为恒源云_GPUSHARE-恒源智享云他的用户文档为Tmux - 恒源云用户文档一般的问题在用户文档中都可以找到解决办法。注册并登录后的界面如下图所示。点击云市…

c++11 标准模板(STL)(std::forward_list)(十)

定义于头文件 <forward_list> template< class T, class Allocator std::allocator<T> > class forward_list;(1)(C11 起)namespace pmr { template <class T> using forward_list std::forward_list<T, std::pmr::polymorphic_…

UPerNet:Unified Perceptual Parsing for Scene Understanding论文解读

Unified Perceptual Parsing for Scene Understanding 论文&#xff1a;[1807.10221] Unified Perceptual Parsing for Scene Understanding (arxiv.org) 代码&#xff1a;CSAILVision/unifiedparsing: Codebase and pretrained models for ECCV’18 Unified Perceptual Parsi…

第二章.线性回归以及非线性回归—岭回归

第二章.线性回归以及非线性回归 2.12 岭回归&#xff08;Ridge Regression&#xff09; 1.前期导入&#xff1a; 1).标准方程法[w(XTX)-1XTy]存在的缺陷&#xff1a; 如果数据的特征比样本点还多&#xff0c;数据特征n&#xff0c;样本个数m&#xff0c;如如果n>m&#xf…

5种气血不足的面相

我们常用“气色好”形容人良好的健康状态&#xff0c;反之&#xff0c;气血不足就是不健康的表现。想知道自己是否气血不足&#xff0c;可以从以下几种表现中判断。眼白黄&#xff1a;所谓人老珠黄&#xff0c;就是指眼白的颜色变得浑浊、发黄、有血丝&#xff0c;很可能气血不…

网络编程基础(1)

1 OSI七层模型&#xff08;理论&#xff09; 七层模型&#xff0c;亦称OSI&#xff08;Open System Interconnection&#xff09;。参考模型是国际标准化组织&#xff08;ISO&#xff09;制定的一个用于计算机或通信系统间互联的标准体系&#xff0c;一般称为OSI参考模型或七层…

cycle_gan使用教程

junyanz/pytorch-CycleGAN-and-pix2pix: Image-to-Image Translation in PyTorch (github.com) 如果是用cycle_gan 数据集 /数据集文件夹名&#xff0c;下面四个子文件名 testA testB trainA trainB trainA是A风格图片&#xff0c;trainB是B风格图片。 训练参数 test…

CCF BDCI | 算能赛题决赛选手说明论文-04

基于TPU平台实现人群密度估计 队名&#xff1a;innovation 陈照照 数据科学与大数据技术20级 台州学院 中国-瑞安 479253198qq.com董昊数据科学与大数据技术20级 台州学院 中国-杭州 donghaowifi163.com陈晓聪数据科学与大数据技术20级 台州学院 中国-宁波 2637491…

Golang -- openwechat微信发送消息、自动回复

开篇 马上就要到农历新年了&#xff0c;不妨写一段代码准时为好友们送上祝福。 该 Demo 使用开源项目 openwechat &#xff0c;实现获取好友列表、为好友发送消息、图片或文件&#xff0c;接收来自好友或群组的消息并设置自动回复等功能。 openwechat Github地址 openwechat 文…

管道(匿名,有名)

文章目录Linux 进程间通信的方式管道匿名管道有名管道Linux 进程间通信的方式 管道 管道特点 管道其实是一个在内核内存中维护的缓冲器&#xff0c;这个缓冲器的存储能力是有限的&#xff0c;不同的操作系统大小不一定相同管道拥有文件的特质&#xff1a;读操作、写操作 匿名管…

线扫相机DALSA-变行高拍照

CamExpert在线阵模式中默认的Buffer设置是Fixed Length。在这种设置下&#xff0c;在一帧采集结束前所接收到的新的帧触发信号都会被忽略。在有的应用中&#xff0c;需要新一帧的外触发信号能够中断当前帧的采集&#xff0c;开始新的一帧。这需要将Buffer设为Variable Length。…

【云原生】k8s之HPA,命名空间资源限制

内容预知 1.HPA的相关知识 2.HPA的部署运用 2.1 进行HPA的部署设置 2.2 HPA伸缩的测试演示 &#xff08;1&#xff09;创建一个用于测试的pod资源 (2)创建HPA控制器&#xff0c;进行资源的限制&#xff0c;伸缩管理 &#xff08;3&#xff09;进入其中一个pod容器仲&#xf…

Redhat OpenStack使用命令行发放云主机

OpenStack中各大组件的作用Glance&#xff1a;负责管理镜像&#xff08;镜像的上传、删除、下载&#xff09;Swift&#xff1a;提供镜像存储的空间Nova&#xff1a;负责配额的修改、启动云主机&#xff08;实例&#xff09;、创建密钥对、绑定弹性IP等Keystone&#xff1a;提供…