在Anchor-based目标检测模型中,根据数据集选择合适的Anchor有利于加快模型的收敛速度以及减少模型的边框预测误差。本篇文章首先介绍
Anchor
在目标检测模型中的作用;然后介绍K-means
聚类算法;最后介绍yolo源码
中自制数据集的Anchor的获取
方法。
1 Anchor的理解
在Anchor-based
目标检测模型中(SSD,YOLO v3/v4/v5等),其通过预先设定的具有不同宽高比
和尺度
的Anchor得到目标的粗略边框,并训练回归参数对Anchor进行修正
以得到目标的准确边框。以YOLOv5为例,其基于Anchor的检测流程如图1所示,在不同尺度的输出特征图使用不同尺度
的Anchor实现对不同大小目标的检测,在一个检测单元中,使用不同宽高比
的Anchor对目标进行预测。
- 在较大的特征图上使用较小的Anchor,实现对小目标的检测;
- 在中等的特征图上使用中等的Anchor,实现对中等大小目标的检测;
- 在较小的特征图上使用较大的Anchor,实现对大目标的检测;
在目标检测模型中,目标的类别预测结果不会随着其在图像中位置的改变而改变
;但目标的边框信息会随着其在图像中位置的改变而改变,通过设定Anchor,实现目标边框对Anchor的偏移量预测,该偏移量不会随着目标在图像中位置的改变而改变
,更有利于模型的回归,符合神经网络位移不变性
。
模型在训练中,根据Anchor和目标实际边框之间的IoU大小,分配用于检测该目标的Anchor。根据数据集科学的设置Anchor有利于加快模型训练时的收敛速度
,减少模型对目标的漏检率
。
2 K-means聚类算法
K-means是最常见的聚类算法,算法接受未标记的数据集,然后将数据聚集成不同的组,其方法如下:
- 首先选取K个随机的点,作为聚类中心;
- 对于数据集中的每一个数据,计算其与聚类中心点的距离,并将其与距离最近的中心点关联起来,与同一个中心点关联的所有点聚成一类;
- 计算每一类的平均值,将该类的中心点移动到平均值的位置;
- 重复步骤2-3,直到中心点不再改变。
3 基于K-means获取自制数据集Anchor
Anchors获取
基于Scipy库中的kmeans函数计算K-means聚类(kmean_anchors)
- 输入:
shapes
(原图大小),labels
(图像标签),n
(聚类中心点个数),img_size
(模型训练图像大小)- 输出:anchors(在模型训练图像上的
绝对大小
)
def kmean_anchors(shapes, labels, n=9, img_size=640):
'''
shapes: 数据集图像大小
labels: 数据集标签 [N, 5] 5->(cls, x, y, w, h)(相对大小)
n: Anchors数量(在img_size上绝对大小)
img_sie:模型训练图像大小
'''
from scipy.cluster.vq import kmeans # 导入kmeans函数, 返回-> k:Anchors; distortion:每一类内点到中心点的平均距离
# 数据集图像输入模型的大小(保持原图比例, 长边缩放为img_size)
shapes = img_size * shapes / shapes.max(1, keepdims=True)
# 得到所有目标的边框(在输入图像上绝对大小)
wh0 = np.concatenate([l[:, 3:5] * s for s, l in zip(shapes, labels)])