草庐IT

yolov5 anchors 中 K-means聚类

国服最强貂蝉 2023-04-09 原文

anchors

运行trains.py没有生成anchor原因

yolov5运行后有一行 autoanchor:

一些教程的生成图如下

训练一开始会先计算Best Possible Recall (BPR),当BPR < 0.98时,再在kmean_anchors函数中进行 k 均值 和 遗传算法 更新 anchors 。

但是我的数据集BPR = 0.9997,所以没有生成新的anchors。
默认的预设anchors很匹配我的训练数据,anchors就不会在更改,就使用预设的。
改了聚类的欧氏距离为iou,和去掉遗传算法,都没有预设的效果好。

yolov5s.yaml anchor:

best.pt 的anchor查看一下和 s 一样

# #################查看模型 的 anchor  #######################
import torch
from models.experimental import attempt_load

model = attempt_load('runs/train/exp_xxxxxxxxxxxx/weights/best.pt', map_location=torch.device('cpu'))
m = model.module.model[-1] if hasattr(model, 'module') else model.model[-1]
print(m.anchor_grid)

如果直接使用预设anchors:
训练时命令行添加–noautoanchor,表示不计算anchor,直接使用配置文件里的默认的anchor,不加该参数表示训练之前会自动计算。

程序

train.py

utils.autoanchor.py
BPR < 0.98时,再在kmean_anchors函数中进行 k 均值 和 遗传算法 更新 anchors

如果就要看它生成anchor的结果,可以把0.98改为0.9999

kmeans改动(距离、k-means++)

用 kmean_anchors 进行聚类。yolov5中用了kmeans和遗传算法。源代码 Kmeans calculation 欧氏距离聚类遗传算法

作者默认使用的k-means方法是scipy包提供的,使用的是欧式距离。
博主改成了基于1-IOU(bboxes, anchors)距离的方法

kmeans和kmeans++参考博客。k-means++算法,属于k-means算法的衍生,其主要解决的是k-means算法第一步,随机选择中心点的问题。

用聚类算法算出来的anchor并不一定比初始值即coco上的anchor要好,原因是目标检测大部分基于迁移学习,backbone网络的训练参数是基于coco上的anchor学习的,所以其实大部分情况用这个聚类效果并没有直接使用coco上的好!!而且聚类效果跟数据集的数量有很大关系,一两千张图片,聚类出来效果可能不会很好

autoanchor.py


    # print(f'{prefix}Running kmeans for {n} anchors on {len(wh)} points...')
    # s = wh.std(0)  # sigmas for whitening
    # k, dist = kmeans(wh / s, n, iter=30)  # points, mean distance
    # assert len(k) == n, f'{prefix}ERROR: scipy.cluster.vq.kmeans requested {n} points but returned only {len(k)}'
    # k *= s
    k = k_means(wh, n)

新建 yolo_kmeans.py

import numpy as np


# 这里IOU的概念更像是只是考虑anchor的长宽
def wh_iou(wh1, wh2):
    # Returns the nxm IoU matrix. wh1 is nx2, wh2 is mx2
    wh1 = wh1[:, None]  # [N,1,2]
    wh2 = wh2[None]  # [1,M,2]
    inter = np.minimum(wh1, wh2).prod(2)  # [N,M]
    return inter / (wh1.prod(2) + wh2.prod(2) - inter)  # iou = inter / (area1 + area2 - inter)


# k-means聚类,且评价指标采用IOU
def k_means(boxes, k, dist=np.median, use_iou=True, use_pp=False):
    """
    yolo k-means methods
    Args:
        boxes: 需要聚类的bboxes,bboxes为n*2包含w,h
        k: 簇数(聚成几类)
        dist: 更新簇坐标的方法(默认使用中位数,比均值效果略好)
        use_iou:是否使用IOU做为计算
        use_pp:是否是同k-means++算法
    """
    box_number = boxes.shape[0]
    last_nearest = np.zeros((box_number,))
    # 在所有的bboxes中随机挑选k个作为簇的中心
    if not use_pp:
        clusters = boxes[np.random.choice(box_number, k, replace=False)]
    # k_means++计算初始值
    else:
        clusters = calc_center(boxes, k)

    # print(clusters)
    while True:
        # 计算每个bboxes离每个簇的距离 1-IOU(bboxes, anchors)
        if use_iou:
            distances = 1 - wh_iou(boxes, clusters)
        else:
            distances = calc_distance(boxes, clusters)
        # 计算每个bboxes距离最近的簇中心
        current_nearest = np.argmin(distances, axis=1)
        # 每个簇中元素不在发生变化说明以及聚类完毕
        if (last_nearest == current_nearest).all():
            break  # clusters won't change
        for cluster in range(k):
            # 根据每个簇中的bboxes重新计算簇中心
            clusters[cluster] = dist(boxes[current_nearest == cluster], axis=0)

        last_nearest = current_nearest

    return clusters


