YOLO数据集kmeans聚类出anchor的算法

YOLO数据集kmeans聚类出anchor的算法

在使用YOLO算法进行目标检测时,需要将原始数据集中的所有bounding box进行kmeans聚类,以得到一组anchor box,从而用于构建训练模型。本文将介绍如何使用kmeans聚类算法,从而得到一组可供模型使用的anchor box。

聚类算法

聚类算法的目标是将一组数据分为若干个类别,其中每个类别中的数据点应该尽可能相似,不同类别之间的数据点应该尽可能不同。在本文中,我们使用kmeans聚类算法来对bounding box进行聚类。

kmeans聚类

kmeans聚类算法是一种基于距离度量的聚类算法。该算法的目标是将数据点分为k个簇,其中每个簇都应该尽可能紧凑,不同簇之间的距离应该尽可能大。

本文中,我们使用kmeans聚类算法将bounding box分为12个簇。在实现过程中,首先需要随机选择12个点作为初始簇中心,然后对每个bounding box计算其与簇中心之间的距离,最后将bounding box分配到最近的簇中心。接下来,我们需要更新簇中心,具体地,对于每个簇,我们将其所有bounding box的坐标的中位数作为新的簇中心。最后,重复以上步骤,直到簇中心不再改变或达到最大迭代次数为止。

代码实现

下面是使用Python实现的kmeans聚类算法,其中load_dataset函数用于加载数据集,compute_iou函数用于计算bounding box之间的距离,kmeans函数用于实现kmeans聚类算法。

# 代码实现
import numpy as np
from glob import glob
input_dim = 1024
 
 
def compute_iou(box, anchors):
    # distance = 1 - iou
    # dis = []
    ious = []
    for anchor in anchors:
        w_min = np.min([box[0], anchor[0]])
        h_min = np.min([box[1], anchor[1]])
        intersection = w_min*h_min
        union = box[0]*box[1] + anchor[0]*anchor[1]
        iou = intersection/(union - intersection)
        # dis.append(1 - iou)
        ious.append(iou)
    return ious
 
 
def kmeans(boxes, k, dist=np.median):
    # number of boxes
    box_num = len(boxes)
    # store cluster center of each box
    nearest_id = np.zeros(box_num)
    np.random.seed(42)
    # initialize the cluster
    clusters = boxes[np.random.choice([i for i in range(box_num)], k, replace=False)]
    while True:
        # store iou distance between each pair of boxes and anchors
        distance = []
        for i in range(box_num):
            ious = compute_iou(boxes[i], clusters)
            dis = [1-iou for iou in ious]
            distance.append(dis)
        distance = np.array(distance)
        # calculate box cluster id
        new_nearest_id = np.argmin(distance, axis=1)
        # break condition
        if (new_nearest_id == nearest_id).all():
            break
        # update clusters using median strategy
        for j in range(k):
            clusters[j] = dist(boxes[new_nearest_id == j], axis=0)
        nearest_id = new_nearest_id
    return clusters
 
 
def load_dataset(path):
    # load normalization width and height of boxes
    path = path + '/*.txt'
    txt_list = glob(path)
    data_set = []
    for txt in txt_list:
        with open(txt, 'r') as f:
            lines = f.readlines()
        for line in lines:
            coordinate = line.split(' ')
            w, h = np.array(coordinate[3:5], dtype=np.float64)
            data_set.append([w, h])
    data_set = np.array(data_set)
    return data_set
 
 
def main():
    txt_path = '/Users/aoxin/CODE/GraduationProject/plusDataSet/labels/train/'
    data = load_dataset(txt_path)
    # number of cluster center
    clusters = kmeans(data, 12)
    print('cluster center:*************')
    print(clusters*input_dim)
    accuracy = np.mean([np.max(compute_iou(box, clusters)) for box in data])*100
    print('Accuracy(Average iou): %.4f%%' % accuracy)
    anchor_ratio = np.around(clusters[:, 0] / clusters[:, 1], decimals=2)
    anchor_ratio = list(anchor_ratio)
    print('Final anchor_ratio: ', anchor_ratio)
    print('Sorted anchor ratio: ', sorted(anchor_ratio))
 
 
if __name__ == "__main__":
    main()

结果分析

经过kmeans聚类算法,我们得到了一组anchor box,其参数值为:

cluster center:*************
[...]

其中,Accuracy(Average iou)表示平均iou,Final anchor_ratio表示最终得到的anchor box的宽高比,Sorted anchor ratio表示排序后的宽高比。

总结

本文介绍了使用kmeans聚类算法对YOLO数据集进行anchor box生成的方法。通过使用kmeans聚类算法,我们可以快速得到一组可以用于训练模型的anchor box,从而提高模型的准确率。

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

麦滋堡的摸鱼芝士

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值