chinese直男口爆体育生外卖, 99久久er热在这里只有精品99, 又色又爽又黄18禁美女裸身无遮挡, gogogo高清免费观看日本电视,私密按摩师高清版在线,人妻视频毛茸茸,91论坛 兴趣闲谈,欧美 亚洲 精品 8区,国产精品久久久久精品免费

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示

YOLOv5中的autoanchor.py代碼解析

jf_pmFSk4VX ? 來(lái)源:GiantPandaCV ? 2023-01-11 15:40 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

前言

代碼倉(cāng)庫(kù)地址:https://github.com/Oneflow-Inc/one-yolov5歡迎star one-yolov5項(xiàng)目 獲取最新的動(dòng)態(tài)。如果您有問(wèn)題,歡迎在倉(cāng)庫(kù)給我們提出寶貴的意見(jiàn)。如果對(duì)您有幫助,歡迎來(lái)給我Star呀~

由于文章中一些鏈接會(huì)被微信公眾號(hào)吃掉,所以推薦訪問(wèn)文章的原始地址獲得更好的閱讀體驗(yàn)。https://start.oneflow.org/oneflow-yolo-doc/source_code_interpretation/utils/autoanchor_py.html

源碼解讀: utils/autoanchor.py

摘要

維度聚類(Dimension Clusters)。當(dāng)把 YOLO 結(jié)合 anchor boxes 使用時(shí),我們會(huì)遇到兩個(gè)問(wèn)題: 首先 anchor boxes 的尺寸是手工挑選的。雖然網(wǎng)絡(luò)可以通過(guò)學(xué)習(xí)適當(dāng)?shù)卣{(diào)整 anchor boxes 形狀,但是如果我們從一開始就為網(wǎng)絡(luò)選擇更好的 anchor boxes ,就可以讓網(wǎng)絡(luò)更容易學(xué)習(xí)并獲得更好的檢測(cè)結(jié)果。

4eef502e-90eb-11ed-bfe3-dac502259ad0.pngimage

圖1:VOC 和 COCO 上的聚類框尺寸。我們?cè)谶吔缈虻木S度(dimensions of bounding boxes) 上運(yùn)行 K-means聚類,以獲得我們模型良好的初始 anchor boxes 。左圖顯示了我們通過(guò) k 的各種選擇獲得的 Avg IoU 。我們發(fā)現(xiàn) k = 5 為召回與模型的復(fù)雜性提供了良好的折中。 右圖顯示了在 VOC 和 COCO 上聚類簇的相對(duì)中心, 并且這兩種不同的 k 對(duì)應(yīng)方案都喜歡更稀疏的,更高的框,此外在 COCO 的尺寸的變化比 VOC 更大。

我們不用手工選擇 anchor boxes,而是在訓(xùn)練集的邊界框上的維度上運(yùn)行 K-means 聚類算法,自動(dòng)找到良好的 anchor boxes 。 如果我們使用具有歐幾里得距離的標(biāo)準(zhǔn) K-means,那么較大的框會(huì)比較小的框產(chǎn)生更多的誤差。 但我們真正想要的是獨(dú)立于框的大小的,能獲得良好的 IoU 分?jǐn)?shù)的 anchor boxes 。 因此對(duì)于距離的度量方式我們使用:

我們用不同的 值運(yùn)行 K-means算法,并繪制最接近聚類中心的平均 Avg IoU(見(jiàn)圖1)。為了在模型復(fù)雜度和高召回率之間的良好折中,我們選擇 k = 5 (也就是5種anchor boxes)簇的相對(duì)中心 與手工選取的 anchor boxes 顯著不同,它有更少的短且寬的框,并且有更多既長(zhǎng)又窄的框。

表1中,我們將聚類策略得到的 anchor boxes 和手工選取的 anchor boxes 在最接近的 Avg IoU 上進(jìn)行比較。通過(guò)聚類策略得到的僅5種 anchor boxes 的 Avg IoU 為61.0,其性能類似于9個(gè)通過(guò)網(wǎng)絡(luò)學(xué)習(xí)的 anchor boxes 的60.9 (即Avg IoU已經(jīng)達(dá)到了Faster RCNN的水平)。 而且使用9種 anchor boxes 會(huì)得到更高的 Avg IoU 。這表明使用 K-means生成 anchor boxes 可以更好地表示模型并使其更容易學(xué)習(xí)。

表1: VOC 2007 上聚類得結(jié)果比使用手工選取的 anchor boxes 結(jié)果要好得多。

什么是K-means?

K-means是非常經(jīng)典且有效的聚類方法,通過(guò)計(jì)算樣本之間的距離(相似程度)將較近的樣本聚為同一類別(簇)。

在 yolov5/one-yolov5 項(xiàng)目中使用 K-means 必須滿足下面的條件:

  1. train.py的parse_opt下的參數(shù)noautoanchor必須為False
  2. hpy.scratch.yaml下的anchors參數(shù)注釋掉。

