Yolov3网络架构分析
Yolov3網(wǎng)絡(luò)架構(gòu)分析
上圖三個藍色方框內(nèi)表示Yolov3的三個基本組件:
? CBL:Yolov3網(wǎng)絡(luò)結(jié)構(gòu)中的最小組件,由Conv+Bn+Leaky_relu激活函數(shù)三者組成。
? Res unit:借鑒Resnet網(wǎng)絡(luò)中的殘差結(jié)構(gòu),讓網(wǎng)絡(luò)可以構(gòu)建的更深。
? ResX:由一個CBL和X個殘差組件構(gòu)成,是Yolov3中的大組件。每個Res模塊前面的CBL都起到下采樣的作用,因此經(jīng)過5次Res模塊后,得到的特征圖是608->304->152->76->38->19大小。
其他基礎(chǔ)操作:
? Concat:張量拼接,會擴充兩個張量的維度,例如2626256和2626512兩個張量拼接,結(jié)果是2626768。Concat和cfg文件中的route功能一樣。
? add:張量相加,張量直接相加,不會擴充維度,例如104104128和104104128相加,結(jié)果還是104104128。add和cfg文件中的shortcut功能一樣。
Backbone中卷積層的數(shù)量:
每個ResX中包含1+2X個卷積層,因此整個主干網(wǎng)絡(luò)Backbone中一共包含1+(1+21)+(1+22)+(1+28)+(1+28)+(1+24)=52,再加上一個FC全連接層,即可以組成一個Darknet53分類網(wǎng)絡(luò)。不過在目標檢測Yolov3中,去掉FC層,不過為了方便稱呼,仍然把Yolov3的主干網(wǎng)絡(luò)叫做Darknet53結(jié)構(gòu)。
? backbone:Darknet-53
在第1個卷積操作DarknetConv2D_BN_Leaky()中,是3個操作的組合,即
? 1個Darknet的2維卷積Conv2D層,即DarknetConv2D();
? 1個正則化(BN)層,即BatchNormalization();
? 1個LeakyReLU層,斜率是0.1,LeakyReLU是ReLU的變換;
backbone部分由Yolov2時期的Darknet-19進化至Darknet-53,加深了網(wǎng)絡(luò)層數(shù),引入了Resnet中的跨層加和操作。原文列舉了Darknet-53與其他網(wǎng)絡(luò)的對比:
圖三. Darknet精度性能對比
Darknet-53處理速度每秒78張圖,比Darknet-19慢不少,但是比同精度的ResNet快很多。Yolov3依然保持了高性能。
(這里解釋一下Top1和Top5:模型在ImageNet數(shù)據(jù)集上進行推理,按照置信度排序總共生成5個標簽。按照第一個標簽預(yù)測計算正確率,即為Top1正確率;前五個標簽中只要有一個是正確的標簽,則視為正確預(yù)測,稱為Top5正確率)
? Yolov3網(wǎng)絡(luò)結(jié)構(gòu)細節(jié)
DBL: 上圖左下角所示,也就是代碼中的Darknetconv2d_BN_Leaky,是yolo_v3的基本組件。就是卷積+BN+Leaky relu。對于v3來說,BN和leaky relu(正則化和激勵)已經(jīng)是和卷積層不可分離的部分了(最后一層卷積除外),共同構(gòu)成了最小組件。
resn:n代表數(shù)字,有res1,res2, … ,res8等等,表示這個res_block里含有多少個res_unit。這是yolo_v3的大組件,yolo_v3開始借鑒了ResNet的殘差結(jié)構(gòu),使用這種結(jié)構(gòu)可以讓網(wǎng)絡(luò)結(jié)構(gòu)更深(從v2的darknet-19上升到v3的darknet-53,前者沒有殘差結(jié)構(gòu))。對于res_block的解釋,可以在圖1的右下角直觀看到,其基本組件也是DBL。
concat:張量拼接。將darknet中間層和后面的某一層的上采樣進行拼接。拼接的操作和殘差層add的操作是不一樣的,拼接會擴充張量的維度,而add只是直接相加不會導致張量維度的改變。
網(wǎng)絡(luò)結(jié)構(gòu)解析:
- Yolov3中,只有卷積層,通過調(diào)節(jié)卷積步長控制輸出特征圖的尺寸。所以對于輸入圖片尺寸沒有特別限制。流程圖中,輸入圖片以256*256作為樣例。
- Yolov3借鑒了金字塔特征圖思想,小尺寸特征圖用于檢測大尺寸物體,而大尺寸特征圖檢測小尺寸物體。特征圖的輸出維度為
為輸出特征圖格點數(shù),一共3個Anchor框,每個框有4維預(yù)測框數(shù)值
,1維預(yù)測框置信度,80維物體類別數(shù)。所以第一層特征圖的輸出維度為
。 - Yolov3總共輸出3個特征圖,第一個特征圖下采樣32倍,第二個特征圖下采樣16倍,第三個下采樣8倍。輸入圖像經(jīng)過Darknet-53(無全連接層),再經(jīng)過Yoloblock生成的特征圖被當作兩用,第一用為經(jīng)過33卷積層、11卷積之后生成特征圖一,第二用為經(jīng)過1*1卷積層加上采樣層,與Darnet-53網(wǎng)絡(luò)的中間層輸出結(jié)果進行拼接,產(chǎn)生特征圖二。同樣的循環(huán)之后產(chǎn)生特征圖三。
- concat操作與加和操作的區(qū)別:加和操作來源于ResNet思想,將輸入的特征圖,與輸出特征圖對應(yīng)維度進行相加,即
;而concat操作源于DenseNet網(wǎng)絡(luò)的設(shè)計思路,將特征圖按照通道維度直接進行拼接,例如8816的特征圖與8816的特征圖拼接后生成8832的特征圖。 - 上采樣層(upsample):作用是將小尺寸特征圖通過插值等方法,生成大尺寸圖像。例如使用最近鄰插值算法,將88的圖像變換為1616。上采樣層不改變特征圖的通道數(shù)。
- 激活函數(shù)
LeakyReLU的激活函數(shù),如下
其中,Darknet的2維卷積DarknetConv2D,具體操作如下:
? 將核權(quán)重矩陣的正則化,使用L2正則化,參數(shù)是5e-4,即操作w參數(shù);
? Padding,一般使用same模式,只有當步長為(2,2)時,使用valid模式。避免在降采樣中,引入無用的邊界信息;
? 其余參數(shù)不變,都與二維卷積操作Conv2D()一致;
kernel_regularizer是將核權(quán)重參數(shù)w進行正則化,而BatchNormalization是將輸入數(shù)據(jù)x進行正則化。
Leaky_Relu(yolov3)與mish(yolov4),如下
- 殘差流程
在darknet_body()中,執(zhí)行5組resblock_body()殘差塊,重復(fù)[1, 2, 8, 8, 4]次,雙卷積(1x1和3x3)操作,每組均含有一次步長為2的卷積操作,因而一共降維5次32倍,即32=2^5,則輸出的特征圖維度是13,即13=416/32。最后1層的通道(filter)數(shù)是1024,因此,最終的輸出結(jié)構(gòu)是(?, 13, 13, 1024)。
8. 特征圖
特征圖
在YOLO v3網(wǎng)絡(luò)中,輸出3個不同尺度的檢測圖,用于檢測不同大小的物體。調(diào)用3次make_last_layers(),產(chǎn)生3個檢測圖,即y1、y2和y3。
13x13檢測圖
第1個部分,輸出維度是13x13。在make_last_layers()方法中,輸入?yún)?shù)如下:
? darknet.output:DarkNet網(wǎng)絡(luò)的輸出,即(?, 13, 13, 1024);
? num_filters:通道個數(shù)512,用于生成中間值x,x會傳導至第2個檢測圖;
? out_filters:第1個輸出y1的通道數(shù),值是錨框數(shù)*(類別數(shù)+4個框值+框置信度);
在make_last_layers()方法中,執(zhí)行2步操作:
? 第1步,x執(zhí)行多組1x1的卷積操作和3x3的卷積操作,filter先擴大再恢復(fù),最后與輸入的filter保持不變,仍為512,則x由(?,13, 13, 1024)轉(zhuǎn)變?yōu)??, 13, 13, 512);
? 第2步,x先執(zhí)行3x3的卷積操作,再執(zhí)行不含BN和Leaky的1x1的卷積操作,作用類似于全連接操作,生成預(yù)測矩陣y;
26x26檢測圖
第2個部分,輸出維度是26x26,包含以下步驟:
? 通過DarknetConv2D_BN_Leaky卷積,將x由512的通道數(shù),轉(zhuǎn)換為256的通道數(shù);
? 通過2倍上采樣UpSampling2D,將x由13x13的結(jié)構(gòu),轉(zhuǎn)換為26x26的結(jié)構(gòu);
? 將x與DarkNet的第152層拼接Concatenate,作為第2個尺度特征圖;
52x52檢測圖
第3部分的輸出結(jié)構(gòu),52x52,與第2部分類似,如下:
邏輯如下:
? x經(jīng)過128個filter的卷積,再執(zhí)行上采樣,輸出為(?, 52, 52, 128);
? darknet.layers[92].output,與152層類似,結(jié)構(gòu)是(?, 52, 52, 256);
? 兩者拼接之后是(?, 52, 52, 384);
? 最后輸入至make_last_layers,生成y3是(?, 52, 52, 18),忽略x的輸出;
? 最后,則是模型的重組,輸入inputs依然保持不變,即(?, 416, 416, 3),而輸出轉(zhuǎn)換為3個尺度的預(yù)測層,即[y1, y2,
y3]。
參考鏈接:
https://blog.csdn.net/loco1223/article/details/92078816
https://zhuanlan.zhihu.com/p/76802514
https://blog.csdn.net/weixin_47196664/article/details/106536656
總結(jié)
以上是生活随笔為你收集整理的Yolov3网络架构分析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。