AnchorBoxes
使用锚点框(AnchorBoxes
)可以帮助目标检测网络更快速的收敛到真值框(GroundTruth
)。关于锚点框的实现也经历了多次迭代变化:YOLOv2/YOLOv3/YOLOv4/YOLOv5
。
YOLOv2
YOLOv2首次使用锚点框来提高目标检测网络的性能。YOLOv2使用kmeans聚类算法来计算锚点,其中距离函数是质心和标注框之间的IoU。
目前在网络上找到3个相关的实现:
- 官方实现:darknet/scripts/gen_anchors.py
- 代码中采用了voc的训练集标注框数据进行计算,参考darknet/scripts/voc_label.py,可以发现采用了
VOC2007 + VOC2012 train/val
数据集
- 代码中采用了voc的训练集标注框数据进行计算,参考darknet/scripts/voc_label.py,可以发现采用了
- 其他实现:
- jinyu121/get_anchor.py
- 部分参考了官方实现,增加了sklean的kmeans实现
- lars76/kmeans-anchor-boxes
- 几年前调研过:[YOLO][k-means聚类]寻找锚点
在Darknet官网上找到几个YOLOv3配置文件:
从配置文件来看,针对VOC数据集,作者生成了5个锚点框
YOLOv3
YOLOv3优化了锚点框的计算,它使用kmeans++算法来加速锚点框的生成。没有在网上找到相关源码实现,不过从官网的issues可以发现作者采用了kmeans++进行锚点框的生成
- pjreddie/darknet
- AlexeyAB/darknet
- howto: calculating custom anchors for YOLOv4-tiny #7856
- stackoverflow
官网也提供了配置文件:
YOLOv4
类似于YOLOv3实现,不过具体的锚点框数值也发生了变化
YOLOv3和YOLOv4的测试环境设置也发生了变化,比如测试图像大小发生了变化,估计和这个会有关系。
YOLOv5
ultralytics/yolov5自定义了锚点框的生成,关键代码位于文件:yolov5/utils/autoanchor.py,其包含了3个函数:
check_anchor_order(m)
:锚点框列表的大小顺序和Detect模块
的步长列表(stride
)保持一致。针对浅层特征层,采用更小的锚点框坐标,用于小目标的预测;针对深层特征层,采用更大的锚点框坐标,用于大目标的预测;check_anchors(dataset, model, thr=4.0, imgsz=640)
:检查配置文件中的锚点框是否和数据集匹配,衡量标准是BPR (Best Possible Recall,最佳召回率)
;kmean_anchors(dataset="./data/coco128.yaml", n=9, img_size=640, thr=4.0, gen=1000, verbose=True)
:锚点计算函数。yolov5使用scipy的kmeans算法实现,同时增加了以下优化:- 过滤
宽或者高==1.0
的极小目标; - 进行聚类计算前,白化宽高列表;
- 通过kmeans得到锚点框后,使用遗传算法来进化锚点以获得更好的匹配度。
- 过滤