使用K-means時(shí)主要關(guān)注兩點(diǎn)

  1. 如何表示樣本與樣本之間的距離(核心問(wèn)題),這個(gè)一般需要根據(jù)具體場(chǎng)景去設(shè)計(jì),不同的方法聚類效果也不同,最常見(jiàn)的就是歐式距離,在目標(biāo)檢測(cè)領(lǐng)域常見(jiàn)的是IoU。
  2. 分為幾類,這個(gè)也是需要根據(jù)應(yīng)用場(chǎng)景取選擇的,也是一個(gè)超參數(shù)。

K-means算法主要流程

  1. 手動(dòng)設(shè)定簇的個(gè)數(shù)k,假設(shè)k=2;
  2. 在所有樣本中隨機(jī)選取k個(gè)樣本作為簇的初始中心,如下圖(random clusters)中兩個(gè)黃色的小星星代表隨機(jī)初始化的兩個(gè)簇中心;
  3. 計(jì)算每個(gè)樣本離每個(gè)簇中心的距離(這里以歐式距離為例),然后將樣本劃分到離它最近的簇中。如下圖(step 0)用不同的顏色區(qū)分不同的簇;
  4. 更新簇的中心,計(jì)算每個(gè)簇中所有樣本的均值(方法不唯一)作為新的簇中心。如下圖(step 1)所示,兩個(gè)黃色的小星星已經(jīng)移動(dòng)到對(duì)應(yīng)簇的中心;
  5. 重復(fù)第3步到第4步直到簇中心不在變化或者簇中心變化很小滿足給定終止條件。如下圖(step2)所示,最終聚類結(jié)果。
4f0cc5f0-90eb-11ed-bfe3-dac502259ad0.pngimage

什么是BPR?

BPR(BPR best possible recall來(lái)源于論文: FCOS.

原論文解釋:

BPR is defined as the ratio of the number of ground-truth boxes a detector can recall at the most divided by all ground-truth boxes. A ground-truth box is considered being recalled if the box is assigned to at least one sample (i.e., a location in FCOS or an anchor box in anchor-based detectors) during training.

BPR (best possible recall): 最多能被召回的 ground truth 框數(shù)量 / 所有 ground truth 框數(shù)量。最大值為1 越大越好 小于0.98就需要使用K-means + 遺傳進(jìn)化算法選擇出與數(shù)據(jù)集更匹配的anchor boxes框。

什么是白化操作whiten?

白化的目的是去除輸入數(shù)據(jù)的冗余信息。假設(shè)訓(xùn)練數(shù)據(jù)是圖像,由于圖像中相鄰像素之間具有很強(qiáng)的相關(guān)性,所以用于訓(xùn)練時(shí)輸入是冗余的;白化的目的就是降低輸入的冗余性。

輸入數(shù)據(jù)集X,經(jīng)過(guò)白化處理后,新的數(shù)據(jù)X’滿足兩個(gè)性質(zhì):

  1. 特征之間相關(guān)性較低;
  2. 所有特征具有相同的方差=1

常見(jiàn)的作法是:對(duì)每一個(gè)數(shù)據(jù)做一個(gè)標(biāo)準(zhǔn)差歸一化處理(除以標(biāo)準(zhǔn)差)。scipy.cluster.vq.kmeans() 函數(shù)輸入的數(shù)據(jù)就是必須是白化后的數(shù)據(jù)。相應(yīng)輸出的 anchor boxes 也是白化后的anchor,所以需要將anchor boxes 都乘以標(biāo)準(zhǔn)差恢復(fù)到原始圖像尺度。

YOLOv5 中的 autoanchor.py 代碼解析

1. 導(dǎo)入需要的包

importnumpyasnp#numpy矩陣操作模塊
importoneflowasflow#OneFlow深度學(xué)習(xí)模塊
importyaml#操作yaml文件模塊
fromtqdmimporttqdm#Python進(jìn)度條模塊

fromutils.generalimportLOGGER,colorstr#日志模塊

PREFIX=colorstr("AutoAnchor:")

2.check_anchor_order

這個(gè)函數(shù)用于確認(rèn)當(dāng)前anchors和stride的順序是否是一致的,因?yàn)槲覀兊膍.anchors是相對(duì)各個(gè)feature map

(每個(gè)feature map的感受野不同 檢測(cè)的目標(biāo)大小也不同 適合的anchor大小也不同)所以必須要順序一致 否則效果會(huì)很不好。

這個(gè)函數(shù)一般用于check_anchors最后階段。

