物体检测(Object Detection)任务的引入与基础概念
一、什么是物体检测?
- 定义:给定一张 RGB 图像,输出图像中所有检测到的物体。
- 每个物体有两个输出:
- 类别标签(Category Label):表示物体是什么,例如“狗”或“车”。
- 边界框(Bounding Box):表示该物体在图像中的空间位置,通常用4个实数表示:x、y(中心点坐标)和 w、h(宽高),单位为像素。
- 注意:标准物体检测任务中,边界框是轴对齐的矩形,不考虑旋转。
二、和图像分类的区别?
- 图像分类(Image Classification):只输出整张图的一个标签,例如“这是一张猫的照片”。
- 物体检测(Object Detection):图中可能有多个物体,每个都要识别并定位。
三、物体检测比图像分类更难的原因:
- 多重输出(Multiple Outputs):图像中可能有多个物体,数量不固定,模型需要输出一个可变长度的物体列表。
- 双重输出类型:不仅要预测类别标签,还要输出边界框,需要设计新的网络结构来处理这两类信息。
- 高分辨率图像需求:
- 图像分类可以使用 224×224 像素这样的小图;
- 物体检测需要处理高分辨率图像(例如800×600),以便能检测到小物体,导致模型计算量更大。
四、实际应用场景:
- 自动驾驶:车辆需要知道其它车、行人、交通标志的位置,不能只知道“图片里有车”,还要知道车在哪里。
- 安全监控、医疗图像分析、机器人导航等领域也都有广泛应用。
五、总结一句话:
物体检测是在图像分类之后,计算机视觉中第二个最核心的任务,不仅要识别“是什么”,还要指出“在哪里”,是更复杂、计算要求更高的任务。
简单的思路
一、检测单个物体(Detecting a Single Object)
对应图:第一张图(猫 + 网络结构)
基本思想
- 假设图像中只存在一个物体,我们就可以将其检测任务拆解为两个子任务:
- “What”:分类任务 → 猫、狗、车等类别 → 用 Softmax + 分类损失
- “Where”:回归定位任务 → 边界框 (x, y, w, h) → 用 L2 回归损失
实现方式:
- 输入图像 → 卷积神经网络提取特征(通常预训练于 ImageNet)
- 得到 4096 维特征向量 → 分两个分支:
- 分类分支(4096 → 类别数,如 1000)→ 输出类概率
- 回归分支(4096 → 4)→ 输出边界框坐标
多任务损失函数(Multitask Loss):
- Softmax Loss(分类)+ L2 Loss(回归)→ 加权求和
- 为什么要加权?为了平衡分类损失和回归损失的影响力
适用情况:
如果你只检测一个物体(如某些简单应用),这种架构虽然简单,但效果很好!
二、检测多个物体(Detecting Multiple Objects)
对应图:第二张图(猫、狗、鸭子)
新挑战:
- 每张图里可能有不同数量的物体
- 猫图 → 1 个物体 → 4 个数(边界框)
- 狗+猫图 → 3 个物体 → 12 个数(3×4)
- 鸭子图 → 多个物体 → 很多个数
问题:
CNN 本身结构固定,无法直接输出可变数量的结果
所以需要设计能动态预测多个物体的机制。
早期的检测窗口
滑动窗口法(Sliding Window)
- 滑动窗口的基本概念:
- 假设我们有一个H×W大小的图像,并且希望在这个图像上使用大小为 h × w 的框(即检测窗口)。
- 对于每一个框,我们都可以在图像上放置它的位置。
- 计算这个框可以放置的x和y坐标位置:
- x 方向:可以放置的位置数为 W - w + 1(其中 W 是图像宽度,w 是框的宽度)
- y 方向:可以放置的位置数为 H - h + 1(H 是图像高度,h 是框的高度)
- 计算可能的框数:
- 对于大小为 h × w 的框,可以放置的总位置数为:
- 这会导致一个平方级别的增长,即随着图像分辨率的增加,可能的窗口数量会增加得非常快。
- 问题的放大:考虑不同大小和长宽比的框:
- 不仅要考虑固定大小的框,还要考虑所有可能的框的尺寸和长宽比。
- 所有可能的框的数量会增长到四次方的数量级,具体来说:
- 这意味着图像的像素数量的平方会影响计算量。
- 如果是 800 x 600 的图像,可能的框数大约为 5800 万个,这意味着需要进行极为庞大的计算。
- 计算不可行性:
- 滑动窗口法要求我们对每个可能的区域应用 CNN 进行分类。假设我们尝试对每个区域进行前向传播,计算量将会极为庞大。
- 不可行:即使我们拥有无限的计算能力,也不可能在合理的时间内处理如此多的窗口。
- 重复计算的问题:
- 即使能够进行如此大量的计算,不同位置的窗口可能会多次检测到同一个物体。
- 这导致了冗余的计算和重复的结果,进一步增加了计算负担。
如何解决?非最大抑制(Non-Maximum Suppression, NMS)
- 为了解决重复检测的问题,可以使用 非最大抑制(NMS)。
- NMS 通过去除重复框(尤其是重叠区域中的多个框)来保留最优的边界框,从而减少冗余。
- 这样能够有效提高检测效率,并减少计算量。
区域提议(Region Proposals)
区域提议的概念
- 问题的提出:
- 在物体检测中,如果要评估图像中每个可能的区域,计算量将会非常庞大,几乎不可能实现。
- 解决方法是:使用区域提议。这是一种通过外部算法,生成一小组高概率覆盖所有物体的候选区域的方法。
- 区域提议的目标:
- 找到一组区域(提议),这些区域很有可能包含图像中的所有物体。
- 这些候选区域将远远少于图像中的所有可能区域,从而减少计算量。
- 区域提议的早期方法:
- 早期的区域提议方法通常通过一些图像处理技术(如寻找“blob-like”区域、边缘检测等)来推测哪些区域可能包含物体。
- 这些方法不依赖于深度学习,而是基于传统的图像处理技术。
- 选择性搜索(Selective Search):
- 选择性搜索是一种著名的区域提议方法,它能在几秒钟内为每个图像生成约 2000个候选区域。
- 它通过合并相似区域和多尺度的图像处理,寻找可能包含物体的区域。
- 这些提议有很高的概率覆盖图像中的所有物体。
- 实际应用:
- 区域提议方法为物体检测网络提供了候选区域,接下来可以使用深度神经网络(CNN)进行更精确的物体分类和定位。
- 未来发展:
- 需要注意的是,区域提议方法最终被深度学习模型所取代,现代物体检测框架(如 Faster R-CNN)直接通过神经网络来生成提议。
R-CNN(Region-based Convolutional Neural Network)的核心思想
目的
利用区域提议(Region Proposals)和卷积神经网络(CNN),构建一个可以对每个候选区域进行分类和位置微调的目标检测器。
R-CNN 的工作流程
1. 输入图像(Input Image)
首先,从整张图像开始。
2. 生成区域提议(Region Proposals)
使用如 Selective Search 这类算法,生成约 2000 个候选区域(ROI,Region of Interest),这些区域有可能包含目标。
3. 将每个候选区域裁剪并缩放到固定尺寸(如 224x224)
由于神经网络要求输入尺寸一致,所以无论原始区域多大,都被拉伸成统一大小。
4. 每个区域独立送入 CNN
每个裁剪区域单独通过 CNN 处理,提取特征并进行预测。
输出两种信息(多任务):
1. 分类(Class):
CNN 输出该区域属于哪一类(包括“背景”类)。
2. 边界框回归(Bounding Box Regression):
- CNN 还会输出一组位置微调参数,用于修正输入的区域框,使它更贴近真实物体。
边界框回归的数学细节
问题:
候选框(region proposals)并不总是完美包住物体,需要微调。
解决方案:输出一个 变换向量 (tx, ty, th, tw),对原始框做细微调整。
- 原始框(proposal)参数是:
- 中心点坐标 (px, py)
- 宽高 (pw, ph)
- 最终输出框(output box)为:
- 位置调整:
- 尺寸调整(采用 log 空间):
这个方式的好处:
- 变换是相对于候选框大小进行的,具有尺度不变性(scale-invariant),适应候选区域的缩放变化。
- 如果输出 (tx, ty, th, tw) = (0, 0, 0, 0),表示原始框就很好,不需要改动。
R-CNN 训练阶段流程(Train-time Pipeline)
1. 候选区域生成(Region Proposals)
- 使用Selective Search等方法生成多个候选框(Region Proposals)。这些候选框是可能包含物体的区域,但并不完美,可能需要进一步调整。
- 在典型的R-CNN中,会生成大约2000个候选框。
2. RoI Pooling
- 每个候选框从图像的特征图中提取对应区域的特征。由于候选框的大小和形状不同,需要进行RoI Pooling(Region of Interest Pooling)操作。
- RoI Pooling将每个候选框区域裁剪成固定大小的特征图(例如 7x7xN),这样每个候选框就可以被传递到同一网络中进行处理。
3. 通过CNN提取特征
- 每个候选框的区域特征图通过CNN(通常是VGG或ResNet)进行进一步处理,得到该区域的高层次特征表示。CNN共享卷积层,提取图像中所有区域的通用特征。
4. 分类和回归
- 在经过RoI Pooling和CNN处理后,提取到的特征被送入两个并行的全连接层:
- 分类分支:用来预测每个候选框的物体类别(例如,猫、狗、车等),输出每个类别的概率。
- 边框回归分支:用来预测每个候选框的四个变换值(tx, ty, tw, th),用于调整候选框的位置和尺寸。
5. 损失函数
- R-CNN的训练过程通过一个综合的损失函数进行优化:
- 分类损失(
):衡量分类任务中的预测误差,通常使用交叉熵损失函数。 - 回归损失(
):衡量边框回归任务中的预测误差,通常使用平滑L1损失(Smooth L1 loss)来优化框的位置和尺寸。 - 综合损失函数:
其中,
6. 训练过程
流程如下:
- 准备训练数据:
- 同样先对每张训练图像生成 2000 个候选框(Region Proposals)
- 然后将每个候选框与“真实标注框”(Ground Truth)进行比较(通过 IoU)
- 标签划分(关键点!):
- 若候选框与某个真实框的 IoU ≥ 0.5 → 认为这是“正样本”
- 分类标签设为该物体的类别(猫/狗/人…)
- 同时计算出框的偏移量(ground truth 的 tx, ty, tw, th)
- 若 IoU < 0.3 → 认为是“背景”,标签为 background 类
- 中间区域可忽略或特殊处理
- 训练目标:
- 分类分支 → 学会判断这个框是什么类别或是否是背景
- 回归分支 → 学会如何微调框的位置让它更贴近真实框
- 多任务损失(Multi-task Loss)同时优化两者
- 参数更新:
- 所有候选框都输入同一个 CNN
- 用多任务损失反向传播,优化 CNN 的参数
总结
R-CNN的训练阶段主要涉及以下几个步骤:
- 使用Selective Search生成候选框。
- 对每个候选框进行RoI Pooling,得到固定大小的特征图。
- 通过CNN提取图像的高层次特征。
- 使用两个分支进行并行的分类和边框回归。
- 使用综合的损失函数(分类损失 + 回归损失)来优化网络。
- 通过训练数据进行反向传播,优化网络参数,最终得到能够准确分类和回归边框的模型。
R-CNN 测试阶段的流程(Test-time Pipeline)
输入:一张 RGB 图像
输出:一组最终检测结果(类别 + 边界框)
主要步骤如下:
1. 生成候选区域(Region Proposals)
- 使用 Selective Search(或其他区域提议方法)在 CPU 上运行,为每张图片生成约 2000 个候选区域(ROI)。
2. 预处理每个候选区域
- 将每个区域裁剪并缩放到 固定尺寸(如 224x224),这与分类网络的输入尺寸一致。
3. 逐个送入 CNN
- 对每个预处理后的区域,独立通过 CNN,输出两类信息:
- 分类分数(是否是某类物体或背景)
- 边界框变换参数(用于微调候选框)
选择最终输出框的策略(用在 test-time)
由于候选框太多(~2000个),我们需要选出一部分框作为最终预测结果,这里有几种做法:
策略一:按背景分数筛选
- 对所有候选框,根据“背景”分类得分进行排序,保留背景得分最低的前 K 个框(最不像背景 → 更可能是目标)。
策略二:每类设定分类阈值
- 分类器会为每个候选框输出一整套类别得分(含背景),我们可以为每个类设置一个阈值:
- 若某框对某类得分 > 阈值,就保留这个框为该类的检测结果;
- 否则丢弃。
这两种方式都不是训练阶段用的,而是测试阶段后处理用的,不影响模型训练本身。
CNN 的权重共享(Weight Sharing)
- 对于每个候选区域,使用同一个 CNN 网络、同一套参数。
- 为什么要共享?
- 每张图的候选框数量不固定,无法为每个候选框单独训练一个 CNN。
- 所以,只训练一个 CNN,把所有裁剪区域都用这个 CNN 处理。
⚠️ 注意:top-k筛选或阈值这些操作只在测试时使用,训练时会对所有候选区域进行训练。
其它关键细节补充:
- 区域位置坐标不会直接输入 CNN,因为我们希望 CNN 对平移和尺度变化具有不变性(translation & scale invariance)。
- 所以框的变换参数是相对原框尺寸计算的,例如:
为什么把候选区域缩放到固定大小(如224x224)?
- 这是 CNN 固有的结构要求(与图像分类中一样),输入尺寸必须一致。
IOU
一、IoU 是什么?
IoU 是 Intersection over Union 的缩写,中文通常叫做交并比,是目标检测中用来比较两个框相似度的标准指标。
也叫:
- Jaccard 相似度(Jaccard similarity)
- Jaccard 指数(Jaccard index)
二、怎么计算 IoU?
IoU = 两个框的 交集面积 / 并集面积
非极大值抑制(Non-Max Suppression, NMS)
一、问题背景:多个重叠框
问题:
- 现实中目标检测模型(如 R-CNN、YOLO)通常会对同一个物体输出多个高度重叠的框(overlapping boxes),每个框都有一定的置信度。
- 比如:对于一只狗,模型可能输出了三个置信度分别为 0.9、0.75、0.7 的框,但这些框其实是在指同一个狗。
结果:
- 会造成冗余重复检测,而我们真正想要的,是对一个物体只保留一个最佳框。
二、解决方案:Non-Max Suppression(NMS)
思路:只保留每组重叠框中置信度最高的那个
基本步骤如下(贪心算法):
- 选择置信度最高的框(比如蓝框:P(dog)=0.9)
- 与所有其他框计算 IoU(交并比)
- 移除与当前框 IoU 大于设定阈值(如 0.7)且置信度更低的框
- 这些大概率是“重复检测”
- 重复步骤1,直到所有框都处理完为止
举例说明(如图):
- 假设我们有4个检测框,分别为蓝、橙、紫、黄
- 分别对应的 P(dog) 是 0.9、0.78、0.75、0.7
- 首先选中蓝框(0.9),然后:
- 蓝框与橙框 IoU = 0.78(> 0.7)→ 删掉橙框
- 蓝框与紫框、黄框 IoU 分别为 0.05、0.02 → 保留
- 然后继续处理紫框,与黄框 IoU = 0.74(也删掉)
- 最终保留蓝框和紫框作为两个检测结果
⚠️ 三、NMS 的问题:在拥挤场景下表现不佳
第二张图展示的是“人群图像”,这时候会遇到NMS 的局限性:
- 问题:如果图中存在大量相互重叠的物体(如密集人群),那么:
- 真实框之间本来就有较高的 IoU(比如两个紧挨着的人)
- 但 NMS 会把高 IoU 的框误判为“重复检测”,从而误删掉正确的目标框
- 结论:NMS 在**拥挤场景(crowded scenes)**下,可能会“误杀”掉一些本来就属于不同目标的框。
目前计算机视觉界仍在寻找更好的替代方法,例如 Soft-NMS、Learned-NMS 等都在尝试解决这个问题。
平均精度(AP)和平均平均精度(mAP),它比分类任务中的 Accuracy 复杂得多,但对于检测质量评估是不可替代的。
一、为什么不能用 Accuracy?
在图像分类中,模型每次输出一个类别,我们只需看它是否等于真实类别(ground truth),计算 accuracy 就行了。
但在目标检测中,模型输出的是:
- 一张图中多个检测框
- 每个框都有:
- 类别预测
- 位置信息(边界框)
- 置信度分数(confidence)
因此,必须同时评估 “有没有检测到 + 框准不准 + 分数排得好不好”。这就需要一个更复杂但更全面的指标 —— mAP。
二、定义:Mean Average Precision(mAP)
mAP 是多类任务中每类的平均精度(AP)的平均值:
mAP = 多个类别的 AP 的平均值
而 AP(Average Precision)是:
PR 曲线下的面积(Area under the Precision-Recall curve)
三、计算流程(以某一类别为例,比如“dog”):
步骤 1:运行目标检测器(检测 + NMS)
- 对测试集所有图片运行目标检测器,去重重叠框(NMS)
- 得到所有“dog”检测框,按置信度排序(从高到低)
步骤 2:遍历每个检测框,计算 Precision 和 Recall
对于每一个预测框(从高分到低分):
- 如果该框与某个 Ground Truth 框的 IoU > 0.5:
- 记为 TP(True Positive),并移除该 GT 框
- 否则,记为 FP(False Positive)
每遍历一个框,都可以算出:
- Precision = TP / (TP + FP)
- Recall = TP / GT 总数
于是得到多个 PR 点,绘制 PR 曲线。
步骤 3:计算 AP
- 把 PR 曲线下面的面积求出来
- 即为该类的 AP
四、图例说明
如图中例子:
- 有 5 个预测框,得分分别为:0.99, 0.95, 0.90, 0.5, 0.10
- 有 3 个真实狗狗框(GT)
标注绿色表示是 TP,红色为 FP:
- TP = 3,FP = 2
- 最终 precision = 3/5 = 0.6,recall = 3/3 = 1.0
用这些 TP 和 FP 计算出的 PR 曲线,面积(灰色区域)就是 AP(例子中为 0.86)
五、什么情况能得到 AP=1.0?
必须满足:
- 所有正确的检测框(TP)排在前面
- 每个 TP 检测框都能匹配某个真实框,IoU > 0.5
- 没有任何错误预测(FP)
也就是说,完美预测 + 排序完美 + 没有多余检测。
六、mAP = 所有类别 AP 的平均
一个检测模型通常不止检测“dog”,还会有“person”、“car”等多个类。
- 对每个类都算一遍 AP
- 然后再平均,得到最终的 mAP 分数
⚠️ 七、为什么还有不同 IoU 阈值?
默认 IoU > 0.5 就算检测成功,但:
- 这样可能“框得很粗略”也算成功
- 所以,COCO 等数据集会要求在 IoU 从 0.5 到 0.95 的多个阈值下分别算 mAP,再取平均
这叫做:
mAP@[.5:.95] —— 更严格、更公平的评价方
Precision 和 Recall 的“互相牵制关系”。
Precision(精准率)
定义: 在所有被模型预测为“正类”的结果中,有多少是真正的正类。
公式是:
举例:
你预测有 10 个狗,结果里面只有 6 个是真的狗,其余 4 个是误报的猫、人等。那么 Precision = 6 / 10 = 0.6。
Recall(召回率)
定义: 在所有真实为“正类”的样本中,有多少被模型成功预测出来了。
公式是:
举例:
图片中一共有 8 只狗,你预测中了 6 只,还有 2 只没找到。那么 Recall = 6 / 8 = 0.75。
Precision 和 Recall 的关系:一种“跷跷板”现象
- 提高 Precision:要减少 False Positives ➝ 变得保守,不轻易预测正类。
- 提高 Recall:要减少 False Negatives ➝ 变得激进,尽量把所有正类都找出来。
但二者通常不能同时提高,一个高了,另一个可能会低。
Precision vs Recall 曲线(PR Curve)
- 把模型的预测结果按置信度(score)排序。
- 从高到低依次取前 N 个预测框,看此时的 Precision 和 Recall。
- 每一组结果就是 PR 曲线上的一个点。
- 整条曲线下的面积,就是 Average Precision(AP)。
- 所有类别的 AP 平均值,就是 mAP(mean Average Precision)。
Fast R-CNN
这段讲的是 Fast R-CNN 的原理与流程,它是为了解决传统 R-CNN 的速度慢的问题而提出的优化版本。下面我来详细解释一下它的背景和改进思路:
一、背景问题:R-CNN 太慢了
传统 R-CNN 的流程是:
- 从输入图像中用如 Selective Search 提出 ~2000 个候选框(Region Proposals)。
- 对每一个候选框单独裁剪图像,warp 成相同大小(比如 224x224)。
- 每个裁剪出来的区域单独送入 CNN 网络,得到分类结果和边界框回归(BBox Regression)。
问题:
对每一张图像要进行 ~2000 次 CNN 前向传播(Forward Pass),计算量太大,不可能实时运行,因此被戏称为 “Slow R-CNN”。
二、Fast R-CNN 的优化核心思想
把“先裁剪再做CNN”的流程换成“先整图做CNN,再裁剪特征图”。
原理流程如下:
- 整张图像先通过一次 CNN(比如 ResNet、AlexNet、VGG),生成整张图的特征图(Feature Map)
- 这个 CNN 网络被称为 Backbone Network。
- 候选框(RoIs)依然通过 Selective Search 得到(如 2000 个),但不再直接裁剪原图像,而是:
- 把候选框映射到特征图上,在特征图上进行 Crop + Resize,得到特征区域。
- 每个特征区域(RoI)送入一个轻量的子网络(Per-Region Network),输出:
- 该区域的类别(Classification)
- 该区域的边界框回归(BBox Regression)
例如:如果使用 AlexNet,前五个卷积层是 backbone,最后两个全连接层是 per-region network。
三、Fast R-CNN 的优点
- 只对整张图像做一次 CNN 特征提取,避免了 2000 次重复计算。
- 大大减少了计算量,速度提升明显。
- 对多个区域(RoIs)复用同一张特征图,提高了效率。
- 保留了区域提议的精准性,且可以端到端训练。
原图 —> 整图卷积(Backbone) —> 特征图
↓
区域提议(RoIs)→ 映射到特征图 → 裁剪+Resize
↓
每个 RoI 送入轻量分类+回归网络
**候选区域(Region of Interest, RoI)中“裁剪”出来用于后续分类和边框回归的关键技术——RoI Pooling(RoI池化) 和 RoI Align
为什么要做 RoI Pooling 或 RoI Align?
- 在 Fast R-CNN 中,整张图像只经过一次 CNN(Backbone)提取特征图,但每个候选框(Region Proposal)形状不一,我们需要把这些不同大小的框变成统一尺寸(比如 7×7×C)才能送入后续的全连接层分类。
- 所以我们要 对特征图中的每个 RoI 区域进行“裁剪 + 尺寸对齐”操作。这一步就是 RoI Pool 或 RoI Align 做的事。
一、RoI Pooling 的原理
步骤解释:
- **从原图中提取 RoI
- 比如输入图是 3×640×480,RoI 是一个矩形框。
- 整张图通过 CNN 提取特征图
- 比如输出特征图大小是 512×20×15(C×H×W)。
- 将 RoI 映射到特征图上(投影)
- 这是因为特征图空间更小(20×15),我们需要把 RoI 按比例投影进这个小空间中。
- 对投影后的区域进行“对齐”(snap)
- 将其划分成固定数量的网格(如 2×2 或 7×7)。
- 每个子区域内做最大池化(max pooling)得到一个数字。
- 输出固定形状的特征张量(比如 512×7×7)
- 不管输入的 RoI 是大是小,最终都变成同一个尺寸的特征,用于后续分类和框回归。
优点:简单、可以反向传播。
缺点:因为“snapping”对齐操作,可能会产生量化误差,导致边缘信息丢失,定位不准。
二、RoI Align 的改进
改进点:
- 不再做“snapping”(不对齐到整数网格)
- RoI 区域划分为等大小子区域,但不强行对齐到网格。
- 每个子区域采样若干点(如 2×2 个点)
- 每个点可能落在两个格子之间,比如坐标是 (6.5, 5.8)。
- 使用双线性插值(Bilinear Interpolation)获取精确值
- 每个采样点不是简单选最大值,而是根据周围四个点做加权平均。
- 数学公式如图所示,本质是:
- 输出同样是固定大小的特征张量(如 512×7×7)
优点:精度更高,对边界敏感,适合检测小物体
方法 | 是否对齐网格 | 是否可微分 | 精度 | 是否常用 |
---|---|---|---|---|
RoI Pool | 是(snap) | 是 | 较低 | 旧方法 |
RoI Align | 否(更精确) | 是 | 高 | 现代标准 |
Region Proposal Network
Region Proposal Network(RPN)是 Faster R-CNN 的关键组件,用来生成候选框。主要流程如下:
Step 1:提取特征(Backbone CNN)
我们先把输入图像(比如一只猫)输入一个 卷积神经网络(Backbone CNN),如 ResNet 或 VGG,得到一张特征图(feature map),比如大小是 512 x 20 x 15,代表 512 个通道、20 行、15 列。
Step 2:生成 Anchor Boxes(锚框)
在特征图的每个位置(格子),想象我们放置一个或多个 锚框(Anchor Box)。锚框是一些 预定义的框,在不同位置、尺度和长宽比上滑动。
比如,每个位置放 9 个不同大小和形状的 anchor。
就像在地图上的每个格子都放一组“探测器”,看那一块区域有没有物体。
Step 3:判断有没有物体 + 回归框位置
RPN 在每个 Anchor 上做两件事:
1. 分类任务:
判断这个 anchor 有没有覆盖到一个物体,用一个小卷积网络输出:
- Anchor is object? 二分类(是/不是)
2. 回归任务:
如果是物体,对 anchor 做一个微调(box transform),让它更贴近真正的物体框(即 Ground Truth)。输出:
- Box transforms 4 个数:偏移量(Δx, Δy, Δw, Δh)
这两个输出都是通过卷积层在每个位置进行的,速度快,而且可以端到端训练。
Step 4:多 anchor 提升表达能力
一个 anchor 可能太小或太大,不能适配不同物体,所以我们每个位置(格子)通常放多个 anchor(如 k=9),每个有不同尺寸和长宽比。
- 分类输出:K x H x W
- 回归输出:4K x H x W
Step 5:筛选候选框(测试时)
测试时,我们会:
- 根据分类得分排序所有 anchor;
- 用得分前 top ~300 个做候选框(region proposals);
- 送入后续 Fast R-CNN 进行分类与精确定位。
总结:
- Backbone 提取整图特征;
- RPN 用卷积网络在特征图每个位置生成多个 anchor;
- 每个 anchor 输出:是不是物体 + 微调位置;
- 最后根据得分挑选前几个作为 Region Proposals。
这样一来,整个区域建议流程就不需要 CPU 上的慢速 Selective Search,而是 完全由神经网络自动学出来了,速度更快,精度更高。
Faster R-CNN 工作流程
Faster R-CNN 是一种集成了 Region Proposal Network (RPN) 的目标检测算法。与 Fast R-CNN 不同,Faster R-CNN 不依赖于外部的候选框生成方法(如 Selective Search),而是通过 Region Proposal Network (RPN) 来自动生成候选框,极大地提高了检测的效率和速度。
Faster R-CNN 的工作流程
Faster R-CNN 的流程可以分为以下几个关键步骤:
1. 输入图像:
- 输入图像经过 卷积神经网络 (CNN),通常使用预训练的网络(例如 ResNet、VGG 等)提取特征,生成 特征图。这些特征图包含了图像中的空间信息和语义信息。
2. Region Proposal Network (RPN):
- Region Proposal Network (RPN) 是 Faster R-CNN 的核心。RPN 的任务是生成 候选框(Region Proposals),也就是可能包含物体的区域。
- Anchor Box:在特征图的每个位置上,RPN 会放置多个不同尺度和长宽比的 anchor box。这些 anchor box 的目的是预测是否有物体存在,或者该区域是否应包含物体。
- RPN 的工作流程:
- 对每个 anchor box,RPN 会进行两项预测:
- 分类预测:判断该 anchor box 是否包含物体。通常是二分类问题,输出“是物体”或“不是物体”。
- 回归预测:如果该 anchor box 被认为包含物体,RPN 会进一步进行 边框回归,通过回归预测调整 anchor box 的位置和大小,使其更精确地框住物体。
- 最终,RPN 会输出一组 候选框(即 Region Proposals),这些候选框会根据预测得分进行排序,通常选取得分较高的几个候选框作为最终的候选区域。
3. RoI Pooling:
- 在获取了候选框之后,Faster R-CNN 需要将这些候选框映射回 特征图 上。
- 由于候选框的尺寸可能不一致,需要进行 RoI Pooling(Region of Interest Pooling),将每个候选框区域的特征池化成固定尺寸。
- 通过 RoI Pooling,Faster R-CNN 将不同大小的候选框区域映射到固定大小的特征向量(例如 7x7xN 的尺寸),以便后续的全连接层处理。
4. 分类与边框回归:
- 对于每个候选框,经过 RoI Pooling 后的特征会送入 全连接层(Fully Connected Layer)。
- 分类:网络会对每个候选框进行分类,判断该框中包含的物体属于哪个类别(比如猫、狗等)。这一步是多分类问题。
- 边框回归:网络还会进行边框回归,调整候选框的精确位置,使其更贴合物体的实际边界。
5. 输出最终结果:
- 通过分类和边框回归,Faster R-CNN 会输出最终的 检测结果,即每个物体的类别和准确的边界框。
6. 训练过程:
- 在训练过程中,Faster R-CNN 采用了 多任务损失函数,该损失函数包含两部分:
- 分类损失:用于分类任务,通常是交叉熵损失。
- 边框回归损失:用于边框回归任务,通常是平滑L1损失。
- 训练时,通过 反向传播,优化整个网络的参数,包括 RPN 和 全连接层。
Faster R-CNN 的优势:
- 全自动化候选框生成:通过 RPN,Faster R-CNN 不再依赖外部的候选框生成方法(如 Selective Search),大大加快了速度。
- 共享计算:Faster R-CNN 中的 RPN 和 分类网络 共享卷积特征,这使得计算更加高效。
- 端到端训练:Faster R-CNN 允许整个网络(包括 RPN 和 目标分类与边框回归部分)端到端训练。
总结
Faster R-CNN 通过引入 Region Proposal Network (RPN) 自动生成候选框,结合 CNN 提取图像特征,利用 RoI Pooling 和 全连接层 进行目标分类和边框回归,从而大幅提高了目标检测的速度和精度。它解决了 Fast R-CNN 中候选框生成效率低的问题,成为了一种非常高效的目标检测方法。
Faster R-CNN的训练和测试阶段流程区别:
训练阶段(Training Phase)
- 候选框生成(Region Proposals)
- RPN网络:在训练阶段,Region Proposal Network(RPN) 是关键组件。RPN是一个全卷积网络,负责从图像的特征图中生成候选区域(Region Proposals)。该网络通过滑动窗口的方式扫描特征图,为每个位置生成多个锚框(anchor boxes),并对这些锚框进行分类(是否包含物体)和回归(调整框的位置)。
- 锚框调整:RPN会输出每个锚框的分类结果(物体/背景)和回归结果(坐标调整),从而得到候选框。
- 候选框选择
- RPN生成的候选框会通过 非极大值抑制(NMS) 被筛选出。NMS会去除与其他框重叠过多的框,保留最优的候选框。
- RoI Pooling
- 通过RoI Pooling技术,将RPN输出的候选框区域映射到固定大小的特征图(例如7x7xN),为后续的分类和回归提供输入。
- 全连接层(FC层)
- 对于每个候选框,经过RoI Pooling后的特征图会送入全连接层,用来分别进行:
- 分类:预测候选框中包含的物体类别(例如猫、狗等)。
- 边框回归:预测候选框的调整量,即预测变换向量 tx, ty, tw, th,以使得候选框更精确地拟合物体的真实边界。
- 损失函数
- 在训练过程中,模型通过一个综合的损失函数进行优化。该损失函数包括:
- RPN的损失:包括RPN的分类损失(物体/背景)和回归损失(边框调整)。
- 检测的损失:包括分类损失和回归损失,分别用于预测物体类别和回归边框。
测试阶段(Testing Phase)
- 候选框生成(Region Proposals)
- 在测试阶段,RPN会生成候选框,过程与训练阶段相同。RPN基于图像的特征图生成多个锚框,并对其进行分类和回归。与训练阶段不同,测试阶段的RPN通常是预训练好的,并且生成的候选框不会与真实标签进行比较,而是用于后续的检测任务。
- Top-K筛选与阈值过滤
- Top-K:在测试阶段,通过RPN生成的候选框会被根据得分排序,选取得分前K个框。
- 阈值过滤:此外,还会根据设定的分类阈值(例如0.5)来过滤掉得分较低的框。这样做的目的是只保留具有较高置信度的候选框。
- RoI Pooling与全连接层
- 和训练阶段相似,测试阶段的每个候选框通过RoI Pooling映射到固定大小的特征图,然后通过全连接层分别进行分类和边框回归。
- 分类分支输出每个框所属类别的概率,回归分支输出框的调整参数(tx, ty, tw, th)。
- 非极大值抑制(NMS)
- 在测试阶段,通常会使用 非极大值抑制(NMS) 来去除冗余的候选框。NMS会根据每个候选框的分类得分,去除与其他框重叠度较高的框,保留得分最高的框。
- 最终检测结果
- 测试阶段的最终输出是调整后的边框及其对应的类别预测。通过NMS筛选后的框被用于最终的物体检测结果输出。
训练和测试的关键区别:
- 候选框生成:
- 训练时,RPN生成候选框并同时与真实框进行比较,优化RPN的分类和回归。
- 测试时,RPN根据输入图像生成候选框,但没有真实框进行比较,只是生成框和输出预测。
- RoI Pooling和全连接层:
- 训练时,RoI Pooling后得到的特征图通过全连接层进行分类和回归,同时计算损失。
- 测试时,RoI Pooling后得到的特征图通过全连接层进行预测分类和边框回归,但不再计算损失。
- 候选框筛选:
- 训练时,通过RPN筛选出高质量的候选框,并计算每个框的分类和回归损失。
- 测试时,使用Top-K和阈值过滤来筛选候选框,并通过NMS去除冗余框,最终输出高质量的检测结果。
总结
- 训练阶段:RPN生成候选框并优化其分类和回归结果,损失函数包括RPN损失、分类损失和回归损失。
- 测试阶段:RPN生成候选框,通过Top-K选择和阈值过滤后,使用NMS去除冗余框,最终输出预测结果。
这些区别使得Faster R-CNN在测试时能够高效地生成候选框,并且通过RPN加速了物体检测过程,相比于传统方法(如Selective Search),大大提高了检测速度。
单阶段物体检测(Single-Stage Object Detection)
1. 基本概念
- Single-Stage Detector:通过 单一网络,直接完成物体的分类和边框回归,不需要像Faster R-CNN那样分成两个阶段(候选框生成和分类回归)。
- RPN与单阶段检测的区别:与RPN通过生成区域提议不同,单阶段方法直接对每个锚框进行分类,确定它属于哪个物体类别(或背景)。
2. 流程
- 输入图像:首先输入图像,通过一个 骨干网络(Backbone CNN) 提取图像特征(例如 512x20x15 的特征图)。
- 生成锚框(Anchor Boxes):在特征图的每个位置生成多个不同尺度和比例的锚框。每个位置上有 K 个锚框,每个锚框是一个可能的物体区域。
- 分类任务:
- 对每个锚框,进行分类,判断该锚框属于哪一类物体(或是否为背景)。假设有 C 个物体类别,则每个锚框将有 C+1 个类别得分(包括背景类别)。
- 回归任务:
- 对每个锚框,输出 4 个回归变换参数(例如 tx, ty, tw, th),用于调整锚框的位置和尺寸,使其更精确地拟合真实的物体边界。
- 输出:
- 网络为每个锚框生成类别得分和回归变换,最终输出分类和回归的结果。
3. Anchor Category 和 Box Transforms
- Anchor Category:每个锚框的类别得分,用来决定该锚框属于哪一类别或是否为背景。
- 输出格式为:(C+1) \times K \times 20 \times 15,其中 C 是物体类别数,K 是每个位置的锚框数量。
- Box Transforms:每个锚框的回归变换,用于调整其位置和尺寸。
- 输出格式为:C \times 4K \times 20 \times 15,其中 C 是类别数,K 是每个位置的锚框数。
4. 优势
- 简化流程:通过将分类和回归任务整合到一个阶段,避免了像Faster R-CNN那样复杂的两阶段流程。
- 提高效率:由于不需要候选框生成的第二阶段,减少了计算开销,使得检测过程更快速。
- 实时性:单阶段检测方法通常能够在 GPU 上实时运行,适用于需要快速响应的应用场景。
5. 类别特定回归(Category-Specific Regression)
- 在进行回归时,可以采用 类别特定回归(category-specific regression),为每个类别的锚框预测不同的回归变换参数。与 类别无关回归(category-agnostic regression)相比,类别特定回归可以让模型更好地适应不同类别物体的尺寸和形状。
6. 常见的单阶段检测方法
- YOLO(You Only Look Once):一种广泛应用的单阶段物体检测方法,它将图像分成网格并直接预测每个网格内的物体类别和边框。
- SSD(Single Shot MultiBox Detector):另一种单阶段物体检测方法,通过在多个尺度的特征图上进行检测,能够同时检测不同大小的物体。
7. 总结
- 单阶段物体检测 通过在单一网络中同时进行 物体分类 和 回归,大大简化了检测流程。
- 这种方法提高了效率,特别是在 实时物体检测 中具有显著优势。
- 通过 类别特定回归,模型能够更好地适应不同类别物体的检测需求。
总结
1. 物体检测的复杂性
- 物体检测是一个 复杂的领域,涉及很多选择和决策。主要的选择包括:
- 方法类型:
- 两阶段方法(如 Faster R-CNN):通过两阶段(生成候选区域和后续的分类/回归)进行检测。
- 单阶段方法(如 SSD):直接对图像中的每个区域进行分类和回归,无需单独的候选框生成阶段。
- 混合方法(如 RFCN):结合了两阶段和单阶段的特点。
- 骨干网络架构:选择合适的网络架构(如 ResNet、Inception、MobileNet、VGG 等)对性能有很大影响。
- 超参数:例如图像分辨率、锚框的数量和尺寸、IoU阈值等,都会影响检测效果。
2. 2017年论文的贡献
- 在2017年,一篇重要的论文重新实现了当时所有的物体检测方法,并进行公平的对比。论文中提供了一个图表,比较了不同方法在 GPU测试时的速度 和 平均精度均值(mAP) 之间的关系。
- 图表分析:
- X轴:测试时的速度。
- Y轴:平均精度均值(mAP)。
- 颜色:表示使用的骨干网络架构(如 ResNet、Inception、VGG 等)。
- 形状:表示方法类型(两阶段方法或单阶段方法)。
3. 结论与观察
- 两阶段方法(如 Faster R-CNN):
- 更准确,因为它有更多的机会查看图像并生成候选框。
- 更慢,因为需要为每个候选框进行独立计算。
- 单阶段方法(如 SSD):
- 更快,因为它对整个图像共享计算,而不需要为每个候选区域单独计算。
- 较不准确,因为它只有一个全局的视角,不能像两阶段方法那样多次查看图像信息。
- 大模型效果更好:
- 比如,使用 ResNet-101 或 Inception-ResNet-v2 等更大的骨干网络,性能通常会提高。
- 小型网络(如 MobileNet)则通常不如大型网络。
4. 2019年的进展
- GPU加速:随着 GPU 性能提升,物体检测的计算速度有了显著提高,训练时间也能变得更长。
- Feature Pyramid Networks (FPN):FPN 是一种提升多尺度特征表示的技术,可以大大提高检测精度。
- Faster R-CNN + FPN:这种结合方法在2019年表现出色,在 COCO 数据集 上的 mAP 达到了 42,测试时的运行时间为 63毫秒。
- 更大的网络(如 ResNeXt 101):使用更大的网络可以进一步提高精度。
5. 单阶段方法的进步
- 自2017年以来,单阶段方法(如 SSD)有了很大的提升,现在它们的表现接近于两阶段方法。
- 一些现代的单阶段方法能够与两阶段方法媲美,甚至在某些情况下超过两阶段方法。
6. 更大模型的趋势
- 大型模型(如 152层的 ResNeXt,使用 FPN 的网络)能够达到 49 的 mAP,性能进一步提高。
- 使用 多尺度、多方向的测试图像 和 模型集成(ensemble) 技术,可以进一步提高性能。
7. 当前的最先进方法
- 当前,物体检测领域的最先进方法已经取得了巨大的进展,mAP 已经从2017年的 35 提升到了 55,这代表了该领域的飞跃性进展。
8. 不建议自己实现物体检测
- 由于物体检测涉及大量的 超参数调优 和 技巧,如果你在实际应用中需要物体检测, 不建议自己从头实现,因为涉及的技术非常复杂,且容易出错。
- 推荐使用 开源的物体检测框架:
- TensorFlow Object Detection API:由 Google 提供,支持多种物体检测方法。
- Detectron2:由 Facebook 提供,基于 PyTorch,实现了最新的物体检测方法。许多最先进的模型(如图中的绿色和紫色点)都可以直接在 Detectron2 中使用。
9. 总结
- 物体检测领域持续发展,研究者不断提出新的方法和技巧来提高精度和速度。
- 在实践中,建议使用现有的高质量开源框架,如 TensorFlow 和 Detectron2,而不是从零开始实现。
区域提议和 Ground Truth 的配对和回归
一、区域提议与 Ground Truth 的匹配方式
两种情况:
1. 使用外部的、固定的区域提议方法(如选择性搜索)
- 这些区域提议不会随着训练过程而变化;
- 所以你可以 提前离线计算好 所有 proposal 和 ground truth 的匹配关系(包括正/负标签和回归目标);
- 优点是:
- 不影响训练速度;
- 标签可以事先保存到磁盘。
适用于:Slow R-CNN 和 Fast R-CNN
2. 使用端到端学习区域提议的模型,例如 Faster R-CNN
- 它的 RPN(Region Proposal Network)是在训练时动态生成区域提议的;
- 所以必须 在训练过程中实时(在线)进行 proposal 和 ground truth 的匹配;
- 原因是:RPN 生成的 proposal 会随着训练变化,无法预先计算;
- 这使得实现更加复杂,需要在每个训练步骤里完成匹配逻辑。
适用于:Faster R-CNN
二、分类损失 vs 回归损失 的处理方式
- 分类损失(classification loss):
- 对 所有区域提议 都要计算;
- 分类为某个具体类别或“背景”。
- 回归损失(regression loss):
- 仅对正样本提议(positive proposals) 才计算;
- 目标是预测从 proposal 框到 ground truth 框的坐标变换;
- 对负样本没有 ground truth 框,也就没有回归目标,因此不计算回归损失。
三、正负样本比例是个超参数
- 在实际训练中,一般不会让所有负样本都参与训练;
- 通常会控制 正负样本比例(如 1:3),以避免负样本过多压制正样本;
- 这个比例可以作为一个超参数,通过交叉验证或经验调整。
RPN训练过程和测试过程
一、RPN 的训练过程(训练阶段)
目标:
训练一个小网络,让它:
- 判断某个 anchor 是否包含目标(分类)
- 预测 该 anchor 应该如何调整,才能更贴近真实目标(回归)
训练数据准备
Step 1:在每个图像的特征图上滑动窗口
- 每个滑动位置生成多个 anchor boxes(不同大小、长宽比)。
Step 2:将 anchor 与 ground truth boxes 做 IoU 匹配,打标签
- 正样本(positive anchor):
- 与某个 ground truth IoU > 0.7,或
- 是和某个 ground truth IoU 最大的 anchor。
- 负样本(negative anchor):
- 与所有 ground truth IoU < 0.3。
- 中性 anchor(0.3~0.7):不参与训练。
📉 损失函数(multi-task loss)
RPN 的总损失 = 分类损失 + 回归损失(仅对正样本计算)
:第 i 个 anchor 的前景概率 *:标签(1 表示前景,0 表示背景)Missing superscript or subscript argument p_i ^ :预测的 box 变换 *:真实 box 与 anchor 的坐标差值(回归目标)Missing superscript or subscript argument t_i^ :交叉熵损失 :平滑 L1 损失 :只有正样本才计算回归损失 :调节两个损失权重(常设为 10)
参数更新
RPN 是可学习的子网络:
- 通过损失函数反向传播更新参数
- 它与 backbone 的权重是 共享的,所以训练 RPN 也在训练主干网络。
二、RPN 的测试过程(推理阶段)
当你输入一张图时,RPN 会完成以下步骤:
- 特征提取:
- 图像 → Backbone → 特征图
- 滑动生成 anchors:
- 每个特征图位置生成 k 个 anchors(比如 3 个尺度 × 3 个比例 = 9 个)
- 分类预测(前景概率) + 回归调整(anchor refinement)
- 应用回归结果到 anchor,得到 refined proposals。
- 用 softmax 分数对 proposals 排序,选出 top-N(如 top-2000)个。
- 进行非极大值抑制(NMS),去掉重复/重叠的 proposal。
- 输出最终的 region proposals,供后续的 Fast R-CNN 阶段使用。
训练阶段:
图像 → Backbone → 特征图
→ RPN → anchor 分类 + 回归
→ 与 ground truth 匹配,计算损失
→ 反向传播更新参数
测试阶段:
图像 → Backbone → 特征图
→ RPN → 得到 proposals(经回归 + 排序 + NMS)
→ 输入 Fast R-CNN 做分类和最终边界框回归
关于 NMS
NMS(Non-Maximum Suppression,非极大值抑制)是不是只在测试阶段使用?
简短回答:
是的,NMS 主要在测试阶段使用,用于筛选最终的预测框结果。
原因分析
训练阶段的目标:
- 是让模型学会:
- 哪些 anchor 是前景(目标);
- 如何调整 anchor 接近 ground truth;
- 此时我们不会关心 proposal 是否重叠,因为模型还在学习。
训练时不适合加 NMS:
- 如果在训练中就做 NMS,会“删掉”很多重叠但有效的正样本;
- 这会影响正样本数量分布,使训练不稳定;
- 我们希望网络在训练中尽量“看到”所有有用的信息。
测试阶段使用 NMS 的目的:
- 模型已经学会了检测;
- 每个目标周围可能会预测出多个重叠的框;
- 此时就需要 NMS 来去除冗余框,只保留一个最好的。
NMS 的流程回顾:
对于每一类物体:
- 将所有预测框按置信度得分降序排序;
- 选择分数最高的框 A;
- 去除与 A 的 IoU 大于阈值(如 0.5)的所有其他框;
- 继续选择下一个得分最高的框,重复步骤 2–3;
- 直到所有框处理完毕。
特例:RPN 中的 NMS
虽然我们常说 “NMS 是测试时才用”,但有一个 例外是 RPN 的训练阶段也有用到 NMS,但只是为了减少候选框数量(比如从几万个 anchor 选 top 2000 个),以提升效率。
注意:这个阶段的 NMS 不参与损失计算,不影响标签匹配,只是节约计算资源。
横向对比
一、横向对比总结表格
比较维度 | R-CNN (Slow) | Fast R-CNN | Faster R-CNN |
---|---|---|---|
区域提议来源 | 外部方法(如选择性搜索)离线生成 | 外部方法(如选择性搜索)离线生成 | **RPN 网络(可学习)**在线生成 |
特征提取顺序 | 每个 proposal 先从原图裁剪,再单独送入 CNN 提取特征 | 整张图先送入 CNN 提取特征图,再对每个 proposal 做 ROI Pooling | 同 Fast R-CNN,但 proposals 来自 RPN 子网 |
匹配操作(proposal 与 GT) | 离线匹配 proposal 和 GT产生正/负/中性样本 | 离线匹配逻辑与 R-CNN 一样 | 两次匹配:① anchor 与 GT → RPN 训练;② RPN 生成的 proposal 与 GT → 第二阶段训练 |
损失函数组成 | 分类 + 回归(仅正样本)每个 proposal 单独训练 | 同上(正样本有回归损失) | RPN 损失(前景/背景 + 回归) + 第二阶段损失(分类 + 回归) |
匹配方式 | proposal 和 GT 框做 IoU 配对 | 同上 | RPN:anchor 与 GTFRCNN:proposal 与 GT |
是否端到端训练 | 各阶段分开训练 | 虽然提速但仍用外部 proposal | 真正端到端训练:提议和分类一起学 |
效率 | 非常慢(每张图提上千个 proposal 分别 CNN) | 提速显著(共享 CNN 特征) | 提速 + 精度都有提升 |
二、核心概念和流程讲解
1. R-CNN(慢速 CNN)
- 外部算法(如选择性搜索)生成 proposals;
- 每个 proposal 区域 单独裁剪图像像素 → 送入 CNN 提取特征;
- 然后分别训练:
- 分类器(SVM)
- 边界框回归器(回归真框)
训练慢,无法共享特征,精度高但效率极差。
2. Fast R-CNN
- 整张图先经过 CNN 提取特征图;
- 然后对每个 proposal(仍由选择性搜索生成)做 RoI Pooling,从共享特征图中裁剪出对应区域特征;
- 分类 + 回归在一个网络中完成;
- 损失函数与 R-CNN 一样(对正样本做回归,对全部做分类);
- proposal 与 GT 的匹配仍然离线完成。
训练和测试都更快,特征共享,大大提升效率。
3. Faster R-CNN
- 引入 RPN(Region Proposal Network)
- 在 CNN 特征图上滑窗生成一堆 anchor;
- 对每个 anchor 做前景/背景分类 + 边界框回归;
- 得到 proposal;
- proposal 送入第二阶段(和 Fast R-CNN 一样):
- RoI Align → 分类 + 回归;
- proposal 与 GT 的配对必须在线进行(因为 proposal 是动态生成的);
- 总共有 两次配对 + 两段损失:
- RPN:anchor vs GT → 分类+回归损失
- Fast RCNN:proposal vs GT → 分类+回归损失
实现了真正端到端、统一、高效的检测框架。
三、配对 & 损失部分特别总结
模块 | 匹配单位 | 标签类型 | 损失内容 | 是否在线匹配 |
---|---|---|---|---|
R-CNN / Fast R-CNN | Proposal vs Ground Truth | 前景/背景 + 类别 + 回归目标 | 分类 + 回归(回归只用于正样本) | 离线匹配 |
RPN(Faster R-CNN) | Anchor vs Ground Truth | 前景/背景(二分类) + 回归目标 | 分类 + 回归 | 在线匹配 |
FRCNN 第二阶段(Faster R-CNN) | Proposal vs Ground Truth | 类别 + 回归目标 | 分类 + 回归 | 在线匹配 |
最后一段话强调的重点
- RPN 与 Fast R-CNN 是一起训练的,proposal 是随着训练不断变化的,所以配对也必须在线完成;
- 除此之外,R-CNN、Fast R-CNN、Faster R-CNN 三者之间的逻辑一致 —— 都涉及:
- 正负样本的配对;
- 分类损失和只针对正样本的回归损失;
- 主要区别在于:区域提议的来源是否固定,是否可训练,是否需要在线处理。
ROI Pooling
1. ROI Pooling 的目的是什么?
我们从 R-CNN → Fast R-CNN 的转变过程中,引入了一个关键操作:
将特征图上的某个区域(由 proposal 框定义)裁剪成固定大小(如 2×2、7×7)的特征表示,以便输入到下游全连接层或分类/回归头中。
2. 图解理解 ROI Pooling 操作
看你上传的图,我们可以拆成几个步骤来讲:
(1)原始图像与 Proposal 区域
- 绿色框是输入图像上的区域提案(Region Proposal),我们想提取该区域的语义特征。
- 将这个绿色框 投影(project)到特征图上。
(2)特征图上的裁剪过程
- 灰色网格表示 CNN 提取出的特征图(尺寸更小,比如从原图 640×480 到 20×15);
- 绿色框被投影到特征图中,形成一个“proposal 区域”;
- 然后将这个区域划分为 2×2 的子区域(图中彩色块);
- 在每个子区域上做 最大池化(max pooling),得到 2×2 的特征块。
(3)输出的固定大小特征
- 输出是一个固定大小的特征张量,比如 512×2×2(或真实使用中是 512×7×7);
- 它被送入后续网络用于分类和回归。
3. ROI Pooling 的两个核心问题(图中也有标注)
问题 1:特征未对齐(Misaligned Features)
- 图中说明了一个重要现象:
- 原图中的绿色框 → 映射到特征图上的蓝色框;
- 再将蓝色框划分为子区域(彩色块);
- 每个子区域被“捕捉”到某个 grid cell;
- 由于量化(snapping)误差,导致最终提取的子区域位置(图中彩色块中心)与原始 proposal 的真实位置不对齐。
直观来说,我们想提的是猫脸的精细特征,结果提取的却是猫脸偏一点、模糊的区域。
问题 2:不能反向传播到 proposal 坐标(Not Fully Differentiable)
- ROI Pooling 的过程涉及对 proposal 坐标做 离散化(rounding);
- 所以:梯度可以传给 CNN 的 feature map,但无法传给 proposal 坐标本身;
- 也就是说,proposal 的坐标在训练中无法通过反向传播被微调;
- 这在某些任务中(如实例分割、关键点检测)是致命的限制。
ROI Pool 只能反向传播到特征图,但不能调整 proposal 本身。
4. 总结这个裁剪函数的结构和缺陷
你这段话中提到:
“这个操作可以看成一个接受两个输入(特征图 + 边界框坐标),输出一个固定大小特征块的函数。”
没错,我们可以形式化为:
- F:特征图
- B:proposal(bounding box 坐标)
- f:固定大小的特征块
但由于 B 被离散化了,这个函数 对 B 不可微分,所以 不能用 end-to-end 的方式优化 box 的坐标。
5. 为什么后来用 ROI Align 替代?
为了解决以上两个问题,Mask R-CNN 中引入了 ROI Align:
特点 | ROI Pool | ROI Align |
---|---|---|
是否对齐 | 有误差(snapping) | 精确对齐 |
是否可微 | 坐标不可导 | 完全可微 |
采样方式 | 粗糙划分 + max pooling | 双线性插值采样 |
精度 | 一般 | 更高(适合精细任务 |
关于Region Proposal在原图还是在特征图
Region Proposal(区域提议)本质上是在特征图上生成的,但它的坐标是映射回原图的坐标系,用于表示图像中的目标区域。
具体流程解释:
1️ 输入图像通过 CNN 提取特征图:
- 原图(如 800×800) → CNN → 特征图(如 50×50)
2️ RPN(Region Proposal Network)在特征图上滑动:
- 每个滑动位置对应一个 空间位置 anchor;
- 每个位置生成多个 anchor boxes(预定义的框);
- 这些 anchor 是在特征图上定义的,但通过缩放因子映射到原图坐标系。
3️ RPN 对这些 anchors:
- 分类:预测是否为前景(含目标);
- 回归:对 anchor 做细微位置和大小调整,得到 refined proposal。
4️ 最终的 region proposal 是:
- RPN 在特征图上操作 anchor
- 但输出的 proposal 坐标是原图上的坐标
总结:
Region Proposal 是在特征图上生成的(由 RPN 运算),但它们的坐标被映射回原图,用来标注图像中可能存在目标的位置。
模块 | 发生在哪? | 坐标属于哪? |
---|---|---|
CNN 提取特征 | 原图 → 特征图 | 特征图空间 |
RPN 生成 proposal | 在特征图上滑窗 | proposal 坐标映射回原图 |
后续的 ROI Pool / ROI Align | 在特征图上裁剪 | 用的是映射到特征图上的坐标 |
具体讲解 ROI Pooling 的误差
回顾背景:ROI Pooling 在干什么?
- 给定一个 proposal(原图中某个矩形框);
- 将它投影到 CNN 特征图上(比如将 800×800 投影到 50×50);
- 然后在特征图上,把这个区域裁剪成固定大小,比如 2×2 子区域;
- 在每个子区域上执行 最大池化(Max Pooling),形成输出特征。
关键点:“量化(snapping)” 是什么?
在将 proposal 映射到特征图并划分成子区域时,需要把连续值的坐标映射成 离散的网格 cell(像素)。
由于坐标是浮点数(比如 6.2, 10.8),但特征图是格子状的(如 cell 是整数索引),你不得不把坐标 “捕捉(snap)”到最近的整数网格点,也就是:
将连续坐标 → 四舍五入 → 离散像素坐标
举个例子来解释“错位”问题:
原始设想(理想情况):
你希望划分的 2×2 网格是均匀地覆盖整个 proposal:
Proposal 区域(示意):
┌────┬
│ A1 │ A2 │
├────┼
│ A3 │ A4 │
└────┴
你希望每个子区域像素的中心是等距分布、精准对齐原 proposal 区域。
实际情况(ROI Pool 中的问题):
由于 proposal 映射到特征图上可能是 6.2 × 10.8 这么小的区域,划分为子区域时就会出现如下操作:
- 6.2 到 6 → 左对齐失真
- 10.8 到 11 → 右对齐失真
结果划出来的子区域(彩色块)大小不均、中心错位。
图中这些不同颜色的子区域(红、蓝、黄、绿):
- 是对 proposal 区域进行划分后得到的子区域;
- 每个彩色块代表一个 pool 的位置;
- 如果我们把这些彩色块“投影回原图”,你会发现:
- 它们的中心位置偏离了原始绿色 proposal 区域的真实中心点;
- 这些偏移就是 misalignment(未对齐)的问题本质。
总结:
ROI Pooling 中由于坐标向下取整/向上取整(即 snapping to grid)导致子区域不再精确覆盖原 proposal 区域,最终提取的特征位置“偏离”了原始区域位置中心,造成特征误差,这就是所谓的 misalignment。
为什么这个错位是严重问题?
- 如果你是做 目标检测:轻微偏差还能忍;
- 如果你是做 实例分割 / 关键点检测:像素级别的精度非常关键,偏一两个像素就错了对象;
- 所以后来才有了 ROI Align —— 不再四舍五入,而是 使用双线性插值在浮点位置采样,彻底解决这个问题。
ROI Align
一、ROI Align 是为了解决什么问题?
这是对 ROI Pooling 的改进,因为:
- ROI Pooling 存在两个关键问题:
- 坐标离散化(snapping)导致 特征错位、不精确;
- 非可微,不能反向传播到 proposal 坐标,不能优化 box 本身。
- ROI Align 用于解决这两个问题:
- 不再对坐标进行离散化;
- 支持在特征图的任意实数位置采样;
- 可完全反向传播。
二、操作流程(结合三张图)
第一步:投影 Proposal 到特征图
如第一张图所示,绿色框是原图的 proposal,经 CNN 后投影到特征图上。
不同于 ROI Pooling,ROI Align 不会四舍五入到特征图的整数像素位置,而是保留实数坐标。
第二步:划分成均匀子区域 + 均匀采样
将投影后的 proposal 划分为固定数量的子区域(如 7×7),在每个子区域内部,采样固定数量的点(如每格采 4 个点),这些采样点 可能不落在 grid 的整数位置上,而是实值坐标(图中的绿色点)。
第三步:双线性插值
这一步是关键。
例如你想在位置 (6.5, 5.8) 上采样特征,但特征图是离散网格,怎么办?
- 找到这个位置周围的四个整数网格点(如图右下角的 f₆,₅、f₇,₅、f₆,₆、f₇,₆);
- 用这四个点按 距离进行加权组合,这就是双线性插值(bilinear interpolation):
- 这样即使你的位置是连续的,也能在离散特征图中得到平滑、连续的采样结果。
第四步:最大池化 + 输出特征
对每个子区域采样多个点后,可以:
- 对这些点做 最大池化或平均池化,获得该子区域的代表特征;
- 所有子区域组成一个固定大小的特征张量(如 7×7);
- 这个张量送入后续分类或回归头中。
同时,由于所有操作(坐标变换 + 插值)都可导,可以 反向传播到原图的 proposal 坐标,进行 box 的优化。
三、ROI Align 的两个优势
问题 | ROI Pooling | ROI Align |
---|---|---|
特征对齐 | 存在偏差(因为坐标量化) | 精准对齐,采样在连续位置 |
可微性 | 不能反传到 box 坐标 | 完全可微,box 坐标可训练 |
ROI Align完美对齐的原因
一、什么叫“对齐”?
“对齐”是指:
你在原图中提议的一个边界框(region proposal)所代表的图像区域,在经过特征提取 + 裁剪后,其提取的特征应准确对应原图中的那个空间区域。
如果提取的特征位置与原图上的实际区域有偏移,那就是“未对齐”或“错位”。
二、ROI Pooling 为何无法做到“对齐”?
因为它在执行过程中,把 proposal 映射到特征图后:
- 对坐标进行了四舍五入(snapping);
- 每个 proposal 被划分为固定网格(如 7×7)时,边界和中心位置都可能被偏移;
- 导致提取的特征并不是从 proposal 的“原始位置”提取的,而是从偏移后的“邻近区域”提取的。
这就出现了“不对齐”。
三、ROI Align 如何做到“完美对齐”?
这句“我们所有的样本特征都将与输入图像中的位置完美对齐”背后的逻辑是:
1. 不再四舍五入坐标(无 snapping)
- Proposal 坐标保持实数;
- 采样点的位置是连续空间中精确的子区域中心。
2. 使用双线性插值在特征图上采样
- 即使采样点在特征图像素格之间,比如坐标是 (6.5, 5.8),也不会舍入;
- 而是用周围四个像素的特征值,按距离权重线性组合出这个精确位置的特征;
- 这个过程模拟了在真实提议位置上”提取特征。
因此:
提取的特征恰好对应 proposal 所描述的真实区域——这就叫“完美对齐”。
四、总结一下这句话的含义
原句:
“因为我们使用实值采样和双线性插值,现在这意味着我们所有的样本特征都将与输入图像中的位置完美对齐。”
换句话说:
- 我们不再对 proposal 坐标做量化;
- 我们使用高精度的插值技术在连续空间提取特征;
- 所以,无论你在原图上定义的边界框有多精细,它都能被准确映射到特征图上并提取正确区域的特征;
- 这就是“完美对齐”——feature 和原图空间真正一一对应了。
如果你想,我还可以用一组对比图直观演示“错位 vs 对齐”。
双线插值更细节的数学原理:参考手稿
一、什么是“完美对齐”?
先把目标说清楚:
当你说“样本特征和输入图像中的位置完美对齐”,指的是:
你在原图中选定了一个 proposal 框,比如包住猫的头,那么你最终从特征图中提取的内容,必须正好代表这个猫头区域的语义信息。
二、问题是:CNN 后我们只剩下特征图,它是低分辨率的,怎么办?
比如:
- 原图 800×800;
- 特征图只有 50×50;
- 那么你原图中的 proposal(比如从 400,400 到 600,600)对应特征图中只是一小块,例如 25.0 到 30.0 之间的浮点位置。
此时,你要从特征图中采样这段区域的“语义表示”,而不是模糊取一个 grid 点。
三、什么是双线性插值?数学公式解释它是“空间连续近似”的方式
设你要采样的点是 (x, y),不在整数网格上,比如 (5.3, 6.7),它的左下角是 (5, 6),你取它四个周围的整数点:
, , ,
然后通过下面这个公式加权组合它们的值:
这其实是一个数学操作,它假设特征图是个二维连续函数,你现在在小网格内,只需要按比例混合四个角的值,就能“模拟出”任意一点的值。
这背后的数学本质是:
你把特征图当成一个连续的函数,在它上面做空间插值采样。插值是空间的线性逼近。只要你的位置选得对,你插出来的值就表示的是那个真实位置应有的语义。
四、回到你关心的核心:为什么插值结果就能对齐原图位置?
这是最关键的一步:
- 我们在原图中定义了 proposal;
- 我们通过比例关系,把 proposal 映射到特征图中的一个 实数区域;
- 然后我们在这个区域里用浮点坐标采样点,这些点在原图中正好均匀铺在你想裁剪的区域;
- 插值让我们能在这些真实位置上提取语义信息,而不是向左/右/下/上偏一格。
所以最终提取出来的特征,是从 proposal 指定区域上精确计算的,而不是某个邻近区域,这就是“完美对齐”。
五、类比理解
你可以把插值类比成这样:
假设你站在地图上的 (5.3, 6.7) 米处,地图上只标出了整数米的点的数据(5,6)、(6,6)、(5,7)、(6,7),你不知道自己这点的精确海拔高度,那你怎么估?
你就取四个角的海拔,按距离加权平均:离哪个点近就用得更多,这样你就估出来你脚下这个点的高度。这种方式很合理,也“连续”,不会突然跳变。
同样地,插值让 CNN 的离散输出“在空间上连续”,我们就可以对齐 proposal 中的任何真实位置,而不是对齐到整数格子去乱抽一通。
六、总结一句话
ROI Align 中的插值让我们可以在 proposal 精确映射到特征图的实值位置处采样,不受 grid 限制;而我们设计的采样点本来就在 proposal 中,因此插值得到的特征正好表达 proposal 中对应位置的语义,实现了“位置上的完美对齐”。
ROI Align解决可微问题分析
一、什么是“可微性问题”?
可微性(differentiability)在神经网络中意味着:
模型的每一个操作都可以对其输入计算梯度,从而参与端到端的反向传播训练。
二、ROI Pooling 为什么不可微?
ROI Pooling 的关键问题是它使用了非连续、不可导的操作:
- 坐标四舍五入(snapping):
- 将 proposal 映射到特征图上时,为了划分成 7×7 网格,会对坐标做整数舍入;
- 这个过程是离散跳变的:一个 proposal 的坐标哪怕只变化了 0.01,它可能就 snap 到另一个格子,导致结果突变。
- 最大池化(max pooling) 本身虽然在值域上是 piecewise differentiable 的,但:
- 当输入位置是浮点坐标时,它必须“选择一个最近邻格子”,这个选择过程是非导数连续的。
- 更重要的是:proposal 的坐标无法反向传播,因为:
- 它在做池化前就被 snap 到了某个格子,这个 snapping 是一个不可导的离散决策;
- 所以反向传播中无法计算关于 proposal 坐标的梯度,也就不能优化 proposal 本身的位置。
三、ROI Align 为什么是可微的?
ROI Align 用了连续的、可导的插值机制,核心特性有两点:
1. 不再四舍五入坐标
采样点的位置是连续的实数,不再 snap 到 grid 上。
2. 使用双线性插值(bilinear interpolation)
插值的计算公式本质上是连续变量的加权平均:
- 这是一个对 x 和 y 连续可导的表达式;
- 所以我们可以对插值点的 x, y也就是 proposal 坐标计算梯度;
- 即:
- 上游梯度能传到特征图;
- 也能传到 box 坐标
, , , ,从而支持 box 的学习和微调。
四、总结:可微性带来了什么能力?
- 网络可以“感知”到:
- 如果你稍微移动 proposal 的位置,它提取出来的特征值也会“微小变化”;
- 网络可以基于损失反向传播,自动优化 proposal 的精确位置,甚至支持软调整;
- 在更复杂的任务中(如检测+姿态估计、检测+mask),这一步尤为重要。
五、最终结论
ROI Align 之所以解决了可微性问题,是因为它的核心计算——双线性插值是对坐标连续可导的,从而使得网络可以不仅对特征图计算梯度,还能对 proposal 本身的位置进行微调训练。
CornerNet
一、核心思想:边界框 = 左上角 + 右下角
- 不再提前定义成百上千个 anchor;
- 而是网络直接在特征图上预测目标的两个角点;
- 每个目标框由 一对角点表示。
二、网络结构(结合你图中内容)
- Backbone CNN:
- 输入图像经过 CNN(如 Hourglass Net)提取特征图;
- 输出一个 shape 为
的特征图。
- 两个分支(关键):
- 左上角热图分支:
- 输出每个位置是目标左上角的概率,维度:
- 右下角热图分支:
- 输出每个位置是目标右下角的概率,维度:
- 两个角点的 embedding 分支:
- 每个角点都会预测一个 embedding 向量(类似于身份编码):
- 左上角 embedding:
- 右下角 embedding:
三、训练目标(数学原理)
1. 角点位置监督(heatmap)
对每一个真实边界框:
- 左上角坐标 → 在左上热图上标记为正样本;
- 右下角坐标 → 在右下热图上标记为正样本;
- 其余位置是负样本。
使用 focal loss 或 cross entropy loss 训练分类概率。
2. 角点匹配监督(embedding)
为了知道哪些左上角和右下角属于同一个物体:
CornerNet 引入了一个 embedding 损失,让真正属于同一个边界框的两个角点拥有“接近的向量”。
- 对于一对角点
, (top-left & bottom-right):
使用两种损失:
- pull loss:拉近同一个 box 的角点 embedding
其中
- push loss:推开不同 box 的角点 embedding
最终总损失:
四、测试阶段(推理逻辑)
1. 角点检测:
从热图中挑出得分最高的左上角、右下角(如 top-K)。
2. 匹配角点:
对于每个候选左上角,尝试与所有右下角组合,只保留那些 embedding 距离最小的一对(即最有可能属于同一个框)。
3. 生成边界框:
每一对通过匹配的角点 → 组合成一个检测框。
五、CornerNet 的优点
对比项 | Anchor-based 方法 | CornerNet |
---|---|---|
先验框设计 | 需要预设多尺度、多比例 anchor | 不需要 |
框表示方式 | 中心点 + 回归偏移 | 角点对 |
框匹配方式 | IoU + NMS | heatmap + embedding |
训练复杂度 | anchor 多,正负样本不均衡 | 结构更自然,对称 |
误检问题 | 可能框太多、重叠严重 | 角点配对过滤误检 |
六、总结流程图(文字版)
输入图像 → CNN → 特征图
↓ ↓
左上角分支右下角分支
↓ heatmap ↓ heatmap
↓ embedding ↓ embedding
训练:
- heatmap → 分类损失
- embedding → pull + push loss
测试:
- 找到 top-K 热点
- 匹配角点对(embedding 距离最小)
- 输出目标框
FPN
FPN (Feature Pyramid Network) 是一种用于 多尺度目标检测 的网络架构,它主要用于生成不同尺度的特征图,以便能够检测不同大小的目标。FPN 通过将不同层次(深度)的特征图合并来帮助模型提取图像的多尺度信息,这对于处理大小不同的物体至关重要。
FPN 的作用:
- 多尺度特征提取:
- 目标检测中,物体的尺寸在图像中可能非常不同。例如,小物体(如人脸)和大物体(如车辆)可能会出现在图像的不同区域。传统的卷积神经网络(CNN)通常会逐步缩小图像的空间分辨率,从而导致对小物体的感知能力变差。FPN 通过构建 多尺度的特征图 来解决这个问题。
- 增强不同尺度的感知能力:
- FPN 会从网络的多个层次提取特征图(比如从浅层特征到深层特征),并且通过 特征融合 来生成不同分辨率的特征图(如 p3、p4、p5)。这样,网络能够在 高分辨率 层(适合捕捉小物体)和 低分辨率 层(适合捕捉大物体)中进行有效的学习。
- 通过上采样和融合来增强高分辨率特征:
- FPN 会通过 上采样 低分辨率特征图(如 p5)并与高分辨率特征图(如 p4, p3)进行 融合,从而使每个特征图层都能够包含来自不同层的信息。
- 这使得模型能够对不同大小的物体做出更好的判断和预测。
FPN 的工作原理:
FPN 的核心思想是通过对网络中不同层的特征进行 融合 来产生多尺度的特征图。具体来说,它包含以下几个关键步骤:
- 从不同的卷积层中提取特征:
- 一般来说,CNN 会通过逐渐降低图像的空间分辨率来提取特征。FPN 会选择网络中的不同层(如 c3, c4, c5)来提取特征。
- 这些特征图的空间尺寸(高度和宽度)从低到高(例如,c3 是最细粒度的特征,c5 是最粗粒度的特征)。
- 使用 1x1 卷积来调整通道数:
- FPN 会通过 lateral 1x1 卷积层 将这些不同层的特征图通道数统一,确保它们的通道数一致,这样后续的融合才能顺利进行。
- 上采样与融合:
- FPN 会 上采样 来将低分辨率的特征图(如 c5)调整为更高分辨率的特征图,并与相邻层(如 c4, c3)的特征图进行加和(融合)。
- 通过上采样和加和操作,FPN 将低分辨率特征和高分辨率特征结合,使每个层的特征都包含来自不同尺度的信息。
- 生成多尺度特征图(如 p3, p4, p5):
- 最终,FPN 生成的 p3、p4、p5 特征图分别代表不同尺度的特征,分别用于不同大小的目标检测。
FPN 层的结构:
- Lateral 1x1 卷积层:用于调整不同层的特征图通道数,使其一致,便于后续的融合。
- 上采样:将低分辨率特征图上采样到高分辨率,便于与其他层的特征图进行加和。
- 3x3 输出卷积层:对融合后的特征进行进一步处理,得到最终的 FPN 输出特征图。
FPN 层如何改善目标检测:
FPN 通过将不同尺度的信息融合到一起,使得模型能够在不同的空间分辨率下做出更加准确的预测:
- 小物体检测:通过高分辨率的特征图(p3)来处理小物体。
- 大物体检测:通过低分辨率的特征图(p5)来处理大物体。
FPN 的关键特点:
- 多尺度特征融合:通过融合不同层次的特征来增强网络的多尺度感知能力。
- 自上而下的信息流:从高分辨率到低分辨率(通过上采样和加和),实现信息的传递。
- 提高检测精度:通过在不同的尺度上进行特征提取和融合,FPN 能够提升对各种尺寸物体的检测能力。
总结:
FCOS
主要内容:
- FCOS 设计:
- FCOS 是一个完全卷积的目标检测模型,意思是它只使用卷积层(没有使用专门的锚框(anchor boxes)、候选区域(proposals)等)。这使得 FCOS 的实现和训练过程简化,因为没有额外的模块需要设计或调试。
- FCOS 的输入是图像的特征图(通过 FPN 提供),然后在每个像素位置上进行目标检测预测(类别、边界框回归和中心性)。它与传统的两阶段目标检测方法(例如 Faster R-CNN)不同,后者需要生成候选区域并对这些区域进行进一步分类和回归。
- 与分类模型的不同:
- 图像分类模型通常是以 (image, label) 这种 (图像,标签) 配对的方式进行训练,其中 label 是一个与整张图像关联的整数标签(或者更具体来说,是一个 one-hot 向量)。即,分类任务的标签与整个图像对应。
- 问题 1:目标检测和图像分类的关键不同之处在于,目标检测的每张图像可能有 多个目标,每个目标都有自己的 边界框 和 类别标签。这意味着每张图像的标签并不是一个简单的类别,而是多个目标的描述。
- 问题 2:在目标检测中,类别标签与图像的某个区域(即目标的边界框)相关,而不是与整个图像相关。这就不同于图像分类任务中的单一标签。
- 每个像素位置的预测:
- 在 FCOS 中,模型会对特征图的 每个位置 进行 目标类别、边界框回归 和 中心性预测。每个位置(即每个像素)会预测一个边界框(例如目标的坐标)和一个 类别(表示该位置是否包含目标以及目标属于哪个类别)。
- 因为每个像素都有预测,所以需要确保 每个像素 都有 一个对应的真实目标框(GT box) 作为训练目标。
- 监督训练:
- 在 FCOS 中,每个预测位置(特征图上的每个像素)都需要有一个 GT 目标框(Ground Truth bounding box) 作为监督目标。每个像素的预测不仅是类别预测,还包括边界框回归(预测的边界框与真实边界框的差异)和中心性预测。
- 这里强调 每个像素 都有 唯一的目标框(GT box),这与图像分类模型的训练方式不同。
总结:
- FCOS 是一个 完全卷积 的目标检测模型,不依赖锚框或候选区域,只使用卷积层直接从图像特征图中预测目标的类别、位置和中心性。
- 与传统的图像分类模型不同,目标检测模型需要每个像素位置对应一个 真实目标框,而不仅仅是与整个图像的标签关联。
- 在训练 FCOS 时,你需要为每个像素的预测提供一个 真实的目标框,并且每个像素都被视为独立的预测任务。
这段话讲解的是在 FCOS 目标检测模型训练过程中,如何为每个模型预测(即每个 FPN 层的每个位置)分配一个 GT(Ground Truth)目标框 和 类别标签。我们可以通过以下几个步骤理解这段文字。
训练 FCOS(作业)
主要内容解析:
- FCOS的三种预测:
- 目标类别(Object class):预测每个位置(像素)是否包含目标,以及它所属的类别。
- 边界框回归(Bounding box):预测每个位置的 边界框坐标,即目标在图像中的位置。
- 中心性(Centerness):预测每个位置作为目标中心的可能性。
这些预测都是针对 FPN 层(如 p3, p4, p5) 中的每个位置进行的。在训练时,我们需要为每个预测分配一个 GT 目标框(真实边界框)和其对应的 类别标签。
- GT目标框的格式:
- GT目标框通过一个 5D 向量表示,形式为 (x1, y1, x2, y2, C):
- (x1, y1) 是边界框的左上角坐标。
- (x2, y2) 是边界框的右下角坐标。
- C 是目标类别标签。
- 这些坐标是 绝对的、实际值,以图像的像素维度表示。
- 目标框的分配问题:
- 在训练时,FCOS模型会对特征图的每个位置进行预测。每个位置会有一个 类别、边界框回归 和 中心性 的预测。因此,我们需要为每个 FPN 层的每个位置 分配一个真实的目标框 和对应的 类别标签。
- 如何为每个位置分配 GT 框:
- 每个 FPN 层的特征图位置(即每个位置上的感受野)在图像中的实际位置 (xc, yc) 是通过将特征图位置与图像坐标对齐来确定的。这个位置对应图像中的某个点,这个点是 感受野的中心。
- (xc, yc) 是特征图每个位置的 绝对坐标,可以通过下述公式计算:
- 假设 FPN 层的特征图尺寸为 (batch_size, channels, H / stride, W / stride),其中 stride 是当前 FPN 层的步幅。
- 对于特征图中的位置 (i, j) 其映射到图像中的位置为:
1 | (xc, yc) = (stride * (i + 0.5), stride * (j + 0.5)) |
这里的 0.5 表示从特征图的左上角偏移到 感受野中心 的平移量。
- 实现 get_fpn_location_coords:
- 你需要在 common.py 文件中实现一个函数 get_fpn_location_coords,该函数的目的是计算 所有 FPN 层特征点的 (xc, yc) 坐标。
- 你可以参考文档和使用示例来编写该函数。具体的功能是根据给定的 FPN 层的大小、步幅等信息,计算出每个特征点的 图像坐标。
任务目标:
- 计算每个位置的实际坐标: 给定 FPN 层的形状 (batch_size, channels, H / stride, W / stride),你需要为每个位置计算其映射到图像中的 (xc, yc) 坐标。
- 为每个预测位置分配 GT 框和类别标签: 训练时,每个位置的预测会根据它所在的图像位置,分配对应的 GT 目标框 和 类别标签。
实现细节:
- get_fpn_location_coords 需要根据 FPN 层的形状和步幅,计算出每个位置对应的图像坐标 (xc, yc)。
- 输入为 FPN 层特征图的大小和步幅,输出是一个坐标列表,表示特征图上每个位置在图像中的位置。