【文章解读】FreeAnchor: Learning to Match Anchors for Visual Object Detection

探讨FreeAnchor方法如何革新目标检测领域,通过改进传统Anchor分配机制,解决目标偏心和遮挡问题,提高检测精度。

一、简介

     这些年已经有不少基于深度学习的目标检测的文章了,从最开始的Anchor based 到后来的 Anchor Free。但是解读这篇文章,主要是由于他的出发点比较新颖---Free Anchor。

     虽然叫Free Anchor,但是依然是Anchor based的方法,只不过他打破了一直以来的Anchor分配机制。

二、回顾Anchor分配机制

    

       上图是来自于SSD的分析,对于不同尺度大小的feature map,每个pixel都会负责预测k个框,这个k就是预先设置好的Anchor数量,图中的虚线框也就是anchor。

        以前,在进行对于所有预测出来的结果box,进行loss计算的时候,会将anchor+偏移=结构box,与groundtruth进行比对,这个比对的过程就是利用IoU,只要预测框与目标物体的框IoU达到了一定阈值,那么这个框就算是正样本,当然如果一个anchor与多个目标物体都达到了阈值怎么办?直接选IoU最大的就好了!

        其他的都是负样本~~~,当然训练过程中会设置正负样本的比例,因为通常负样本会很多!

        这个方式,看似非常的合理,并且一直沿用至今,实际应用中也是非常有效的!但是这个方式毕竟也是经验式的

        大家可以看下面这例子

                          

        看完这两张图,想必大家不说也懂我想说什么了!!!!!嗯~~~~,词穷~~~~!因为现实世界中很多的目标物体,并不是规则,比如月亮,他们是偏心的!这也就导致了越是中心的点的feature 越是背景!无法代表这个目标,红色框与绿色框虽然IoU很高,如果按照传统方式判定为正样本!显然不好!

三、回到文章中来

       在文章中,把传统的Anchor分配方式称之为“IoU restriction”!文章对于传统方式给出了两方面的评价:1、并不是所有的目标物体都是规则的,很多时候物体是偏心的,瘦长的!或者说物体会被遮挡,比如图像中猫挡住了笔记本电脑,导致了笔记本电脑属于偏心的目标!2、On the other hand, it is infeasible to match proper anchors/features for objects using IoU when multiple objects come together.我感觉这句话有点重复吧,总之就是说传统的方式不灵活!毕竟对于不灵活,不智能的点进行优化,基本上都能提升效果!

     文章提出了自己的方法,并且把这个方式和损失函数联系起来,从而可以优化!和损失函数联系起来的方式叫“极大似然估计”,添加上负号和log,就得到了可以最小化的损失!

 

        上图中,上半部分是传统的anchor分配方式,基于这种方式无论这个pixel位置是否包含了“有效特征”,只要IoU达到了就是正样本!在计算损失函数的时候,就比必须带上它!这个时候,基本上我们也就发现问题了:引入了基于背景特征的正样本!强行让背景信息预测!

       这个公式就是传统的训练损失,A是anchor的集合,A_代表饿了没有配上正样本的那些,因此就是负样本。B代表了label中的目标全体,Cij则是0,1值,用于表示第i个目标和第j个anchor配上了。分类用BCE损失,回归用SoomthL1.

      在本文中,利用极大似然的想法来建立损失函数:因此上面的损失函数就可以转换为如下公式:

 四、文章核心       

     上面的公式中,“类别”和“回归”这两部分是分开计算的!本文的以思想就是,一个pixel位置是否能够预测box,应该具有两个特点:“能够拥有高的分类置信度” 以及 “框的IoU也高”。

        引入这两个公式,对应了常会用到的:召回率 与 精度,两个指标。对于召回率而言,需要为每个目标都能提供至少一个anchor,并且基于这个anchor的两类特性都应该接近对应的label。对于精度而言,“classify the anchors of poor localization into the background class”

        

       这个部分代表了,第j个anchor与所有的目标b都没有配对上的概率,这个概率的计算来自以上的计算方式,1-能配上的最大概率。当然,想要在网络模型中计算,就要建立一些公式来实现:

                                          

到这里,也就基本上知道这个网络需要优化的目标函数的计算方式了:

