(yolo v3)使用自己数据集k-means聚类产生的anchor效果反而变差解决方法

  • Post author:
  • Post category:其他




(yolo v3)使用自己数据集k-means聚类产生的anchor效果反而变差解决方法

最近在使用yolo v3训练自己的数据集时,先使用k-means聚类出自己数据集anchors,然后训练自己数据集,最后结果发现预测的效果并不好,预测框得分很低,且容易误检,而使用COCO数据集都感觉效果更好一点,这就让我很怀疑使用k-means聚类产生anchor这个方法是否有效了。

而经过观察发现,原来通过聚类方法产生anchor其实跟你的数据集本身有很大关系,在使用我自己数据集进行训练时,我自己数据集类型单一,且标记框大小都差不多,尺寸比较集中,这个时候通过k-means聚类的方法产生的锚框(anchor box)自然就很集中,几乎相差不大,这就体现不出模型的多尺度输出的优势;同时我发现此时标记框其实有较多是比得到的锚框尺寸大的,这样在训练时对模型要求更高。因此我使用了一种将锚框进行线性尺度的缩放的方式,将锚框尺寸往两边进行一个拉伸,其计算公式和效果如下图所示:




x

1

=

α

x

1

x_1′ = \alpha {x_1}







x










1































=








α




x










1


























x

6

=

β

x

6

x_6′ = \beta {x_6}







x










6































=








β




x










6


























x

i

=

(

x

i

x

1

)

(

x

6

x

1

)

(

x

6

x

1

)

+

x

1

x_i’ = \frac{

{\left( {

{x_i} – {x_1}} \right)}}{

{\left( {

{x_6} – {x_1}} \right)}}\left( {x_6′ – x_1′} \right) + x_1′







x










i































=























(






x










6
























x










1





















)






















(






x










i
























x










1





















)



























(




x










6





































x










1






























)





+









x










1




































y

i

=

x

i

y

i

x

i

y_i’ = x_i’\frac{

{

{y_i}}}{

{

{x_i}}}







y










i































=









x










i












































x










i





































y










i









































在这里插入图片描述

实现代码如下:

import numpy as np
anchor = open('model_data/neuron_anchors.txt') #原始anchors
expand_anchor = open('model_data/neuron_anchors1.txt','w')  #变换后的anchor保存地址
ratio=0.5   #最小的锚框缩小倍数
base_ratio=3  #最大的锚框扩大倍数
box=anchor.read().split(',')
box=np.array(box)
for i in range(0,len(box)):
    box[i]=float(box[i].strip())  
box=box.reshape((len(box)//2,2))
new_box=np.zeros((len(box),2))
length = len(box)
new_box[0,0]=int(float(box[0,0])*ratio)
new_box[0,1]=int(float(box[0,1])*ratio)
new_box[-1,0]=int(float(box[-1,0])*base_ratio)
new_box[-1,1]=int(float(box[-1,1])*base_ratio)
print(box)
for i in range(1,length-1):
    new_box[i,0]=(float(box[i,0])-float(box[0,0]))/(float(box[-1,0])-float(box[0,0]))*(new_box[-1,0]-new_box[0,0])+new_box[0,0]
    new_box[i,1]=new_box[i,0]*float(box[i,1])/float(box[i,0])
    new_box[i,0]=int(new_box[i,0])
    new_box[i,1]=int(new_box[i,1])

for i in range(length):
    if i == 0:
        x_y = "%d,%d" % (new_box[i][0], new_box[i][1])
    else:
        x_y = ",  %d,%d" % (new_box[i][0], new_box[i][1])
    expand_anchor.write(x_y)
expand_anchor.close()
anchor.close()

print(new_box)

anchor的txt文件内容如下:

在这里插入图片描述

使用我的数据集其预测结果对比图如下,可以看到对模型还是有不错提升的:


使用原始anchor

:

在这里插入图片描述


使用变换后的anchor

:

在这里插入图片描述

如果有什么理解不对的地方欢迎评论区指正,不胜感激!!!


相关博客



YOLOV3中k-means聚类获得anchor boxes过程详解



版权声明:本文为qq_42109740原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。