欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

yolov5中anchors設(shè)置實(shí)例詳解

 更新時(shí)間:2022年06月24日 10:16:55   作者:高祥xiang  
在YOLOV5算法之中,針對(duì)不同的數(shù)據(jù)集,一般會(huì)預(yù)先設(shè)置固定的Anchor,下面這篇文章主要給大家介紹了關(guān)于yolov5中anchors設(shè)置的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下

yolov5中增加了自適應(yīng)錨定框(Auto Learning Bounding Box Anchors),而其他yolo系列是沒有的。

一、默認(rèn)錨定框

Yolov5 中默認(rèn)保存了一些針對(duì) coco數(shù)據(jù)集的預(yù)設(shè)錨定框,在 yolov5 的配置文件*.yaml 中已經(jīng)預(yù)設(shè)了640×640圖像大小下錨定框的尺寸(以 yolov5s.yaml 為例):

# anchors
anchors:
  - [10,13, 16,30, 33,23]  # P3/8
  - [30,61, 62,45, 59,119]  # P4/16
  - [116,90, 156,198, 373,326]  # P5/32

 anchors參數(shù)共有三行,每行9個(gè)數(shù)值;且每一行代表應(yīng)用不同的特征圖;

1、第一行是在最大的特征圖上的錨框

2、第二行是在中間的特征圖上的錨框

3、第三行是在最小的特征圖上的錨框;

在目標(biāo)檢測(cè)任務(wù)中,一般希望在大的特征圖上去檢測(cè)小目標(biāo),因?yàn)榇筇卣鲌D才含有更多小目標(biāo)信息,因此大特征圖上的anchor數(shù)值通常設(shè)置為小數(shù)值,而小特征圖上數(shù)值設(shè)置為大數(shù)值檢測(cè)大的目標(biāo)。

二、自定義錨定框

1、訓(xùn)練時(shí)自動(dòng)計(jì)算錨定框

yolov5 中不是只使用默認(rèn)錨定框,在開始訓(xùn)練之前會(huì)對(duì)數(shù)據(jù)集中標(biāo)注信息進(jìn)行核查,計(jì)算此數(shù)據(jù)集標(biāo)注信息針對(duì)默認(rèn)錨定框的最佳召回率,當(dāng)最佳召回率大于或等于0.98,則不需要更新錨定框;如果最佳召回率小于0.98,則需要重新計(jì)算符合此數(shù)據(jù)集的錨定框。

核查錨定框是否適合要求的函數(shù)在 /utils/autoanchor.py 文件中:

def check_anchors(dataset, model, thr=4.0, imgsz=640):

 其中 thr 是指 數(shù)據(jù)集中標(biāo)注框?qū)捀弑茸畲箝撝?,默認(rèn)是使用 超參文件 hyp.scratch.yaml 中的 “anchor_t” 參數(shù)值。

核查主要代碼如下:

    def metric(k):  # compute metric
        r = wh[:, None] / k[None]
        x = torch.min(r, 1. / r).min(2)[0]  # ratio metric
        best = x.max(1)[0]  # best_x
        aat = (x > 1. / thr).float().sum(1).mean()  # anchors above threshold
        bpr = (best > 1. / thr).float().mean()  # best possible recall
        return bpr, aat
 
    bpr, aat = metric(m.anchor_grid.clone().cpu().view(-1, 2))

其中兩個(gè)指標(biāo)需要解釋一下(bpr 和 aat):

bpr(best possible recall) 

aat(anchors above threshold) 

 其中 bpr 參數(shù)就是判斷是否需要重新計(jì)算錨定框的依據(jù)(是否小于 0.98)。

