以yolov5s v3为例:
以下是yolov5 v3.0中的anchor
anchors:
1. [10,13, 16,30, 33,23] # P3/8 608/8=76
2. [30,61, 62,45, 59,119] # P4/16 608/16=38
3. [116,90, 156,198, 373,326] # P5/32 608/32=19
为啥anchor一共是3行呢?
答:这里指的是在三个不同分辨率的特征图上的anchor,能够分别对大、中、小目标进行计算。
第一行在最大的特征图上 ----小数值检测大的目标
第二行在第二大的特征图上
第三行在最小的特征图上----大数值检测小的目标
为啥anchor一行是六个数呢,xywh个数也不对啊?
这里就要说一下anchor是怎么生成的了。
-
对于输出层(Prediction),经过前面的一系列特征提取和计算操作后,会生成三个特定大小的特征,大小分别为608/8=76,608/16=38,608/32=19,可能这也是输入图像大小要求是32的倍数的原因。
-
下面是v5代码中采用kmeans计算anchor的过程。
path代表数据yaml路径,n代表聚类数,img_size代表模型输入图片的大小,thr代表长宽比的阈值(将长宽比限定在一定的范围内,这个可以自己统计一下数据集),gen代表kmeans迭代次数。
def kmean_anchors(path='./data/coco128.yaml', n=9, img_size=640, thr=4.0, gen=1000, verbose=True):
""" Creates kmeans-evolved anchors from training dataset
Arguments:
path: path to dataset *.yaml, or a loaded dataset
n: number of anchors
img_size: image size used for training
thr: anchor-label wh ratio threshold hyperparameter hyp['anchor_t'] used for training, default=4.0
gen: generations to evolve anchors using genetic algorithm
Return:
k: kmeans evolved anchors
Usage:
from utils.general import *; _ = kmean_anchors()
"""
thr = 1. / thr
def metric(k, wh): # compute metrics
r = wh[:, None] / k[None]
x = torch.min(r, 1. / r).min(2)[0] # ratio metric
# x = wh_iou(wh, torch.tensor(k)) # iou metric
return x, x.max(