五、最最最核心部分到了

      损失函数,需要把极大似然换成最小化的形式。

      那么如果只是简单的使用max来完成,Free Anchor,显然大家会觉得有点敷衍!!!而且效果肯定也不太行,原因如下:训练初期,所有的anchor置信度都很低,那么这个时候选一个max的?有没有意义?(我觉得这应该也是可以的,现实一种随机,或者平均?有没有大佬说一说?)

       处于上面这个原因,作者提出了一种替代直接使用max的方法:

                 

     这个函数,一开始会是一种平均策略,随着训练的加深,anchor们的,置信度开始出现差异,最终是一个max。因此进一步优化后的损失函数如下,加入了两个权重和focal loss:

   Ai怎么来的呢?就是对于bi这个目标,利用IoU,从anchor们中选择top n个,就形成了一个A i 子集。文中原话如下

六、效果对比

 

### 什么是 Anchor? 在目标检测任务中,**anchor** 是一种预定义的参考框(reference box),用于辅助模型预测目标的位置和类别。anchor 通常在图像的不同位置、不同尺度和不同长宽比下进行采样,作为候选区域的基础。模型基于这些 anchor 来预测目标的边界框偏移量以及对应的类别置信度。 anchor 的设计灵感来源于滑动窗口机制,它允许模型在每个位置上同时预测多个可能的目标框,从而提升检测的精度和召回率。这种方法在 **anchor-based** 检测器中被广泛使用,例如 Faster R-CNN、YOLOv2 及其后续版本、RetinaNet 等[^1]。 ### Anchor 的作用 1. **提供先验框**:anchor 作为目标边界框的初始参考,模型通过预测相对于 anchor 的偏移量来获得最终的检测框。这种设计简化了回归任务,使模型更容易收敛。 2. **多尺度和多长宽比支持**:在不同位置上设置多个 anchor,可以覆盖图像中可能出现的多种目标形状和大小,从而提升对目标的适应能力。 3. **统一分类与定位任务**:每个 anchor 都会对应一个分类得分和一个边界框回归参数,使得分类和定位可以并行处理。 4. **优化训练过程**:通过 anchor 与真实边界框(ground truth)之间的 IoU(交并比)匹配,可以确定正负样本,指导模型的训练过程。 ### Anchor 的选择与优化策略 在训练过程中,anchor 的选择至关重要。例如,在 **Multiple Anchor Learning (MAL)** 中,通过 anchor 与目标之间的 IoU 排序,选择 IoU 最高的 anchor 构建“anchor bag”,并结合分类和定位分数评估每个 anchor 的质量,最终选择得分最高的 anchor 进行优化,以实现分类和定位性能的同步提升。 此外,在 **Consistent Optimization for Single-Shot Object Detection** 中,指出传统的 anchor 在分类和定位之间可能存在不一致性问题,即回归后的 anchor 与分类所使用的 anchor 不一致,从而影响最终检测效果。为此,提出了一种一致性优化策略,通过更合理的 anchor 选择机制来缓解这一问题[^2]。 ### Anchor-Free 与 Anchor-Point 方法 与 anchor-based 方法相对的是 **anchor-free** 检测器,其中一种主流方法是 **anchor-point**。这类方法不再依赖预定义的 anchor,而是直接在特征图的关键点(如中心点)上预测目标的边界框。例如,**Soft Anchor-Point Object Detection (SAPD)** 通过引入软匹配机制,使 anchor-point 方法在 COCO 数据集上取得了较高的检测精度和推理速度,单尺度下 AP 达到 47.4%,且推理速度比其他检测器快五倍[^3]。 ### 示例代码:Anchor 的生成 以下是一个简单的 anchor 生成示例,用于在特征图上生成多个 anchor 框: ```python import numpy as np def generate_anchors(base_size=16, ratios=[0.5, 1, 2], scales=2**np.arange(3, 6)): base_anchor = np.array([1, 1, base_size, base_size]) - 1 w, h, x_ctr, y_ctr = base_anchor[2] - base_anchor[0] + 1, base_anchor[3] - base_anchor[1] + 1, (base_anchor[0] + base_anchor[2]) / 2, (base_anchor[1] + base_anchor[3]) / 2 anchors = [] for r in ratios: size = w * h w_r = np.round(np.sqrt(size / r)) h_r = np.round(w_r * r) for s in scales: anchors.append([x_ctr - 0.5 * w_r * s, y_ctr - 0.5 * h_r * s, x_ctr + 0.5 * w_r * s, y_ctr + 0.5 * h_r * s]) return np.array(anchors, dtype=np.float32) # 生成默认 anchor anchors = generate_anchors() print("Anchor 框示例:", anchors) ``` 该代码生成了多个具有不同长宽比和尺度的 anchor 框,可用于后续的目标检测任务。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值