重新計(jì)算符合此數(shù)據(jù)集標(biāo)注框的錨定框,是利用 kmean聚類方法實(shí)現(xiàn)的,代碼在  /utils/autoanchor.py 文件中:

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
            verbose: print all results
        Return:
            k: kmeans evolved anchors
        Usage:
            from utils.autoanchor import *; _ = kmean_anchors()
    """
    thr = 1. / thr
    prefix = colorstr('autoanchor: ')
 
    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(1)[0]  # x, best_x
 
    def anchor_fitness(k):  # mutation fitness
        _, best = metric(torch.tensor(k, dtype=torch.float32), wh)
        return (best * (best > thr).float()).mean()  # fitness
 
    def print_results(k):
        k = k[np.argsort(k.prod(1))]  # sort small to large
        x, best = metric(k, wh0)
        bpr, aat = (best > thr).float().mean(), (x > thr).float().mean() * n  # best possible recall, anch > thr
        print(f'{prefix}thr={thr:.2f}: {bpr:.4f} best possible recall, {aat:.2f} anchors past thr')
        print(f'{prefix}n={n}, img_size={img_size}, metric_all={x.mean():.3f}/{best.mean():.3f}-mean/best, '
              f'past_thr={x[x > thr].mean():.3f}-mean: ', end='')
        for i, x in enumerate(k):
            print('%i,%i' % (round(x[0]), round(x[1])), end=',  ' if i < len(k) - 1 else '\n')  # use in *.cfg
        return k
 
    if isinstance(path, str):  # *.yaml file
        with open(path) as f:
            data_dict = yaml.load(f, Loader=yaml.SafeLoader)  # model dict
        from utils.datasets import LoadImagesAndLabels
        dataset = LoadImagesAndLabels(data_dict['train'], augment=True, rect=True)
    else:
        dataset = path  # dataset
 
    # Get label wh
    shapes = img_size * dataset.shapes / dataset.shapes.max(1, keepdims=True)
    wh0 = np.concatenate([l[:, 3:5] * s for s, l in zip(shapes, dataset.labels)])  # wh
 
    # Filter
    i = (wh0 < 3.0).any(1).sum()
    if i:
        print(f'{prefix}WARNING: Extremely small objects found. {i} of {len(wh0)} labels are < 3 pixels in size.')
    wh = wh0[(wh0 >= 2.0).any(1)]  # filter > 2 pixels
    # wh = wh * (np.random.rand(wh.shape[0], 1) * 0.9 + 0.1)  # multiply by random scale 0-1
 
    # Kmeans calculation
    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
    k *= s
    wh = torch.tensor(wh, dtype=torch.float32)  # filtered
    wh0 = torch.tensor(wh0, dtype=torch.float32)  # unfiltered
    k = print_results(k)
 
    # Plot
    # k, d = [None] * 20, [None] * 20
    # for i in tqdm(range(1, 21)):
    #     k[i-1], d[i-1] = kmeans(wh / s, i)  # points, mean distance
    # fig, ax = plt.subplots(1, 2, figsize=(14, 7), tight_layout=True)
    # ax = ax.ravel()
    # ax[0].plot(np.arange(1, 21), np.array(d) ** 2, marker='.')
    # fig, ax = plt.subplots(1, 2, figsize=(14, 7))  # plot wh
    # ax[0].hist(wh[wh[:, 0]<100, 0],400)
    # ax[1].hist(wh[wh[:, 1]<100, 1],400)
    # fig.savefig('wh.png', dpi=200)
 
    # Evolve
    npr = np.random
    f, sh, mp, s = anchor_fitness(k), k.shape, 0.9, 0.1  # fitness, generations, mutation prob, sigma
    pbar = tqdm(range(gen), desc=f'{prefix}Evolving anchors with Genetic Algorithm:')  # progress bar
    for _ in pbar:
        v = np.ones(sh)
        while (v == 1).all():  # mutate until a change occurs (prevent duplicates)
            v = ((npr.random(sh) < mp) * npr.random() * npr.randn(*sh) * s + 1).clip(0.3, 3.0)
        kg = (k.copy() * v).clip(min=2.0)
        fg = anchor_fitness(kg)
        if fg > f:
            f, k = fg, kg.copy()
            pbar.desc = f'{prefix}Evolving anchors with Genetic Algorithm: fitness = {f:.4f}'
            if verbose:
                print_results(k)
 
    return print_results(k)

對(duì) kmean_anchors()函數(shù)中的參數(shù)做一下簡(jiǎn)單解釋(代碼中已經(jīng)有了英文注釋):

  • path:包含數(shù)據(jù)集文件路徑等相關(guān)信息的 yaml 文件(比如 coco128.yaml), 或者 數(shù)據(jù)集張量(yolov5 自動(dòng)計(jì)算錨定框時(shí)就是用的這種方式,先把數(shù)據(jù)集標(biāo)簽信息讀取再處理)
  • n:錨定框的數(shù)量,即有幾組;默認(rèn)值是9
  • img_size:圖像尺寸。計(jì)算數(shù)據(jù)集樣本標(biāo)簽框的寬高比時(shí),是需要縮放到 img_size 大小后再計(jì)算的;默認(rèn)值是640
  • thr:數(shù)據(jù)集中標(biāo)注框?qū)捀弑茸畲箝撝?,默認(rèn)是使用 超參文件 hyp.scratch.yaml 中的 “anchor_t” 參數(shù)值;默認(rèn)值是4.0;自動(dòng)計(jì)算時(shí),會(huì)自動(dòng)根據(jù)你所使用的數(shù)據(jù)集,來計(jì)算合適的閾值。
  • gen:kmean聚類算法迭代次數(shù),默認(rèn)值是1000
  • verbose:是否打印輸出所有計(jì)算結(jié)果,默認(rèn)值是true

如果你不想自動(dòng)計(jì)算錨定框,可以在 train.py 中設(shè)置參數(shù)即可:

parser.add_argument('--noautoanchor', action='store_true', help='disable autoanchor check')

2、訓(xùn)練前手動(dòng)計(jì)算錨定框

如果使用 yolov5 訓(xùn)練效果并不好(排除其他原因,只考慮 “預(yù)設(shè)錨定框” 這個(gè)因素), yolov5在核查默認(rèn)錨定框是否符合要求時(shí),計(jì)算的最佳召回率大于0.98,沒有自動(dòng)計(jì)算錨定框;此時(shí)你可以自己手動(dòng)計(jì)算錨定框?!炯词棺约旱臄?shù)據(jù)集中目標(biāo)寬高比最大值小于4,默認(rèn)錨定框也不一定是最合適的】

 首先可以自行編寫一個(gè)程序,統(tǒng)計(jì)一下你所訓(xùn)練的數(shù)據(jù)集所有標(biāo)簽框?qū)捀弑龋聪聦捀弑戎饕植荚谀膫€(gè)范圍、最大寬高比是多少? 比如:你使用的數(shù)據(jù)集中目標(biāo)寬高比最大達(dá)到了 5:1(甚至 10:1) ,那肯定需要重新計(jì)算錨定框了,針對(duì)coco數(shù)據(jù)集的最大寬高比是 4:1 。

然后在 yolov5 程序中創(chuàng)建一個(gè)新的 python 文件 test.py,手動(dòng)計(jì)算錨定框:

import utils.autoanchor as autoAC
 
# 對(duì)數(shù)據(jù)集重新計(jì)算 anchors
new_anchors = autoAC.kmean_anchors('./data/mydata.yaml', 9, 640, 5.0, 1000, True)
print(new_anchors)

輸入信息如下(只截取了部分):

autoanchor: Evolving anchors with Genetic Algorithm: fitness = 0.6604:  87%|████████▋ | 866/1000 [00:00<00:00, 2124.00it/s]autoanchor: thr=0.25: 0.9839 best possible recall, 3.84 anchors past thr
autoanchor: n=9, img_size=640, metric_all=0.267/0.662-mean/best, past_thr=0.476-mean: 15,20,  38,25,  55,65,  131,87,  97,174,  139,291,  256,242,  368,382,  565,422
autoanchor: thr=0.25: 0.9849 best possible recall, 3.84 anchors past thr
autoanchor: n=9, img_size=640, metric_all=0.267/0.663-mean/best, past_thr=0.476-mean: 15,20,  39,26,  54,64,  127,87,  97,176,  142,286,  257,245,  374,379,  582,424
autoanchor: thr=0.25: 0.9849 best possible recall, 3.84 anchors past thr
autoanchor: n=9, img_size=640, metric_all=0.267/0.663-mean/best, past_thr=0.476-mean: 15,20,  39,26,  54,63,  126,86,  97,176,  143,285,  258,241,  369,381,  583,424
autoanchor: thr=0.25: 0.9849 best possible recall, 3.84 anchors past thr
autoanchor: n=9, img_size=640, metric_all=0.267/0.663-mean/best, past_thr=0.476-mean: 15,20,  39,26,  54,63,  127,86,  97,176,  143,285,  258,241,  369,380,  583,424
autoanchor: thr=0.25: 0.9849 best possible recall, 3.84 anchors past thr
autoanchor: n=9, img_size=640, metric_all=0.267/0.663-mean/best, past_thr=0.476-mean: 15,20,  39,26,  53,63,  127,86,  97,175,  143,284,  257,243,  369,381,  582,422
autoanchor: thr=0.25: 0.9849 best possible recall, 3.84 anchors past thr
autoanchor: n=9, img_size=640, metric_all=0.267/0.663-mean/best, past_thr=0.476-mean: 15,20,  40,26,  53,62,  129,85,  96,175,  143,287,  256,240,  370,378,  582,419
autoanchor: Evolving anchors with Genetic Algorithm: fitness = 0.6605: 100%|██████████| 1000/1000 [00:00<00:00, 2170.29it/s]
Scanning '..\coco128\labels\train2017.cache' for images and labels... 128 found, 0 missing, 2 empty, 0 corrupted: 100%|██████████| 128/128 [00:00<?, ?it/s]
autoanchor: thr=0.25: 0.9849 best possible recall, 3.84 anchors past thr
autoanchor: n=9, img_size=640, metric_all=0.267/0.663-mean/best, past_thr=0.476-mean: 15,20,  40,26,  53,62,  129,85,  96,175,  143,287,  256,240,  370,378,  582,419
[[     14.931      20.439]
 [     39.648       25.53]
 [     53.371       62.35]
 [     129.07      84.774]
 [     95.719      175.08]
 [     142.69      286.95]
 [     256.46      239.83]
 [      369.9       378.3]
 [     581.87      418.56]]
 
Process finished with exit code 0

輸出的 9 組新的錨定框即是根據(jù)自己的數(shù)據(jù)集來計(jì)算的,可以按照順序替換到你所使用的配置文件*.yaml中(比如 yolov5s.yaml)。就可以重新訓(xùn)練了。

參考的博文(表示感謝!):

https://github.com/ultralytics/yolov5

https://blog.csdn.net/flyfish1986/article/details/117594265

https://zhuanlan.zhihu.com/p/183838757

https://blog.csdn.net/aabbcccddd01/article/details/109578614

總結(jié)

到此這篇關(guān)于yolov5中anchors設(shè)置詳解的文章就介紹到這了,更多相關(guān)yolov5 anchors設(shè)置內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Django 解決阿里云部署同步數(shù)據(jù)庫報(bào)錯(cuò)的問題

    Django 解決阿里云部署同步數(shù)據(jù)庫報(bào)錯(cuò)的問題

    這篇文章主要介紹了Django 解決阿里云部署同步數(shù)據(jù)庫報(bào)錯(cuò)的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-05-05
  • Python3如何在Windows和Linux上打包

    Python3如何在Windows和Linux上打包

    這篇文章主要介紹了Python3如何在Windows和Linux上打包,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-02-02
  • Python拼接微信好友頭像大圖的實(shí)現(xiàn)方法

    Python拼接微信好友頭像大圖的實(shí)現(xiàn)方法

    這篇文章主要介紹了Python拼接微信好友頭像大圖的實(shí)現(xiàn)方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2018-08-08
  • 超詳細(xì)注釋之OpenCV制作圖像Mask

    超詳細(xì)注釋之OpenCV制作圖像Mask

    這篇文章主要介紹了OpenCV制作圖像Mask,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-09-09
  • 詳解Python異常處理中的Finally else的功能

    詳解Python異常處理中的Finally else的功能

    本篇文章主要介紹了詳解Python異常處理中的Finally else的功能,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-12-12
  • python多進(jìn)程并發(fā)demo實(shí)例解析

    python多進(jìn)程并發(fā)demo實(shí)例解析

    這篇文章主要介紹了python多進(jìn)程并發(fā)demo實(shí)例解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-12-12
  • 基于Python實(shí)現(xiàn)本地音樂播放器的制作

    基于Python實(shí)現(xiàn)本地音樂播放器的制作

    這篇文章主要介紹了如何利用Python實(shí)現(xiàn)本地音樂播放器的制作,并且可以選擇需要播放的音樂的路徑,選擇播放方式,感興趣的小伙伴可以了解一下
    2022-06-06
  • python流水線框架pypeln的安裝使用教程

    python流水線框架pypeln的安裝使用教程

    這篇文章主要介紹了python流水線框架pypeln的安裝使用教程,通過安裝pip install pypeln,基本元素在文中給大家介紹過,需要的朋友可以參考下
    2021-05-05
  • 使用Python內(nèi)置模塊與函數(shù)進(jìn)行不同進(jìn)制的數(shù)的轉(zhuǎn)換

    使用Python內(nèi)置模塊與函數(shù)進(jìn)行不同進(jìn)制的數(shù)的轉(zhuǎn)換

    這篇文章主要介紹了使用Python內(nèi)置模塊與函數(shù)進(jìn)行不同進(jìn)制的數(shù)的轉(zhuǎn)換,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-04-04
  • python進(jìn)程和線程用法知識(shí)點(diǎn)總結(jié)

    python進(jìn)程和線程用法知識(shí)點(diǎn)總結(jié)

    在本篇文章里小編給大家整理了關(guān)于python進(jìn)程和線程用法以及相關(guān)實(shí)例內(nèi)容,需要的朋友們跟著學(xué)習(xí)下。
    2019-05-05

最新評(píng)論