上一篇博客中介绍了Faster-RCNN 是怎么通过 RPN (region proposal net) 设置 anchor 获得原图中的bounding box(bbx)的。对于 RPN 来说,或还没干完。还需要将获得的 bbxes 进行分类和回归,获得最终可以进行细粒度检测的 proposals。
大部分人可能都知道,由 bbx 获得 proposals,无非包括两个 heads :1)cls (分类器);2)regression (回归器)。其中分类器用与判断该bbx 是前景还是背景;回归器用与微调 bbx 的位置和 scale (高 & 宽),以获得更加合适的 proposals。
但是看了很多博客,有个细节很少被提到:对于回归来说,对于一个bbx 来说,如何确定目标位置与尺寸?
这里的微妙之处在于,有以下两种情况可以思考:
1. 如果这个anchor 生成 bbx 与某个前景 groundtruth 框的 IoU (intersection of union)大于设定阈值,被认为是“可培养对象”(潜在proposal),那么问题就简单了,根据公式,计算出前景 groundtruth 框 与 anchor 生成的 bbx 之间的仿射变换信息(位移与 scale ),便可以计算损失函数,进行回归。
2. 但是如果,某个 anchor 生成的bbx 是个三不沾的背景 bbx,找不到一个合适的可以 “投靠” 的前景 groundtruth 计算仿射变换信息,那么对这种 bbx 怎么办呢?
以上问题,其实看原文的损失函数公式变一目了然:
![Faster-rcnn 损失函数](https://img-blog.csdnimg.cn/2020033020432981.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3lhbmd5ZWh1aXN3,size_16,color_FFFFFF,t_70)
损失函数包括两部分,第一部分为分类损失,第二部分为回归损失。注意到第二部分回归损失前有个很重要的变量,
由此可见,第二项回归只对“正”的预测 bbx 起作用,而忽略其他的bbx,也就是说,对于之前第二个思考,“三不沾”的 bbx 是不在回归分支的考虑范围内的。
而如何判断一个bbx为正还是负呢?
bbx 标签 | 条件 |
正(1) | 1. bbx 与任意一个前景类别的groundtruth IoU > 0.7 2. 如果对于一个前景类别的groundtruth,所有的anchor生成 bbx 与其 IoU 都小于等于 0.7,那么取与该 groundtruth IoU 最大的bbx为正 |
负(0) | 1. bbx 与任意一个前景类别的 groundtruth IoU < 0.3 |
其他(不进入RPN 训练) | 其他条件 |
获得了 每个 bbx 的标签后,便可以从中抽取正负样本训练 RPN 网络了。网络收敛后,变可以用如下步骤将anchor 生成的 bbxes 转化为可以用与Fast-RCNN 检测的proposals 了
step 1. 对于每一个 anchor 生成的 bbx,先用RPN 网络进行一篇前传;
step 2. 先看 RPN 网络的分类分支,如果分类分支认为是背景(预测为 0 ),那么该 bbx 丢弃;如果判断为前景,进入step 3;
step 3. 取回归分支的输出结果计算该 proposal 的(x, y, w,h)。这样变把 anchor 生成的 bbx 转化为可以进行后续操作的proposals 了。
这里有个细节是,对于回归损失,在位置的基础上做了个变换:
这里就是仿射变换,为位置偏移,
为尺寸 scale,除法和取 log,都是为了将此项限制在 (-1,1) 之间方便在网络实现时回归层的输出节点利用 sigmoid 函数。
至此,如何将anchor 生成的 bbxes 转化为检测分支的 proposals 的步骤便讲完了,proposals 确定,接下来就是 Fast-RCNN 的事情了。(当然,这里面还有一些训练的tricks,论文里面写的很清楚 4-Step Alternating Training)
这里其实可以看到, 这个转化过程还是有一些瑕疵的,比如:
1. 没有充分利用 bbx,回归只在针对判断为正的 bbxes
2. 过分依赖于分类分支,如果分类分支预测错了,那么后面怎么都回不了头了。因此 RPN 网络需要保证高敏感。
3. RPN 只做个 anchor bbx 的粗筛,理论上只要后面的检测分支足够好(又快又准),这个网络是可以去掉的。所以我大胆看好 one-stage 的检测器。
好了,本文基本结束,这个点其实没太多难度,所以不建议看任何人写的博客,论文写的很清楚。更多是代码实现上的问题,建议大家找个好代码有个方向直接撸代码会更好些。
如有问题,欢迎留言讨论。