defcheck_anchor_order(m):
"""用在check_anchors函數(shù)的最后確定anchors和stride的順序是一致的
CheckanchororderagainststrideorderforYOLOv5Detect()modulem,andcorrectifnecessary
:paramsm:model中的最后一層Detect層
"""
#CheckanchororderagainststrideorderforYOLOv5Detect()modulem,andcorrectifnecessary
#計(jì)算anchor的面積anchorarea[9]
a=m.anchors.prod(-1).mean(-1).view(-1)#meananchorareaperoutputlayer
#計(jì)算最大anchor與最小anchor面積差
da=a[-1]-a[0]#deltaa
#計(jì)算最大stride與最小stride差
#m.stride:modelstrides
#https://github.com/Oneflow-Inc/one-yolov5/blob/bf8c66e011fcf5b8885068074ffc6b56c113a20c/models/yolo.py#L144-L152
ds=m.stride[-1]-m.stride[0]#deltas
#flow.sign(x):當(dāng)x大于/小于0時(shí),返回1/-1
#如果這里anchor與stride順序不一致,則重新調(diào)整順序,但注意這里要拋出warning
ifdaand(da.sign()!=ds.sign()):#sameorder
LOGGER.info(f"{PREFIX}Reversinganchororder")
m.anchors[:]=m.anchors.flip(0)

3. kmean_anchors

這個(gè)函數(shù)才是這個(gè)這個(gè)文件的核心函數(shù)。功能:使用 K-means + 遺傳算法 算出更符合當(dāng)前數(shù)據(jù)集的anchors。

這里不僅僅使用了 K-means 聚類,還使用了 Genetic Algorithm 遺傳算法,在 K-means 聚類的結(jié)果上進(jìn)行 mutation(變異)。接下來(lái)簡(jiǎn)單介紹下代碼流程:

  1. 載入數(shù)據(jù)集,得到數(shù)據(jù)集中所有數(shù)據(jù)的wh
  2. 將每張圖片中wh的最大值等比例縮放到指定大小img_size,較小邊也相應(yīng)縮放
  3. 將bboxes從相對(duì)坐標(biāo)改成絕對(duì)坐標(biāo)(乘以縮放后的wh)
  4. 篩選bboxes,保留wh都大于等于兩個(gè)像素的bboxes
  5. 使用K-means聚類得到n個(gè)anchors(調(diào)用K-means包 涉及一個(gè)白化操作)
  6. 使用遺傳算法隨機(jī)對(duì)anchors的wh進(jìn)行變異,如果變異后效果變得更好(使用anchor_fitness方法計(jì)算得到的fitness(適應(yīng)度)進(jìn)行評(píng)估)就將變異后的結(jié)果賦值給anchors,如果變異后效果變差就跳過(guò),默認(rèn)變異1000次

不知道什么是遺傳算法,可以看看這兩個(gè)b站視頻:傳算法超細(xì)致+透徹理解和霹靂吧啦Wz

defkmean_anchors(path='./data/coco128.yaml',n=9,img_size=640,thr=4.0,gen=1000,verbose=True):
"""在check_anchors中調(diào)用
使用K-means+遺傳算法算出更符合當(dāng)前數(shù)據(jù)集的anchors
Createskmeans-evolvedanchorsfromtrainingdataset
:paramspath:數(shù)據(jù)集的路徑/數(shù)據(jù)集本身
:paramsn:anchors的個(gè)數(shù)
:paramsimg_size:數(shù)據(jù)集圖片約定的大小
:paramsthr:閾值由hyp['anchor_t']參數(shù)控制
:paramsgen:遺傳算法進(jìn)化迭代的次數(shù)(突變+選擇)
:paramsverbose:是否打印所有的進(jìn)化(成功的)結(jié)果默認(rèn)傳入是False,只打印最佳的進(jìn)化結(jié)果
:returnk:K-means+遺傳算法進(jìn)化后的anchors
"""
fromscipy.cluster.vqimportkmeans


#注意一下下面的thr不是傳入的thr,而是1/thr,所以在計(jì)算指標(biāo)這方面還是和check_anchor一樣
thr=1./thr#0.25
prefix=colorstr('autoanchor:')

defmetric(k,wh):#computemetrics
"""用于print_results函數(shù)和anchor_fitness函數(shù)
計(jì)算ratiometric:整個(gè)數(shù)據(jù)集的groundtruth框與anchor對(duì)應(yīng)寬比和高比即:gt_w/k_w,gt_h/k_h+x+best_x用于后續(xù)計(jì)算BPR+aat
注意我們這里選擇的metric是groundtruth框與anchor對(duì)應(yīng)寬比和高比而不是常用的iou這點(diǎn)也與nms的篩選條件對(duì)應(yīng)是yolov5中使用的新方法
:paramsk:anchor框
:paramswh:整個(gè)數(shù)據(jù)集的wh[N,2]
:returnx:[N,9]N個(gè)groundtruth框與所有anchor框的寬比或高比(兩者之中較小者)
:returnx.max(1)[0]:[N]N個(gè)groundtruth框與所有anchor框中的最大寬比或高比(兩者之中較小者)
"""
#[N,1,2]/[1,9,2]=[N,9,2]N個(gè)gt_wh和9個(gè)anchor的k_wh寬比和高比
#兩者的重合程度越高就越趨近于1遠(yuǎn)離1(<1?或?>1)重合程度都越低
r=wh[:,None]/k[None]
#r=gt_height/anchor_heightgt_width/anchor_width有可能大于1,也可能小于等于1
#flow.min(r,1./r):[N,9,2]將所有的寬比和高比統(tǒng)一到<=1
#.min(2):value=[N,9]選出每個(gè)groundtruth個(gè)和anchor的寬比和高比最小的值index:[N,9]這個(gè)最小值是寬比(0)還是高比(1)
#[0]返回value[N,9]每個(gè)groundtruth個(gè)和anchor的寬比和高比最小的值就是所有g(shù)roundtruth與anchor重合程度最低的
x=flow.min(r,1./r).min(2)[0]#ratiometric
#x=wh_iou(wh,flow.tensor(k))#IoUmetric
#x.max(1)[0]:[N]返回每個(gè)groundtruth和所有anchor(9個(gè))中寬比/高比最大的值
returnx,x.max(1)[0]#x,best_x

