简单回顾一下detection方面的经典文章,希望能形成一个系统的知识树。自己也不做detection,只是希望能有所借鉴吧。
YOLOv1是CVPR16的文章,在此之间以faster rcnn为代表的two-stages检测方法在精度上已经做的不错的,但是以proposal为思想的这些方法,速度上是达不到实时应用程度的。本文提出一种新的架构, 将检测问题看作统一的一个回归问题, 直接从整个图像回归到class概率和bbox坐标。
具体地,网络将图片划分为S*S的网格(eg. S=7)。 每个网格预测B个bbox和分别的置信度。这个置信度可以按下式理解:
。
即它反映了这个bbox有多么确定它包含一个物体,和多么确定它预测的bbox是准确的。
每个bbox包含5个输出(x, y, w, h, confidence)。(x, y)是bbox中心的坐标相对与当前格子的偏移比例([0,1], 比如在格子正中间,则,x=y=0.5)。(w,h)是bbox的长宽相对于整幅图长宽的比例([0-1])。
每个格子还预测C个条件类别概率:
不管B是多少, 每个格子至预测一种类别的概率。也就是说我们默认当前格子里出现的一定只有一种物体。
test时,我们把这个条件类别概率和前面每个bbox的置信度相乘, 就得到了每个bbox的类别概率:
它不但包含这个box包含第i类物体的概率, 还包含了预测框的准确程度。
举例: 令S=7, B=2, 数据集有20类物体, 那么 最后网络预测是:7*7*(2*5+20)=7*7*30的tensor。
loss:
这个loss设计考虑了以下问题:
1. 传统的loss: classification loss + localization loss将二者同等对待, 这样在YOLO中是不行的, 因为一张图中,绝大多数格子是不包含物体的,也就是说会'push'这些格子的置信度为0, 这样会影响那些少量包含物体的格子梯度传递, 也就是overpowering。 所以解决方法是给包含物体的格子localization loss赋予较大权重(5), 不包含物体赋予较小权重(0.5), 当然此时loss只包每个bbox置信度的loss, 坐标和class的概率都不参加loss计算。
2. 传统的localization loss对w和h做均方差, 但是考虑小物体和大物体偏移相同的距离, 显然小物体犯错更不能被忍受, 解决方法是w和h开放后再算均方差。
3. 训练时, 每个格子会预测B个bbox, 我们只想要一个bbox负责预测一个物体, 基于什么条件指定这样的负责呢? 就是当一个bbox和一个物体有最高的IOU时,它就负责这个物体的预测, loss中其他bbox对这个物体的权重为0。
YOLOv1的缺点:
1. 产生更多的localization error, 即预测物体的class是对的, 但是IOU较低((0.1, 0.5));
2. 对成群的小物体的检测困难,因为每个格子只预测B个bbox。
优点:
1. fast, 且保持较高精度;
2. 很少将背景检测为物体, 即false positive的概率较小, 因为YOLO训练是看的是整张图, 感受野更大, context 信息更丰富。
相反faster rcnn就容易犯这样的错误。