# 计算单独一个点和一个中心的距离
def single_distance(center, point):
    center_x, center_y = center[0] / 2, center[1] / 2
    point_x, point_y = point[0] / 2, point[1] / 2
    return np.sqrt((center_x - point_x) ** 2 + (center_y - point_y) ** 2)


# 计算中心点和其他点直接的距离
def calc_distance(boxes, clusters):
    """
    :param obs: 所有的观测点
    :param clusters: 中心点
    :return:每个点对应中心点的距离
    """
    distances = []
    for box in boxes:
        # center_x, center_y = x/2, y/2
        distance = []
        for center in clusters:
            # center_xc, cneter_yc = xc/2, yc/2
            distance.append(single_distance(box, center))
        distances.append(distance)

    return distances


# k_means++计算中心坐标
def calc_center(boxes, k):
    box_number = boxes.shape[0]
    # 随机选取第一个中心点
    first_index = np.random.choice(box_number, size=1)
    clusters = boxes[first_index]
    # 计算每个样本距中心点的距离
    dist_note = np.zeros(box_number)
    dist_note += np.inf
    for i in range(k):
        # 如果已经找够了聚类中心,则退出
        if i + 1 == k:
            break
        # 计算当前中心点和其他点的距离
        for j in range(box_number):
            j_dist = single_distance(boxes[j], clusters[i])
            if j_dist < dist_note[j]:
                dist_note[j] = j_dist
        # 转换为概率
        dist_p = dist_note / dist_note.sum()
        # 使用赌轮盘法选择下一个点
        next_index = np.random.choice(box_number, 1, p=dist_p)
        next_center = boxes[next_index]
        clusters = np.vstack([clusters, next_center])
    return clusters


还要多远才能进入你的心
还要多久才能和你接近