defanchor_fitness(k):#mutationfitness
"""用于kmean_anchors函數(shù)
適應(yīng)度計(jì)算優(yōu)勝劣汰用于遺傳算法中衡量突變是否有效的標(biāo)注如果有效就進(jìn)行選擇操作,無(wú)效就繼續(xù)下一輪的突變
:paramsk:[9,2]K-means生成的9個(gè)anchorswh:[N,2]:數(shù)據(jù)集的所有g(shù)roundtruth框的寬高
:return(best*(best>thr).float()).mean()=適應(yīng)度計(jì)算公式[1]注意和BPR有區(qū)別這里是自定義的一種適應(yīng)度公式
返回的是輸入此時(shí)anchork對(duì)應(yīng)的適應(yīng)度
"""
_,best=metric(flow.tensor(k,dtype=flow.float32),wh)
return(best*(best>thr).float()).mean()#fitness

defprint_results(k):
"""用于kmean_anchors函數(shù)中打印K-means計(jì)算相關(guān)信息
計(jì)算BPR、aat=>打印信息:閾值+BPR+aatanchor個(gè)數(shù)+圖片大小+metric_all+best_mean+past_mean+Kmeans聚類出來(lái)的anchor框(四舍五入)
:paramsk:K-means得到的anchork
:returnk:input
"""
#將K-means得到的anchork按面積從小到大排序
k=k[np.argsort(k.prod(1))]
#x:[N,9]N個(gè)groundtruth框與所有anchor框的寬比或高比(兩者之中較小者)
#best:[N]N個(gè)groundtruth框與所有anchor框中的最大寬比或高比(兩者之中較小者)
x,best=metric(k,wh0)
#(best>thr).float():True=>1.False->0..mean():求均值
#BPR(bestpossiblerecall):最多能被召回(通過(guò)thr)的groundtruth框數(shù)量/所有g(shù)roundtruth框數(shù)量[1]0.96223小于0.98才會(huì)用K-means計(jì)算anchor
#aat(anchorsabovethreshold):[1]3.54360每個(gè)target平均有多少個(gè)anchors
BPR,aat=(best>thr).float().mean(),(x>thr).float().mean()*n#bestpossiblerecall,anch>thr
f=anchor_fitness(k)
#print(f'{prefix}thr={thr:.2f}:{BPR:.4f}bestpossiblerecall,{aat:.2f}anchorspastthr')
#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='')
print(f"aat:{aat:.5f},fitness:{f:.5f},bestpossiblerecall:{BPR:.5f}")
fori,xinenumerate(k):
print('%i,%i'%(round(x[0]),round(x[1])),end=','ifi1else'
')#usein*.cfg

returnk


#載入數(shù)據(jù)集
ifisinstance(path,str):#*.yamlfile
withopen(path)asf:
data_dict=yaml.safe_load(f)#modeldict
fromutils.datasetsimportLoadImagesAndLabels
dataset=LoadImagesAndLabels(data_dict['train'],augment=True,rect=True)
else:
dataset=path#dataset

#得到數(shù)據(jù)集中所有數(shù)據(jù)的wh
#將數(shù)據(jù)集圖片的最長(zhǎng)邊縮放到img_size,較小邊相應(yīng)縮放
shapes=img_size*dataset.shapes/dataset.shapes.max(1,keepdims=True)
#將原本數(shù)據(jù)集中g(shù)tboxes歸一化的wh縮放到shapes尺度
wh0=np.concatenate([l[:,3:5]*sfors,linzip(shapes,dataset.labels)])

#統(tǒng)計(jì)gtboxes中寬或者高小于3個(gè)像素的個(gè)數(shù),目標(biāo)太小發(fā)出警告
i=(wh03.0).any(1).sum()
ifi:
print(f'{prefix}WARNING:Extremelysmallobjectsfound.{i}of{len(wh0)}labelsare)

#篩選出label大于2個(gè)像素的框拿來(lái)聚類,[...]內(nèi)的相當(dāng)于一個(gè)篩選器,為True的留下
wh=wh0[(wh0>=2.0).any(1)]#filter>2pixels
#wh=wh*(np.random.rand(wh.shape[0],1)*0.9+0.1)#multiplybyrandomscale0-1

#Kmeans聚類方法:使用歐式距離來(lái)進(jìn)行聚類
print(f'{prefix}Runningkmeansfor{n}anchorson{len(wh)}gtboxes...')
#計(jì)算寬和高的標(biāo)準(zhǔn)差->[w_std,h_std]
s=wh.std(0)#sigmasforwhitening
#開始聚類,仍然是聚成n類,返回聚類后的anchorsk(這個(gè)anchorsk是白化后數(shù)據(jù)的anchor框s)
#另外還要注意的是這里的kmeans使用歐式距離來(lái)計(jì)算的
#運(yùn)行K-means的次數(shù)為30次obs:傳入的數(shù)據(jù)必須先白化處理'whitenoperation'
#白化處理:新數(shù)據(jù)的標(biāo)準(zhǔn)差=1降低數(shù)據(jù)之間的相關(guān)度,不同數(shù)據(jù)所蘊(yùn)含的信息之間的重復(fù)性就會(huì)降低,網(wǎng)絡(luò)的訓(xùn)練效率就會(huì)提高
#白化操作參考博客:https://blog.csdn.net/weixin_37872766/article/details/102957235
k,dist=kmeans(wh/s,n,iter=30)#points,meandistance
assertlen(k)==n,print(f'{prefix}ERROR:scipy.cluster.vq.kmeansrequested{n}pointsbutreturnedonly{len(k)}')
k*=s#k*s得到原來(lái)數(shù)據(jù)(白化前)的anchor框

wh=flow.tensor(wh,dtype=flow.float32)#filteredwh
wh0=flow.tensor(wh0,dtype=flow.float32)#unfilteredwh0

#輸出新算的anchorsk相關(guān)的信息
k=print_results(k)

#Plotwh
#k,d=[None]*20,[None]*20
#foriintqdm(range(1,21)):
#k[i-1],d[i-1]=kmeans(wh/s,i)#points,meandistance
#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))#plotwh
#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類似遺傳/進(jìn)化算法變異操作
npr=np.random#隨機(jī)工具
#f:fitness0.62690
#sh:(9,2)
#mp:突變比例mutationprob=0.9s:sigma=0.1
f,sh,mp,s=anchor_fitness(k),k.shape,0.9,0.1#fitness,generations,mutationprob,sigma
pbar=tqdm(range(gen),desc=f'{prefix}EvolvinganchorswithGeneticAlgorithm:')#progressbar
#根據(jù)聚類出來(lái)的n個(gè)點(diǎn)采用遺傳算法生成新的anchor
for_inpbar:
#重復(fù)1000次突變+選擇選擇出1000次突變里的最佳a(bǔ)nchork和最佳適應(yīng)度f(wàn)
v=np.ones(sh)#v[9,2]全是1
while(v==1).all():
#產(chǎn)生變異規(guī)則mutateuntilachangeoccurs(preventduplicates)
#npr.random(sh)
v=((npr.random(sh)1).clip(0.3,3.0)
#變異(改變這一時(shí)刻之前的最佳適應(yīng)度對(duì)應(yīng)的anchork)
kg=(k.copy()*v).clip(min=2.0)
#計(jì)算變異后的anchorkg的適應(yīng)度
fg=anchor_fitness(kg)
#如果變異后的anchorkg的適應(yīng)度>最佳適應(yīng)度k就進(jìn)行選擇操作
iffg>f:
#選擇變異后的anchorkg為最佳的anchork變異后的適應(yīng)度f(wàn)g為最佳適應(yīng)度f(wàn)
f,k=fg,kg.copy()

#打印信息
pbar.desc=f'{prefix}EvolvinganchorswithGeneticAlgorithm:fitness={f:.4f}'
ifverbose:
print_results(k)
returnprint_results(k)

4. check_anchors

這個(gè)函數(shù)是通過(guò)計(jì)算BPR確定是否需要改變anchors 需要就調(diào)用K-means重新計(jì)算anchors。

defcheck_anchors(dataset,model,thr=4.0,imgsz=640):
#Checkanchorfittodata,recomputeifnecessary
"""用于train.py中
通過(guò)BPR確定是否需要改變anchors需要就調(diào)用K-means重新計(jì)算anchors
Checkanchorfittodata,recomputeifnecessary
:paramsdataset:自定義數(shù)據(jù)集LoadImagesAndLabels返回的數(shù)據(jù)集
:paramsmodel:初始化的模型
:paramsthr:超參中得到界定anchor與label匹配程度的閾值
:paramsimgsz:圖片尺寸默認(rèn)640
"""
#從model中取出最后一層(Detect)
m=model.module.model[-1]ifhasattr(model,"module")elsemodel.model[-1]#Detect()
#dataset.shapes.max(1,keepdims=True)=每張圖片的較長(zhǎng)邊
#shapes:將數(shù)據(jù)集圖片的最長(zhǎng)邊縮放到img_size,較小邊相應(yīng)縮放得到新的所有數(shù)據(jù)集圖片的寬高[N,2]
shapes=imgsz*dataset.shapes/dataset.shapes.max(1,keepdims=True)
#產(chǎn)生隨機(jī)數(shù)scale[img_size,1]
scale=np.random.uniform(0.9,1.1,size=(shapes.shape[0],1))#augmentscale
#[6301,2]所有target(6301個(gè))的wh基于原圖大小shapes*scale:隨機(jī)化尺度變化
wh=flow.tensor(np.concatenate([l[:,3:5]*sfors,linzip(shapes*scale,dataset.labels)])).float()#wh

defmetric(k):#computemetric
"""用在check_anchors函數(shù)中computemetric
根據(jù)數(shù)據(jù)集的所有圖片的wh和當(dāng)前所有anchorsk計(jì)算BPR(bestpossiblerecall)和aat(anchorsabovethreshold)
:paramsk:anchors[9,2]wh:[N,2]
:returnBPR:bestpossiblerecall最多能被召回(通過(guò)thr)的groundtruth框數(shù)量/所有g(shù)roundtruth框數(shù)量小于0.98才會(huì)用K-means計(jì)算anchor
:returnaat:anchorsabovethreshold每個(gè)target平均有多少個(gè)anchors
"""
#None添加維度所有target(gt)的whwh[:,None][6301,2]->[6301,1,2]
#所有anchor的whk[None][9,2]->[1,9,2]
#r:target的高h(yuǎn)寬w與anchor的高h(yuǎn)_a寬w_a的比值,即h/h_a,w/w_a[6301,9,2]有可能大于1,也可能小于等于1
r=wh[:,None]/k[None]
#x高寬比和寬高比的最小值無(wú)論r大于1,還是小于等于1最后統(tǒng)一結(jié)果都要小于1[6301,9]
x=flow.min(r,1/r).min(2)[0]#ratiometric
#best[6301]為每個(gè)groundtruth框選擇匹配所有anchors寬高比例值最好的那一個(gè)比值
best=x.max(1)[0]#best_x
#aat(anchorsabovethreshold)每個(gè)target平均有多少個(gè)anchors
aat=(x>1/thr).float().sum(1).mean()#anchorsabovethreshold
#BPR(bestpossiblerecall)=最多能被召回(通過(guò)thr)的groundtruth框數(shù)量/所有g(shù)roundtruth框數(shù)量小于0.98才會(huì)用K-means計(jì)算anchor
BPR=(best>1/thr).float().mean()#bestpossiblerecall
returnBPR,aat

stride=m.stride.to(m.anchors.device).view(-1,1,1)#modelstrides
#anchors:[N,2]所有anchors的寬高基于縮放后的圖片大小(較長(zhǎng)邊為640較小邊相應(yīng)縮放)
anchors=m.anchors.clone()*stride#currentanchors
BPR,aat=metric(anchors.cpu().view(-1,2))
s=f"
{PREFIX}{aat:.2f}anchors/target,{BPR:.3f}BestPossibleRecall(BPR)."
#考慮這9類anchor的寬高和groundtruth框的寬高之間的差距,如果BPR<0.98(說(shuō)明當(dāng)前anchor不能很好的匹配數(shù)據(jù)集?ground?truth?框)就會(huì)根據(jù)K-means算法重新聚類新的anchor
ifBPR>0.98:#thresholdtorecompute
LOGGER.info(f"{s}Currentanchorsareagoodfittodataset")
else:
LOGGER.info(f"{s}Anchorsareapoorfittodataset,attemptingtoimprove...")
na=m.anchors.numel()//2#numberofanchors
try:
#如果BPR<0.98(最大為1?越大越好)?使用K-means?+?遺傳進(jìn)化算法選擇出與數(shù)據(jù)集更匹配的anchors框??[9,?2]
anchors=kmean_anchors(dataset,n=na,img_size=imgsz,thr=thr,gen=1000,verbose=False)
exceptExceptionase:
LOGGER.info(f"{PREFIX}ERROR:{e}")
#計(jì)算新的anchors的new_BPR
new_BPR=metric(anchors)[0]
#比較K-means+遺傳進(jìn)化算法進(jìn)化后的anchors的new_BPR和原始anchors的BPR
#注意:這里并不一定進(jìn)化后的BPR必大于原始anchors的BPR,因?yàn)閮烧叩暮饬繕?biāo)注是不一樣的進(jìn)化算法的衡量標(biāo)準(zhǔn)是適應(yīng)度而這里比的是BPR
ifnew_BPR>BPR:#replaceanchors
anchors=flow.tensor(anchors,device=m.anchors.device).type_as(m.anchors)
#替換m的anchor_grid[9,2]->[3,1,3,1,1,2]
m.anchors[:]=anchors.clone().view_as(m.anchors)
#檢查anchor順序和stride順序是否一致不一致就調(diào)整
#因?yàn)槲覀兊膍.anchors是相對(duì)各個(gè)featuremap所以必須要順序一致否則效果會(huì)很不好
check_anchor_order(m)#mustbeinpixel-space(notgrid-space)
m.anchors/=stride
s=f"{PREFIX}Done(optional:updatemodel*.yamltousetheseanchorsinthefuture)"
else:
s=f"{PREFIX}Done(originalanchorsbetterthannewanchors,proceedingwithoriginalanchors)"
LOGGER.info(s)

這個(gè)函數(shù)會(huì)在train.py中調(diào)用:

總結(jié)

K-means是非常經(jīng)典且有效的聚類方法,通過(guò)計(jì)算樣本之間的距離(相似程度)將較近的樣本聚為同一類別(簇)。


審核編輯 :李倩


聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點(diǎn)僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場(chǎng)。文章及其配圖僅供工程師學(xué)習(xí)之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問(wèn)題,請(qǐng)聯(lián)系本站處理。 舉報(bào)投訴
  • 代碼
    +關(guān)注

    關(guān)注

    30

    文章

    4940

    瀏覽量

    73074
  • 聚類算法
    +關(guān)注

    關(guān)注

    2

    文章

    118

    瀏覽量

    12492
  • K-means
    +關(guān)注

    關(guān)注

    0

    文章

    28

    瀏覽量

    11691

原文標(biāo)題:YOLOv5 中的 autoanchor.py 代碼解析

文章出處:【微信號(hào):GiantPandaCV,微信公眾號(hào):GiantPandaCV】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評(píng)論

    相關(guān)推薦
    熱點(diǎn)推薦

    基于迅為RK3588開發(fā)板實(shí)現(xiàn)高性能機(jī)器狗主控解決方案-?AI能力實(shí)戰(zhàn):YOLOv5目標(biāo)檢測(cè)例程

    基于迅為RK3588開發(fā)板實(shí)現(xiàn)高性能機(jī)器狗主控解決方案-?AI能力實(shí)戰(zhàn):YOLOv5目標(biāo)檢測(cè)例程
    的頭像 發(fā)表于 11-28 11:32 ?453次閱讀
    基于迅為RK3588開發(fā)板實(shí)現(xiàn)高性能機(jī)器狗主控解決方案-?AI能力實(shí)戰(zhàn):<b class='flag-5'>YOLOv5</b>目標(biāo)檢測(cè)例程

    迅為如何在RK3576上部署YOLOv5;基于RK3576構(gòu)建智能門禁系統(tǒng)

    迅為如何在RK3576開發(fā)板上部署YOLOv5;基于RK3576構(gòu)建智能門禁系統(tǒng)
    的頭像 發(fā)表于 11-25 14:06 ?674次閱讀
    迅為如何在RK3576上部署<b class='flag-5'>YOLOv5</b>;基于RK3576構(gòu)建智能門禁系統(tǒng)

    技術(shù)分享 | RK3588基于Yolov5的目標(biāo)識(shí)別演示

    YOLO是一種基于深度神經(jīng)網(wǎng)絡(luò)的目標(biāo)檢測(cè)算法,用在圖像或視頻實(shí)時(shí)識(shí)別和定位多個(gè)對(duì)象。在其各個(gè)版本的迭代,YOLOv5憑借易用性和性能平衡在工業(yè)、醫(yī)療、農(nóng)業(yè)、零售等領(lǐng)域被廣泛的應(yīng)用。本文以啟揚(yáng)
    的頭像 發(fā)表于 09-18 17:27 ?989次閱讀
    技術(shù)分享 | RK3588基于<b class='flag-5'>Yolov5</b>的目標(biāo)識(shí)別演示

    基于瑞芯微RK3576的 yolov5訓(xùn)練部署教程

    1.Yolov5簡(jiǎn)介 YOLOv5 模型是 Ultralytics 公司于 2020 年 6 月 9 日公開發(fā)布的。YOLOv5 模型是基于 YOLOv3 模型基礎(chǔ)上改進(jìn)而來(lái)的,有
    的頭像 發(fā)表于 09-11 16:43 ?2353次閱讀
    基于瑞芯微RK3576的 <b class='flag-5'>yolov5</b>訓(xùn)練部署教程

    在k230上使用yolov5檢測(cè)圖像卡死,怎么解決?

    0.99以上 模型轉(zhuǎn)換指令 再將該模型放到k230設(shè)備上使用yolo大作戰(zhàn)yolov5檢測(cè)示例,檢測(cè)就會(huì)卡死,打印出的檢測(cè)結(jié)果會(huì)超過(guò)1。 目前無(wú)從下手,大佬們求救!
    發(fā)表于 08-11 07:41

    yolov5訓(xùn)練部署全鏈路教程

    1.Yolov5簡(jiǎn)介YOLOv5模型是Ultralytics公司于2020年6月9日公開發(fā)布的。YOLOv5模型是基于YOLOv3模型基礎(chǔ)上改進(jìn)而來(lái)的,有
    的頭像 發(fā)表于 07-25 15:22 ?1306次閱讀
    <b class='flag-5'>yolov5</b>訓(xùn)練部署全鏈路教程

    使用yolov5轉(zhuǎn)為kmodel之后,運(yùn)行MicroPython報(bào)錯(cuò)誤:IndexError: index is out of bounds怎么解決?

    /YOLO%E5%A4%A7%E4%BD%9C%E6%88%98.html 將標(biāo)準(zhǔn)的yolov5s.pt模型轉(zhuǎn)為yolov5s.kmodel模型,然后使用以上鏈接的案例運(yùn)行如下代碼
    發(fā)表于 06-06 06:23

    在K230上部署yolov5時(shí) 出現(xiàn)the array is too big的原因?

    重現(xiàn)步驟 1將yolov5的kmodel放入k230的data數(shù)據(jù) 2使用yolo大作戰(zhàn)里的視頻流推理代碼 3運(yùn)行 期待結(jié)果和實(shí)際結(jié)果 期待的結(jié)果 將目標(biāo)檢測(cè)的框圈起來(lái) 實(shí)際看到的結(jié)果
    發(fā)表于 05-28 07:47

    RV1126 yolov8訓(xùn)練部署教程

    YOLOv8 是 ultralytics 公司在 2023 年 1月 10 號(hào)開源的基于YOLOV5進(jìn)行更新的 下一個(gè)重大更新版本,目前支持圖像分類、物體檢測(cè)和實(shí)例分割任務(wù),鑒于Yolov5的良好表現(xiàn),
    的頭像 發(fā)表于 04-16 14:53 ?1119次閱讀
    RV1126 <b class='flag-5'>yolov</b>8訓(xùn)練部署教程

    請(qǐng)問(wèn)如何在imx8mplus上部署和運(yùn)行YOLOv5訓(xùn)練的模型?

    我正在從事 imx8mplus yocto 項(xiàng)目。我已經(jīng)在自定義數(shù)據(jù)集上的 YOLOv5 上訓(xùn)練了對(duì)象檢測(cè)模型。它在 ubuntu 電腦上運(yùn)行良好。現(xiàn)在我想在我的 imx8mplus 板上運(yùn)行該模型
    發(fā)表于 03-25 07:23

    YOLOv5rgb888p_size這個(gè)參數(shù)要與模型推理和訓(xùn)練的尺寸一致嗎?一致會(huì)達(dá)到更好的效果?

    YOLOv5rgb888p_size這個(gè)參數(shù)要與模型推理和訓(xùn)練的尺寸一致嗎,一致會(huì)達(dá)到更好的效果
    發(fā)表于 03-11 08:12

    yolov5轉(zhuǎn)onnx在cubeAI進(jìn)行部署,部署失敗的原因?

    第一個(gè)我是轉(zhuǎn)onnx時(shí) 想把權(quán)重文件變小點(diǎn) 就用了半精度 --half,則說(shuō)17版本不支持半精度 后面則是沒(méi)有縮小的單精度 但是顯示哪里溢出了···· 也不說(shuō)是哪里、、。。。 到底能不能部署yolov5這種東西啊?? 也沒(méi)看見(jiàn)幾個(gè)部署在這上面......................
    發(fā)表于 03-07 11:38

    【米爾RK3576開發(fā)板評(píng)測(cè)】+項(xiàng)目名稱YOLOV5目標(biāo)檢測(cè)

    的Toolkit來(lái)進(jìn)行格式轉(zhuǎn)換。(PC電腦需要聯(lián)網(wǎng)) 三、模型轉(zhuǎn)換 cd Projects/rknn_model_zoo/examples/yolov5/python python convert.py
    發(fā)表于 02-15 13:24

    【ELF 2學(xué)習(xí)板試用】ELF2開發(fā)板(飛凌嵌入式)部署yolov5s的自定義模型

    = os.getcwd() /root/yolov5/data/voc_label.py abs_path = \'/root/yolov5/data/\' def convert(size, box
    發(fā)表于 02-04 18:15

    在RK3568教學(xué)實(shí)驗(yàn)箱上實(shí)現(xiàn)基于YOLOV5的算法物體識(shí)別案例詳解

    一、實(shí)驗(yàn)?zāi)康?本節(jié)視頻的目的是了解YOLOv5模型的用途及流程,并掌握基于YOLOV5算法實(shí)現(xiàn)物體識(shí)別的方法。 二、實(shí)驗(yàn)原理 YOLO(You Only Look Once!) YOLOv5 是一種
    發(fā)表于 12-03 14:56