目标检测 YOLOv5 - Sample Assignment
flyfish
target是通过标注数据构建的 例如包括 目标的类别,目标的位置这些已知内容。 BBox就是bounding box,边框。 target里面的边框就是Ground Truth BBox,简称 GT BBox或者GT Box,就是人告诉计算机的,已知的正确答案。 通过模型输出的边框就是 Predicated BBox,
我们期望Predicated BBox结果就是GT BBox。两者交流不方便的时候就增加了一个中介,这两种边框存在一个中介,这个中介就是Anchor BBox,有时简称anchor。 当发现prior box,prior bbox,先验框这样的词汇的时候,不用疑惑,它就是anchor,是人为通过程序生成的一些边框。程序生成的边框坐标是固定的,即anchor的坐标是固定,这不是正确答案。anchor的坐标就想和GT BBox这个正确答案匹配 那怎么匹配呢?
一个anchor对应一个GT BBox的情况
一种是GT BBox找到与其IoU最大的那个anchor匹配,每个GT BBox都有个anchor匹配 如果没有anchor的时候,需要直接回归GT BBox的坐标,有anchor的时候,回归的时候就可以回归两者的偏移量,两个边框上下左右各差多少,即人为生成的anchor的与标准答案GT BBox之间的差别。
多个anchor对应一个GT BBox的情况
YOLOv5 是这样来比较人为生成的anchor的与标准答案 gt box之间的差别 通过两个量来变:一个是中心点的偏移,anchor的中心点如何变gt box的中心点 另一个是 宽度和高度的缩放系数, 相对于GT BBox的宽度和高度,anchor的宽度和高度各自变大了,还是变小了。 通过两个量的偏移变化,anchor就变GT BBox了, 这就是一个被确定为正样本的anchor 如何变GT BBox的过程
这种宽度和高度的缩放系数在文件hyp.scratch.yaml里面存着。
anchor_t: 4.0
YOLO各个版本的Sample Assignment
?version?
?scale?
?num.?anchors?
?per?scale?
?assignment?method?
?assigned?
?anchors?per?GT?
?YOLO?v1?
1
0
?center?position?comparison?
?single?
?YOLO?v2?
1
9
?IoU?comparison?
?single?
?YOLO?v3?
3
3
?IoU?comparison?
?single?
?YOLO?v4?
3
3
?IoU?comparison?
?multiple?
?YOLO?v5?
3
3
?box?size?comparison?
?additional?neighboring?2?cells?
?multiple?
\begin{array}{|l|l|l|l|l|} \hline \text { version } & \text { scale } & \begin{array}{l} \text { num. anchors } \\ \text { per scale } \end{array} & \text { assignment method } & \begin{array}{l} \text { assigned } \\ \text { anchors per GT } \end{array} \\ \hline \text { YOLO v1 } & 1 & 0 & \text { center position comparison } & \text { single } \\ \hline \text { YOLO v2 } & 1 & 9 & \text { IoU comparison } & \text { single } \\ \hline \text { YOLO v3 } & 3 & 3 & \text { IoU comparison } & \text { single } \\ \hline \text { YOLO v4 } & 3 & 3 & \text { IoU comparison } & \text { multiple } \\ \hline \text { YOLO v5 } & 3 & 3 & \begin{array}{l} \text { box size comparison } \\ \text { additional neighboring 2 cells } \end{array} & \text { multiple } \\ \hline \end{array}
?version??YOLO?v1??YOLO?v2??YOLO?v3??YOLO?v4??YOLO?v5???scale?11333??num.?anchors??per?scale??09333??assignment?method??center?position?comparison??IoU?comparison??IoU?comparison??IoU?comparison??box?size?comparison??additional?neighboring?2?cells????assigned??anchors?per?GT???single??single??single??multiple??multiple???
YOLOv3的时候是 一个target center对应一个target grid cell YOLOv5的时候一个target grid cell是不够的,一个target center对应三个target grid cell。 除了本身的target grid cell,还要从它的上下左右4个grid cell再选择两个。也就是前景foreground与背景background的区分。 原来他们只是叫做grid cell,被选中之后就成了target grid cell。 代码中是这样描述的(utils/loss.py)
gxy = t[:, 2:4]
gxi = gain[[2, 3]] - gxy
j, k = ((gxy % 1. < g) & (gxy > 1.)).T
l, m = ((gxi % 1. < g) & (gxi > 1.)).T
j = torch.stack((torch.ones_like(j), j, k, l, m))
t = t.repeat((5, 1, 1))[j]
offsets = (torch.zeros_like(gxy)[None] + off[:, None])[j]
gxy % 1 是浮点求模
选择之后的结果(utils/loss.py)
b, c = t[:, :2].long().T
gxy = t[:, 2:4]
gwh = t[:, 4:6]
gij = (gxy - offsets).long()
tensor([[ 0.00000, 0.00000], [ 0.50000, 0.00000], [ 0.00000, 0.50000], [-0.50000, 0.00000], [ 0.00000, -0.50000]], device=‘cuda:0’) 原点不动,往右、往下、往左、往上 往右、往下、往左、往上,分别用字母 j k l m 表示 编写一下代码将gij可视化的结果是 特征图有三种,所以有3种情况 模型的输出,其中80,40,20就是特征图大小
torch.Size([16, 3, 80, 80, 85])
torch.Size([16, 3, 40, 40, 85])
torch.Size([16, 3, 20, 20, 85])
都是三个target grid cell做为一个小组
anchor通过配置文件或者自动计算
|