YoloV3 先验框

本文主要是记录在学习YoloV3模型先验框作用和生成文本参考睿智的目标检测10——先验框详解及其代码实现,这篇博客其实写的非常详细,我在此处就不再展开,仅仅写一下个人学习理解有错误的话还望不吝批评。

先验框

目标检测|Anchor(先验框)的作用

提前在图像上预设好的不同大小,不同长宽比的框,使得模型更加容易学习使用不同尺寸和长宽比可以得到更大的交并比,就有更高的概率出 现对于目标物体有良好匹配度的先验框(体现为高IoU)简单的一句话来讲,先验框就是帮助我们定好了常见目标的宽和高,在进行预测的时候,我们可以利用这个已经定好的宽和高处理,可以帮助我们进行预测。

先验框的生成主要有以下方法:

人为经验选取k-means聚类,可以参看K-Means聚类算法详解作为超参数进行学习

先验框生成方式

在此使用k-means聚类对人工标注好的数据集中目标宽高进行聚类,目的是计算出对于目标物体有良好匹配度的先验框。一般使用k-means聚类时用的是欧拉距离完成聚类,但先验框这是和宽高(我理解为面积)强相关的,所以使用IOU进行计算。注意在k-means聚类时‘"距离值"越小重合度越大,但是"IOU值"与之相反("IOU值"越大重合度越大),所以计算时用不可直接用"IOU值"计算,可以用“1-IOU值“使其满足数值越小重合度越大

d

i

s

t

a

n

c

e

(

i

,

c

e

n

t

e

r

)

=

1

I

O

U

(

i

,

c

e

n

t

e

r

)

distance(i,center)=1−IOU(i,center)

distance(i,center)=1−IOU(i,center)

先验框生成关键代码

这个代码是目标检测|Anchor(先验框)的作用出自这篇博客的。我添加一些注释帮助理解

def kmeans(box, k):

#-------------------------------------------------------------#

# 取出一共有多少框

#-------------------------------------------------------------#

row = box.shape[0]

#-------------------------------------------------------------#

# 每个框各个点的位置

#-------------------------------------------------------------#

distance = np.empty((row, k))

#-------------------------------------------------------------#

# 最后的聚类位置

#-------------------------------------------------------------#

last_clu = np.zeros((row, ))

np.random.seed()

#-------------------------------------------------------------#

# 随机选k个当聚类中心

#-------------------------------------------------------------#

cluster = box[np.random.choice(row, k, replace = False)]

iter = 0

while True:

#-------------------------------------------------------------#

# cas_iou:计算当前框和随机选的k个当聚类中心的IOU,distance: shape = (row, k)

#-------------------------------------------------------------#

for i in range(row):

distance[i] = 1 - cas_iou(box[i], cluster)

#-------------------------------------------------------------#

# 计算当前框到k个当聚类中心最小距离,near是一个下标值,存储所有框最近的距离中心index

#-------------------------------------------------------------#

near = np.argmin(distance, axis=1)

if (last_clu == near).all():

break

#-------------------------------------------------------------#

# 求每一个类的中位点,更新k个聚类中心点的值

#-------------------------------------------------------------#

for j in range(k):

cluster[j] = np.median(

box[near == j],axis=0)

last_clu = near

if iter % 5 == 0:

print('iter: {:d}. avg_iou:{:.2f}'.format(iter, avg_iou(box, cluster)))

iter += 1

return cluster, near

IOU的计算

def cas_iou(box, cluster):

x = np.minimum(cluster[:, 0], box[0])

y = np.minimum(cluster[:, 1], box[1])

intersection = x * y

area1 = box[0] * box[1]

area2 = cluster[:,0] * cluster[:,1]

iou = intersection / (area1 + area2 - intersection)

return iou

查看原文