有关yolov5 anchors 中 K-means聚类的更多相关文章

  1. python - 是否可以使用 Ruby 或 Python 禁用 anchor /引用来发出有效的 YAML? - 2

    是否可以在PyYAML或Ruby的Psych引擎中禁用创建anchor和引用(并有效地显式列出冗余数据)?也许我在网上搜索时遗漏了一些东西,但在Psych中似乎没有太多可用的选项,而且我也无法确定PyYAML是否允许这样做.基本原理是我必须序列化一些数据并将其以可读的形式传递给一个不是真正的技术同事进行手动验证。有些数据是多余的,但我需要以最明确的方式列出它们以提高可读性(anchor和引用是提高效率的好概念,但不是人类可读性)。Ruby和Python是我选择的工具,但如果有其他一些相当简单的方法来“展开”YAML文档,它可能就可以了。 最佳答案

  2. ruby - :this means in Ruby on Rails? 是什么 - 2

    我是Ruby和RubyonRails世界的新手。我已经阅读了一些指南,但我在使用以下语法时遇到了一些麻烦。我认为在Ruby中使用:condition语法来定义具有某种访问器的类属性,例如:classSampleattr_accessor:conditionend隐式声明“条件”属性的getter和setter。当我查看一些Rails示例代码时,我发现以下示例我并不完全理解。例如:@post=Post.find(params[:id])为什么它使用这种语法访问id属性,而不是:@post=Post.find(params[id])或者,例如:@posts=Post.find(:all):

  3. ruby - : mean in rails before a variable name? 是什么 - 2

    例如,:符号-我正在尝试弄清楚:的含义,以及它与@的区别也没有任何符号。如果有真正有用的指南! 最佳答案 它是一个符号,是一种Ruby语言结构。符号类似于字符串,但thisblogpost解释细节。@表示类的实例变量:它基本上是一个在类实例的所有方法之间共享的变量。它与:无关。 关于ruby-:meaninrailsbeforeavariablename?是什么,我们在StackOverflow上找到一个类似的问题: https://stackoverflow

  4. 关于yolov5训练时参数workers和batch-size的理解 - 2

    关于yolov5训练时参数workers和batch-size的理解yolov5训练命令workers和batch-size参数的理解两个参数的调优总结yolov5训练命令python.\train.py--datamy.yaml--workers8--batch-size32--epochs100yolov5的训练很简单,下载好仓库,装好依赖后,只需自定义一下data目录中的yaml文件就可以了。这里我使用自定义的my.yaml文件,里面就是定义数据集位置和训练种类数和名字。workers和batch-size参数的理解一般训练主要需要调整的参数是这两个:workers指数据装载时cpu所使

  5. ruby-on-rails - ruby rails : what does "equals" symbol mean as a parameter? - 2

    我一直在使用的一些开放源代码具有以下行作为函数声明:defparse_query(query=nil,options={},models=nil)“等于”符号对语句有什么影响?它只是使参数可选吗? 最佳答案 如果调用函数的人没有指定参数,它会设置参数的默认值。 关于ruby-on-rails-rubyrails:whatdoes"equals"symbolmeanasaparameter?,我们在StackOverflow上找到一个类似的问题: https:/

  6. ruby-on-rails - 未定义方法 `upload' 用于 nil :NilClass Did you mean? 加载 - 2

    尝试将ActiveStorage用于简单的图像上传表单。它创建成功,但在提交时抛出错误:undefinedmethod`upload'fornil:NilClassDidyoumean?load这是它要我查看的block:@comment=Comment.create!params.require(:comment).permit(:content)@comment.image.attach(params[:comment][:image])redirect_tocomments_pathend这是在完整的Controller中:classCommentsController实际应该发

  7. ruby-on-rails - rails gem prawn,图像和 anchor - 2

    你能告诉我如何插入图片,例如第20页的链接吗?我知道如何用普通文本制作:text"Gotopage20",:inline_format=>true然后在第20页我有add_dest('page20',dest_fit(page.dictionary))但是如何用图像来做呢? 最佳答案 部分归功于lightswitch05对于正确方向的一些刺激,我找到了一种通过这种不优雅的方式获得我想要的效果的方法:在bounding_box中插入一张图片(此时页面cursor位于图片底部)将光标移回图片顶部在图片上插入一个文本链接(在我的例子中,我

  8. ruby - 在不破坏 anchor 和别名的情况下读写 YAML 文件? - 2

    我需要打开一个YAML文件,其中使用了别名:defaults:&defaultsfoo:barzip:buttonnode:这显然扩展为等效的YAML文档:defaults:foo:barzip:buttonnode:foo:otherzip:buttonYAML::load将其读取为。我需要在此YAML文档中设置新键,然后将其写回磁盘,尽可能保留原始结构。我看过YAML::Store,但这完全破坏了别名和anchor。是否有任何可用的东西:thing=Thing.load("config.yml")thing[:node][:foo]="yetanother"将文档另存为:defau

  9. Ruby 基准测试模块 : meanings of "user", "system"和 "real"? - 2

    试验Ruby的基准模块...>>Benchmark.bm(7){|b|b.report('Report:'){s='';10000.times{s+='a'}}}usersystemtotalrealReport:0.1500000.0100000.160000(0.156361)“用户”、“系统”、“真实”的含义是什么? 最佳答案 这些时间与Unixtime命令或其他典型基准测试工具报告的时间相同:user:执行用户空间代码(即:您的代码)所花费的时间,system:执行内核代码所花费的时间和真实:执行代码所花费的“真实”时间(即

  10. ruby-on-rails - Rails - 渲染 :action to target anchor tag? - 2

    我希望像这样使用渲染:render:action=>'page#form'我也试过这个:render:template=>'site/page#form'那也没用。这个特定页面上的表单位于最底部,如果提交时出现任何错误,我不希望用户被默认显示在页面顶部。我还需要使用渲染(而不是重定向),因为我需要保留对象及其错误。如何呈现以定位特定anchor标记? 最佳答案 相信我找到了解决方案。对于遇到此问题的任何其他人,请像这样指向表格:似乎已经解决了问题。 关于ruby-on-rails-Rai

随机推荐