源代碼網(wǎng)站githat(源代碼網(wǎng)頁)
向AI轉(zhuǎn)型的程序員都關(guān)注了這個號??????
本篇我們會介紹 yolo.py,這是YOLO的特定模塊,和網(wǎng)絡(luò)構(gòu)建有關(guān)。在 YOLOv5源碼中,模型的建立是依靠 yolo.py 中的函數(shù)和對象完成的,這個文件主要由三個部分:parse_model函數(shù)、Detect類和Model類組成。
yolo.py文件位置在./models/yolo.py
文章代碼逐行手打注釋,每個模塊都有對應(yīng)講解,一文幫你梳理整個代碼邏輯!
一、 導(dǎo)包和基本配置 1.1 導(dǎo)入安裝好的python庫
首先,導(dǎo)入一下常用的python庫:
argparse: 它是一個用于命令項選項與參數(shù)解析的模塊,通過在程序中定義好我們需要的參數(shù),argparse 將會從 sys.argv 中解析出這些參數(shù),并自動生成幫助和使用信息
sys:它是與python解釋器交互的一個接口,該模塊提供對解釋器使用或維護(hù)的一些變量的訪問和獲取,它提供了許多函數(shù)和變量來處理 Python 運(yùn)行時環(huán)境的不同部分
展開全文
copy: Python 中賦值語句不復(fù)制對象,而是在目標(biāo)和對象之間創(chuàng)建綁定關(guān)系。copy模塊提供了通用的淺層復(fù)制和深層復(fù)制操作
pathlib: 這個庫提供了一種面向?qū)ο蟮姆绞絹砼c文件系統(tǒng)交互,可以讓代碼更簡潔、更易讀
1.2 獲取當(dāng)前文件的絕對路徑
這段代碼會獲取 當(dāng)前文件的絕對路徑,并使用Path庫將其轉(zhuǎn)換為Path對象。
這一部分的主要作用有兩個:
將當(dāng)前項目添加到系統(tǒng)路徑上,以使得項目中的模塊可以調(diào)用。
將當(dāng)前項目的相對路徑保存在ROOT中,便于尋找項目中的文件。
這些都是用戶自定義的庫,由于上一步已經(jīng)把路徑加載上了,所以現(xiàn)在可以導(dǎo)入,這個順序不可以調(diào)換。具體來說,代碼從如下幾個文件中導(dǎo)入了部分函數(shù)和類:
models.common: 這個是yolov5的網(wǎng)絡(luò)結(jié)構(gòu)
models.experimental: 實驗性質(zhì)的代碼,包括MixConv2d、跨層權(quán)重Sum等
utils.autoanchor: 定義了自動生成錨框的方法
utils.general: 定義了一些常用的工具函數(shù),比如檢查文件是否存在、檢查圖像大小是否符合要求、打印命令行參數(shù)等等
utils.plots: 定義了Annotator類,可以在圖像上繪制矩形框和標(biāo)注信息
utils.torch_utils: 定義了一些與PyTorch有關(guān)的工具函數(shù),比如選擇設(shè)備、同步時間等
通過導(dǎo)入這些模塊,可以更方便地進(jìn)行目標(biāo)檢測的相關(guān)任務(wù),并且減少了代碼的復(fù)雜度和冗余。
二、parse_model函數(shù)
parse_model函數(shù)用在DetectionModel模塊中,主要作用是解析模型yaml的模塊,通過讀取yaml文件中的配置,并且到common.py中找到相對于的模塊,然后組成一個完整的模型解析模型文件(字典形式),并搭建網(wǎng)絡(luò)結(jié)構(gòu)。簡單來說,就是把yaml文件中的網(wǎng)絡(luò)結(jié)構(gòu)實例化成對應(yīng)的模型。后續(xù)如果需要動模型框架的話,需要對這個函數(shù)做相應(yīng)的改動。
2.1 獲取對應(yīng)參數(shù)
這段代碼主要是獲取配置dict里面的參數(shù),并打印最開始展示的網(wǎng)絡(luò)結(jié)構(gòu)表的表頭。
我們先解釋幾個參數(shù),d和ch,na和no:
d: yaml 配置文件(字典形式),yolov5s.yaml中的6個元素 + ch
ch: 記錄模型每一層的輸出channel,初始ch=[3],后面會刪除
na: 判斷anchor的數(shù)量
no: 根據(jù)anchor數(shù)量推斷的輸出維度
這里有一行代碼我們上篇YOLOv5源碼逐行超詳細(xì)注釋與解讀(5)——配置文件yolov5s.yaml就見過了:
這里就是讀取了 yaml 文件的相關(guān)參數(shù)(參數(shù)含義忘了的話再看看上篇哦)
2.2 搭建網(wǎng)絡(luò)前準(zhǔn)備
這段代碼主要是遍歷backbone和head的每一層,獲取搭建網(wǎng)絡(luò)前的一系列信息。
我們還是先解釋參數(shù),layers、save和c2:
layers: 保存每一層的層結(jié)構(gòu)
save: 記錄下所有層結(jié)構(gòu)中from不是-1的層結(jié)構(gòu)序號
c2: 保存當(dāng)前層的輸出channel
然后開始迭代循環(huán)backbone與head的配置。for i, (f, n, m, args) in enumerate(d['backbone'] + d['head']):中有幾個參數(shù)
f:from,當(dāng)前層輸入來自哪些層
n:number,當(dāng)前層次數(shù) 初定
m:module,當(dāng)前層類別
args:當(dāng)前層類參數(shù) 初定
接著還用到一個函數(shù)eval,主要作用是將字符串當(dāng)成有效的表達(dá)式來求值,并且返回執(zhí)行的結(jié)果。在這里簡單來說,就是實現(xiàn)list、dict、tuple與str之間的轉(zhuǎn)化。
2.3 更新當(dāng)前層的參數(shù),計算c2
這段代碼主要是更新當(dāng)前層的args,計算c2(當(dāng)前層的輸出channel)
首先網(wǎng)絡(luò)將C3中的BottleNeck數(shù)量乘以模型縮放倍數(shù)n*gd控制模塊的深度縮放,舉個栗子,對于yolo5s來講,gd為0.33,那么就是n*0.33,也就是把默認(rèn)的深度縮放為原來的1/3。
然后將m實例化成同名模塊,別看列舉了那么多模塊,目前只用到Conv,SPP,F(xiàn)ocus,C3,nn.Upsample。對于以上的這幾種類型的模塊,ch是一個用來保存之前所有的模塊輸出的channle,ch[-1]代表著上一個模塊的輸出通道。args[0]是默認(rèn)的輸出通道。
這樣以來,c1=ch[f]就代表輸入通道c1為f指向的層的輸出通道,c2=args[0]就代表輸出通道c2為yaml的args中的第一個變量。注意,如果輸出通道不等于255即Detect層的輸出通道, 則將通道數(shù)乘上width_multiple,并調(diào)整為8的倍數(shù)。通過函數(shù)make_divisible來實現(xiàn)
make_divisible代碼如下:
2.4 使用當(dāng)前層的參數(shù)搭建當(dāng)前層
這段代碼主要是使用當(dāng)前層的參數(shù)搭建當(dāng)前層。
經(jīng)過以上處理,args里面保存的前兩個參數(shù)就是module的輸入通道數(shù)、輸出通道數(shù)。只有BottleneckCSP和C3這兩種module會根據(jù)深度參數(shù)n調(diào)整該模塊的重復(fù)迭加次數(shù)
然后進(jìn)行的是其他幾種類型的Module判斷:
如果是BN層,只需要返回上一層的輸出channel,通道數(shù)保持不變。
如果是Concat層,則將f中所有的輸出累加得到這層的輸出channel,f是所有需要拼接層的index,輸出通道c2是所有層的和。
如果是Detect層,則對應(yīng)檢測頭部分,這塊下一小節(jié)細(xì)講。
Contract和Expand目前未在模型中使用。
2.5 打印和保存layers
這段代碼主要是打印當(dāng)前層結(jié)構(gòu)的一些基本信息并保存。
把構(gòu)建的模塊保存到layers里,把該層的輸出通道數(shù)寫入ch列表里。待全部循環(huán)結(jié)束后再構(gòu)建成模型。
返回值:
return nn.Sequential(*layers): 網(wǎng)絡(luò)的每一層的層結(jié)構(gòu)
return sorted(save): 把所有層結(jié)構(gòu)中from不是-1的值記下 并排序 [4, 6, 10, 14, 17, 20, 23]
至此模型就全部構(gòu)建完畢了。
下面詳細(xì)介紹一下各個模塊。
?? 三、Detect模塊
Detect 模塊是 YOLO 網(wǎng)絡(luò)模型的最后一層 (對應(yīng) yaml 文件最后一行),通過 yaml 文件進(jìn)行聲明,格式為:
3.1 獲取預(yù)測得到的參數(shù)
這段代碼主要是獲取預(yù)測得到的各種信息。
detection layer 相當(dāng)于yolov3中的YOLOLayer層,我們解釋一下包含的參數(shù):
nc: 分類數(shù)量
no: 每個anchor的輸出數(shù),為(x,y,w,h,conf) + nc = 5 + nc 的總數(shù)
nl: 預(yù)測層數(shù),此次為3
na: anchors的數(shù)量,此次為3
grid: 格子坐標(biāo)系,左上角為(1,1),右下角為(input.w/stride,input.h/stride)
3.2 向前傳播
這段代碼主要是對三個feature map分別進(jìn)行處理:(n, 255, 80, 80),(n, 255, 40, 40),(n, 255, 20, 20)
首先進(jìn)行for循環(huán),每次i的循環(huán),產(chǎn)生一個z。維度重排列:(n, 255, _, _) - (n, 3, nc+5, ny, nx) - (n, 3, ny, nx, nc+5),三層分別預(yù)測了80*80、40*40、20*20次。
接著 構(gòu)造網(wǎng)格,因為推理返回的不是歸一化后的網(wǎng)格偏移量,需要再加上網(wǎng)格的位置,得到最終的推理坐標(biāo),再送入nms。所以這里構(gòu)建網(wǎng)格就是為了紀(jì)律每個grid的網(wǎng)格坐標(biāo) 方面后面使
最后按損失函數(shù)的回歸方式來轉(zhuǎn)換坐標(biāo),利用sigmoid激活函數(shù)計算定位參數(shù),cat(dim=-1)為直接拼接。注意:訓(xùn)練階段直接返回x ,而預(yù)測階段返回3個特征圖拼接的結(jié)果
3.3 相對坐標(biāo)轉(zhuǎn)換到grid絕對坐標(biāo)系
這段代碼主要是將相對坐標(biāo)轉(zhuǎn)換到grid絕對坐標(biāo)系。
首先構(gòu)造網(wǎng)格標(biāo)尺坐標(biāo)
indexing='ij' : 表示的是i是同一行,j表示同一列
indexing='xy' : 表示的是x是同一列,y表示同一行
grid復(fù)制成3倍,因為是3個框。anchor_grid是每個anchor寬高。anchor_grid = (self.anchors[i].clone * self.stride[i])。注意這里為啥要乘呢?因為在外面已經(jīng)把a(bǔ)nchors給除了對應(yīng)的下采樣率,這里再乘回來。
原文地址
機(jī)器學(xué)習(xí)算法AI大數(shù)據(jù)技術(shù)
搜索公眾號添加: datanlp
閱讀過本文的人還看了以下文章:
TensorFlow 2.0深度學(xué)習(xí)案例實戰(zhàn)
基于40萬表格數(shù)據(jù)集TableBank,用MaskRCNN做表格檢測
《基于深度學(xué)習(xí)的自然語言處理》中/英PDF
Deep Learning 中文版初版-周志華團(tuán)隊
【全套視頻課】最全的目標(biāo)檢測算法系列講解,通俗易懂!
《美團(tuán)機(jī)器學(xué)習(xí)實踐》_美團(tuán)算法團(tuán)隊.pdf
《深度學(xué)習(xí)入門:基于Python的理論與實現(xiàn)》高清中文PDF+源碼
《深度學(xué)習(xí):基于Keras的Python實踐》PDF和代碼
特征提取與圖像處理(第二版).pdf
python就業(yè)班學(xué)習(xí)視頻,從入門到實戰(zhàn)項目
2019最新《PyTorch自然語言處理》英、中文版PDF+源碼
《21個項目玩轉(zhuǎn)深度學(xué)習(xí):基于TensorFlow的實踐詳解》完整版PDF+附書代碼
《深度學(xué)習(xí)之pytorch》pdf+附書源碼
PyTorch深度學(xué)習(xí)快速實戰(zhàn)入門《pytorch-handbook》
【下載】豆瓣評分8.1,《機(jī)器學(xué)習(xí)實戰(zhàn):基于Scikit-Learn和TensorFlow》
《Python數(shù)據(jù)分析與挖掘?qū)崙?zhàn)》PDF+完整源碼
汽車行業(yè)完整知識圖譜項目實戰(zhàn)視頻(全23課)
李沐大神開源《動手學(xué)深度學(xué)習(xí)》,加州伯克利深度學(xué)習(xí)(2019春)教材
筆記、代碼清晰易懂!李航《統(tǒng)計學(xué)習(xí)方法》最新資源全套!
《神經(jīng)網(wǎng)絡(luò)與深度學(xué)習(xí)》最新2018版中英PDF+源碼
將機(jī)器學(xué)習(xí)模型部署為REST API
yolo3 檢測出圖像中的不規(guī)則漢字
同樣是機(jī)器學(xué)習(xí)算法工程師,你的面試為什么過不了?
前海征信大數(shù)據(jù)算法:風(fēng)險概率預(yù)測
【Keras】完整實現(xiàn)‘交通標(biāo)志’分類、‘票據(jù)’分類兩個項目,讓你掌握深度學(xué)習(xí)圖像分類
特征工程(一)
特征工程(二) :文本數(shù)據(jù)的展開、過濾和分塊
特征工程(三):特征縮放,從詞袋到 TF-IDF
特征工程(四): 類別特征
特征工程(五): PCA 降維
特征工程(六): 非線性特征提取和模型堆疊
特征工程(七):圖像特征提取和深度學(xué)習(xí)
如何利用全新的決策樹集成級聯(lián)結(jié)構(gòu)gcForest做特征工程并打分?
Machine Learning Yearning 中文翻譯稿
螞蟻金服2018秋招-算法工程師(共四面)通過
全球AI挑戰(zhàn)-場景分類的比賽源碼(多模型融合)
斯坦福CS230官方指南:CNN、RNN及使用技巧速查(打印收藏)
中科院Kaggle全球文本匹配競賽華人第1名團(tuán)隊-深度學(xué)習(xí)與特征工程
不斷更新資源
深度學(xué)習(xí)、機(jī)器學(xué)習(xí)、數(shù)據(jù)分析、python
搜索公眾號添加: datayx
掃描二維碼推送至手機(jī)訪問。
版權(quán)聲明:本文由飛速云SEO網(wǎng)絡(luò)優(yōu)化推廣發(fā)布,如需轉(zhuǎn)載請注明出處。