前言
前面已經(jīng)講過了Yolov5模型目標檢測和分類模型訓練流程,這一篇講解一下yolov5模型結構,數(shù)據(jù)增強,以及訓練策略。
官方地址:https://github.com/ultralytics/yolov5
yolov5模型訓練流程:https://blog.csdn.net/qq_45066628/article/details/129470290?spm=1001.2014.3001.5501
Yolov5 (v6.2) 使用自己的數(shù)據(jù)訓練分類模型 基于ONNX TensorRT轉換:https://blog.csdn.net/qq_45066628/article/details/129594154?spm=1001.2014.3001.5501
網(wǎng)絡結構
Yolov5發(fā)布的預訓練模型,包含yolov5l.pt、yolov5l6.pt、yolov5m.pt、yolov5m6.pt、yolov5s.pt、yolov5s6.pt、yolov5x.pt、yolov5x6.pt等。針對不同大小的網(wǎng)絡整體架構(n, s, m, l, x)都是一樣的,只不過會在每個子模塊中采用不同的深度和寬度,分別應對yaml文件中的depth_multiple和width_multiple參數(shù)。下面以yolov5l.yaml繪制的網(wǎng)絡整體結構為例。
網(wǎng)絡結構圖
網(wǎng)絡結構主要由以下幾部分組成:
(1)輸入端:Mosaic數(shù)據(jù)增強、自適應錨框計算、自適應圖片縮放
(2) Backbone: New CSP-Darknet53
(3)Neck: SPPF, New CSP-PAN
(4)輸出端:Head
官方網(wǎng)絡結構圖:
source:https://user-images.githubusercontent.com/31005897/157381276-6e8429f3-c759-4aef-aea8-034438919457.png
v5.x網(wǎng)絡結構:
v6.x網(wǎng)絡結構:
source:https://blog.csdn.net/weixin_43799388/article/details/123271962
可以看出,相比于之前v5.x,最新版的v6.x網(wǎng)絡結構更加精簡(以提高速度和推理性能),主要有以下更新:
- Conv(k=6, s=2, p=2) 替換Focus,便于導出其他框架(for improved exportability)
- SPPF代替SPP,并且將SPPF放在主干最后一層(for reduced ops)
- 主干中的C3層重復次數(shù)從9次減小到6次(for reduced ops)
- 主干中最后一個C3層引入shortcut
yolov5s.yaml文件內(nèi)容
nc: 80 # number of classes 數(shù)據(jù)集中的類別數(shù)
depth_multiple: 0.33 # model depth multiple 模型層數(shù)因子(用來調整網(wǎng)絡的深度)
width_multiple: 0.50 # layer channel multiple 模型通道數(shù)因子(用來調整網(wǎng)絡的寬度)
# 如何理解這個depth_multiple和width_multiple呢?它決定的是整個模型中的深度(層數(shù))和寬度(通道數(shù)。
anchors: # 表示作用于當前特征圖的Anchor大小為 xxx
# 9個anchor,其中P表示特征圖的層級,P3/8該層特征圖縮放為1/8,是第3層特征
- [10,13, 16,30, 33,23] # P3/8, 表示[10,13],[16,30], [33,23]3個anchor
- [30,61, 62,45, 59,119] # P4/16
- [116,90, 156,198, 373,326] # P5/32
# YOLOv5s v6.0 backbone
backbone:
# [from, number, module, args]
[[-1, 1, Conv, [64, 6, 2, 2]], # 0-P1/2
[-1, 1, Conv, [128, 3, 2]], # 1-P2/4
[-1, 3, C3, [128]],
[-1, 1, Conv, [256, 3, 2]], # 3-P3/8
[-1, 6, C3, [256]],
[-1, 1, Conv, [512, 3, 2]], # 5-P4/16
[-1, 9, C3, [512]],
[-1, 1, Conv, [1024, 3, 2]], # 7-P5/32
[-1, 3, C3, [1024]],
[-1, 1, SPPF, [1024, 5]], # 9
]
# YOLOv5s v6.0 head
head:
[[-1, 1, Conv, [512, 1, 1]],
[-1, 1, nn.Upsample, [None, 2, 'nearest']],
[[-1, 6], 1, Concat, [1]], # cat backbone P4
[-1, 3, C3, [512, False]], # 13
[-1, 1, Conv, [256, 1, 1]],
[-1, 1, nn.Upsample, [None, 2, 'nearest']],
[[-1, 4], 1, Concat, [1]], # cat backbone P3
[-1, 3, C3, [256, False]], # 17 (P3/8-small)
[-1, 1, Conv, [256, 3, 2]],
[[-1, 14], 1, Concat, [1]], # cat head P4
[-1, 3, C3, [512, False]], # 20 (P4/16-medium)
[-1, 1, Conv, [512, 3, 2]],
[[-1, 10], 1, Concat, [1]], # cat head P5
[-1, 3, C3, [1024, False]], # 23 (P5/32-large)
[[17, 20, 23], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5)
]
nc是類別數(shù);
depth_multiple表示channel的縮放系數(shù),就是將配置里面的backbone和head部分有關通道的設置,全部乘以該系數(shù)即可;
而width_multiple表示BottleneckCSP模塊的層縮放系數(shù),將所有的BottleneckCSP模塊的number系數(shù)乘上該參數(shù)就可以最終的層個數(shù);如果希望大一點,就把這個數(shù)字改大一點,網(wǎng)絡就會按比例變深、變寬;如果希望小一點,就把這個數(shù)字改小一點,網(wǎng)絡就會按比例變淺、變窄。
anchors 解讀
yolov5 初始化了 9 個 anchors,分別在三個特征圖 (feature map)中使用,每個 feature map 的每個 grid cell 都有三個 anchor 進行預測。 分配規(guī)則:
- 尺度越大的 feature map 越靠前,相對原圖的下采樣率越小,感受野越小, 所以相對可以預測一些尺度比較小的物體(小目標),分配到的 anchors 越小。
- 尺度越小的 feature map 越靠后,相對原圖的下采樣率越大,感受野越大, 所以可以預測一些尺度比較大的物體(大目標),所以分配到的 anchors 越大。
- 即在小特征圖(feature map)上檢測大目標,中等大小的特征圖上檢測中等目標, 在大特征圖上檢測小目標。
backbone & head解讀
[from, number, module, args] 參數(shù)
四個參數(shù)的意義分別是:
- 第一個參數(shù) from :從哪一層獲得輸入,-1表示從上一層獲得,[-1, 6]表示從上層和第6層兩層獲得。
- 第二個參數(shù) number:表示有幾個相同的模塊,如果為9則表示有9個相同的模塊。
- 第三個參數(shù) module:模塊的名稱,這些模塊寫在common.py中。
- 第四個參數(shù) args:類的初始化參數(shù),用于解析作為 moudle 的傳入?yún)?shù),即[ch_out, kernel, stride, padding, groups][輸出通道數(shù)量,卷積核尺寸,步長,padding],這里連ch_in都省去了,因為輸入都是上層的輸出(初始ch_in為3)
Backbone骨干網(wǎng)絡
骨干網(wǎng)絡是指用來提取圖像特征的網(wǎng)絡,它的主要作用是將原始的輸入圖像轉化為多層特征圖,以便后續(xù)的目標檢測任務使用。在Yolov5中,使用的是CSPDarknet53或ResNet骨干網(wǎng)絡。Backbone中的主要結構有Conv模塊、C3模塊、SPPF模塊。
Conv
Conv模塊是卷積神經(jīng)網(wǎng)絡中常用的一種基礎模塊,它主要由卷積層、BN層和激活函數(shù)組成。下面對這些組成部分進行詳細解析。
- 卷積層是卷積神經(jīng)網(wǎng)絡中最基礎的層之一,用于提取輸入特征中的局部空間信息。
- BN層是在卷積層之后加入的一種歸一化層,用于規(guī)范化神經(jīng)網(wǎng)絡中的特征值分布。
- 激活函數(shù)是一種非線性函數(shù),用于給神經(jīng)網(wǎng)絡引入非線性變換能力。常用的激活函數(shù)包括sigmoid、ReLU、LeakyReLU、ELU等。
C3模塊
C3模塊是YOLOv5網(wǎng)絡中的一個重要組成部分,其主要作用是增加網(wǎng)絡的深度和感受野,提高特征提取的能力。
C3模塊是由三個Conv塊構成的,其中第一個Conv塊的步幅為2,可以將特征圖的尺寸減半,第二個Conv塊和第三個Conv塊的步幅為1。C3模塊中的Conv塊采用的都是3x3的卷積核。在每個Conv塊之間,還加入了BN層和LeakyReLU激活函數(shù),以提高模型的穩(wěn)定性和泛化性能。
Neck特征金字塔
在Neck部分的變化還是相對較大的,首先是將SPP換成成了SPPF,其次是New CSP-PAN了,在YOLOv4中,Neck的PAN結構是沒有引入CSP結構的,但在YOLOv5中作者在PAN結構中加入了CSP。
SPPF模塊
SPP
SPP模塊是何凱明大神在2015年的論文《Spatial Pyramid Pooling in Deep Convolutional Networks for Visual Recognition》中被提出。
SPP全程為空間金字塔池化結構,主要是為了解決兩個問題:
- 有效避免了對圖像區(qū)域裁剪、縮放操作導致的圖像失真等問題;
- 解決了卷積神經(jīng)網(wǎng)絡對圖相關重復特征提取的問題,大大提高了產(chǎn)生候選框的速度,且節(jié)省了計算成本。
class SPP(nn.Module):
# Spatial Pyramid Pooling (SPP) layer https://arxiv.org/abs/1406.4729
def __init__(self, c1, c2, k=(5, 9, 13)):
super().__init__()
c_ = c1 // 2 # hidden channels
self.cv1 = Conv(c1, c_, 1, 1)
self.cv2 = Conv(c_ * (len(k) + 1), c2, 1, 1)
self.m = nn.ModuleList([nn.MaxPool2d(kernel_size=x, stride=1, padding=x // 2) for x in k])
def forward(self, x):
x = self.cv1(x)
with warnings.catch_warnings():
warnings.simplefilter('ignore') # suppress torch 1.9.0 max_pool2d() warning
return self.cv2(torch.cat([x] + [m(x) for m in self.m], 1))
SPPF
這個是YOLOv5作者Glenn Jocher基于SPP提出的,速度較SPP快很多,所以叫SPP-Fast.
class SPPF(nn.Module):
# Spatial Pyramid Pooling - Fast (SPPF) layer for YOLOv5 by Glenn Jocher
def __init__(self, c1, c2, k=5): # equivalent to SPP(k=(5, 9, 13))
super().__init__()
c_ = c1 // 2 # hidden channels
self.cv1 = Conv(c1, c_, 1, 1)
self.cv2 = Conv(c_ * 4, c2, 1, 1)
self.m = nn.MaxPool2d(kernel_size=k, stride=1, padding=k // 2)
def forward(self, x):
x = self.cv1(x)
with warnings.catch_warnings():
warnings.simplefilter('ignore') # suppress torch 1.9.0 max_pool2d() warning
y1 = self.m(x)
y2 = self.m(y1)
return self.cv2(torch.cat((x, y1, y2, self.m(y2)), 1))
CSP-PAN
在Neck部分另外一個不同點就是New CSP-PAN了,在YOLOv4中,Neck的PAN結構是沒有引入CSP結構的,但在YOLOv5中作者在PAN結構中加入了CSP。
CSP
YOLOv5s的CSP結構是將原輸入分成兩個分支,分別進行卷積操作使得通道數(shù)減半,然后一個分支進行Bottleneck * N操作,然后concat兩個分支,使得BottlenneckCSP的輸入與輸出是一樣的大小,這樣是為了讓模型學習到更多的特征。
YOLOv5中的CSP有兩種設計,分別為CSP1_X結構和CSP2_X結構。
PAN
Yolov5 的 Neck 部分采用了 PANet 結構,Neck 主要用于生成特征金字塔。特征金字塔會增強模型對于不同縮放尺度對象的檢測,從而能夠識別不同大小和尺度的同一個物體。
PANet 結構是在FPN的基礎上引入了 Bottom-up path augmentation 結構。
PANet[1]最大的貢獻是提出了一個自頂向下和自底向上的雙向融合骨干網(wǎng)絡,同時在最底層和最高層之間添加了一條“short-cut”,用于縮短層之間的路徑。PANet還提出了自適應特征池化(Adaptive Features Pooling)和全連接融合(Fully-connected Fusion)兩個模塊。其中自適應特征池化可以用于聚合不同層之間的特征,保證特征的完整性和多樣性,而通過全連接融合可以得到更加準確的預測mask。
Head目標檢測頭
目標檢測頭是用來對特征金字塔進行目標檢測的部分,它包括了一些卷積層、池化層和全連接層等。
head中的主體部分就是三個Detect檢測器,即利用基于網(wǎng)格的anchor在不同尺度的特征圖上進行目標檢測的過程。
head:
[[-1, 1, Conv, [512, 1, 1]],
[-1, 1, nn.Upsample, [None, 2, 'nearest']],
[[-1, 6], 1, Concat, [1]], # cat backbone P4
[-1, 3, C3, [512, False]], # 13
?
[-1, 1, Conv, [256, 1, 1]],
[-1, 1, nn.Upsample, [None, 2, 'nearest']],
[[-1, 4], 1, Concat, [1]], # cat backbone P3
[-1, 3, C3, [256, False]], # 17 (P3/8-small)
?
[-1, 1, Conv, [256, 3, 2]],
[[-1, 14], 1, Concat, [1]], # cat head P4
[-1, 3, C3, [512, False]], # 20 (P4/16-medium)
?
[-1, 1, Conv, [512, 3, 2]],
[[-1, 10], 1, Concat, [1]], # cat head P5
[-1, 3, C3, [1024, False]], # 23 (P5/32-large)
?
[[17, 20, 23], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5)
]
數(shù)據(jù)增強
1.Mosaic數(shù)據(jù)增強
將四張圖片拼成一張圖片,采用隨機縮放、隨機裁剪、隨機排布的方式進行拼接。
優(yōu)點:
- 豐富數(shù)據(jù)集
- 減少GPU
2.Copy paste數(shù)據(jù)增強
將部分目標隨機的粘貼到圖片中,前提是數(shù)據(jù)要有segments數(shù)據(jù)才行,即每個目標的實例分割信息。
3. Random affine仿射變換
yolov5的仿射變換包含隨機旋轉、平移、縮放、錯切操作,和yolov3-spp一樣,代碼都沒有改變。據(jù)配置文件里的超參數(shù)發(fā)現(xiàn)只使用了Scale和Translation即縮放和平移。
4. MixUp數(shù)據(jù)增強
就是將兩張圖片按照一定的透明度融合在一起。
5. HSV(Augment HSV(Hue, Saturation, Value))隨機增強圖像
隨機調整色度,飽和度以及明度。
6.Random horizontal flip隨機水平翻轉
隨機上下左右的水平翻轉
7. Cutout數(shù)據(jù)增強
Cutout是一種新的正則化方法。訓練時隨機把圖片的一部分減掉,這樣能提高模型的魯棒性。它的來源是計算機視覺任務中經(jīng)常遇到的物體遮擋問題。通過cutout生成一些類似被遮擋的物體,不僅可以讓模型在遇到遮擋問題時表現(xiàn)更好,還能讓模型在做決定時更多地考慮環(huán)境。
Cutout數(shù)據(jù)增強在之前也見過很多次了。在yolov5的代碼中默認也是不啟用的。
8. Albumentations數(shù)據(jù)增強工具包
該工具最大的好處是會根據(jù)你使用的數(shù)據(jù)增強方法自動修改標注框信息!
albumentations 是一個給予 OpenCV的快速訓練數(shù)據(jù)增強庫,擁有非常簡單且強大的可以用于多種任務(分割、檢測)的接口,易于定制且添加其他框架非常方便。
它可以對數(shù)據(jù)集進行逐像素的轉換,如模糊、下采樣、高斯造點、高斯模糊、動態(tài)模糊、RGB轉換、隨機霧化等;也可以進行空間轉換(同時也會對目標進行轉換),如裁剪、翻轉、隨機裁剪等。
github地址:https://github.com/albumentations-team/albumentations
docs使用文檔:https://albumentations.ai/docs
YOLOV5的訓練技巧
1.訓練預熱 Warmup
剛開始訓練時,模型的權重是隨機初始化的,此時若選擇一個較大的學習率,可能帶來模型的不穩(wěn)定(振蕩)。選擇Warmup預熱學習率的方式可以使得開始訓練的幾個epoches或者一些steps內(nèi)學習率較小,在預熱的小學習率下,模型可以慢慢趨于穩(wěn)定,等模型相對穩(wěn)定后再選擇預先設置的學習率進行訓練,使得模型收斂速度變得更快,模型效果更佳。
常見Warmup類型
- Constant Warmup
在前面100epoch里,學習率線性增加,大于100epoch以后保持不變 - Constant Warmup
在前面100epoch里,學習率線性增加,大于100epoch以后保持不變 - Constant Warmup
在前面100epoch里,學習率線性增加,大于100epoch以后保持不變
超參數(shù)設置
在yolov5中data/hyps/hyp.scratch-*.yaml三個文件中,都存在著warmup_epoch代表訓練預熱輪次
2. 自動調整錨定框——Autoanchor
預定義邊框就是一組預設的邊框,在訓練時,以真實的邊框位置相對于預設邊框的偏移來構建(也就是我們打下的標簽)
訓練樣本。 這就相當于,預設邊框先大致在可能的位置“框“出來目標,然后再在這些預設邊框的基礎上進行調整。
一個Anchor Box可以由:邊框的縱橫比和邊框的面積(尺度)來定義,相當于一系列預設邊框的生成規(guī)則,根據(jù)Anchor Box,可以在圖像的任意位置,生成一系列的邊框
3.超參數(shù)進化
yolov5提供了一種超參數(shù)優(yōu)化的方法–Hyperparameter Evolution,即超參數(shù)進化。超參數(shù)進化是一種利用 遺傳算法(GA) 進行超參數(shù)優(yōu)化的方法,我們可以通過該方法選擇更加合適自己的超參數(shù)。
提供的默認參數(shù)也是通過在COCO數(shù)據(jù)集上使用超參數(shù)進化得來的。由于超參數(shù)進化會耗費大量的資源和時間,如果默認參數(shù)訓練出來的結果能滿足你的使用,使用默認參數(shù)也是不錯的選擇。
4.凍結訓練——Freeze training
凍結訓練的作用:當我們已有部分預訓練權重,這部分預訓練權重所應用的那部分網(wǎng)絡是通用的,如骨干網(wǎng)絡,那么我們可以先凍結這部分權重的訓練,將更多的資源放在訓練后面部分的網(wǎng)絡參數(shù),這樣使得時間和資源利用都能得到很大改善。然后后面的網(wǎng)絡參數(shù)訓練一段時間之后再解凍這些被凍結的部分,這時再全部一起訓練。
5.多尺度訓練——multi-scale training
當前的多尺度訓練(Multi Scale Training,MST)通常是指設置幾種不同的圖片輸入尺度,訓練時從多個尺度中隨機選取一種尺度,將輸入圖片縮放到該尺度并送入網(wǎng)絡中,是一種簡單又有效的提升多尺度物體檢測的方法。雖然一次迭代時都是單一尺度的,但每次都各不相同,增加了網(wǎng)絡的魯棒性,又不至于增加過多的計算量。而在測試時,為了得到更為精準的檢測結果,也可以將測試圖片的尺度放大,例如放大4倍,這樣可以避免過多的小物體。
6. 加權圖像策略
圖像加權策略可以解決樣本不平衡的,具體操作步驟圖下:
根據(jù)樣本種類分布使用圖像調用頻率不同的方法解決。
1、讀取訓練樣本中的GT,保存為一個列表;
2、計算訓練樣本列表中不同類別個數(shù),然后給每個類別按相應目標框數(shù)的倒數(shù)賦值,數(shù)目越多的種類權重越小,形成按種類的分布直方圖;
3、對于訓練數(shù)據(jù)列表,訓練時按照類別權重篩選出每類的圖像作為訓練數(shù)據(jù)。使用random.choice(population, weights=None, *, cum_weights=None, k=1)更改訓練圖像索引,可達到樣本均衡的效果。
7.矩形推理——Rectangular Inference
通常YOLO系列網(wǎng)絡的輸入都是預處理后的方形圖像數(shù)據(jù),如416 * 416、608 * 608。當原始圖像為矩形時,會將其填充為方形(如下圖:方形輸入),但是填充的灰色區(qū)域其實就是冗余信息,不論是在訓練還是推理階段,這些冗余信息都會增加耗時。
為了減少圖像的冗余數(shù)據(jù),輸入圖像由方形改為矩形(如下圖:矩形輸入):將長邊resize為固定尺寸(如416),短邊按同樣比例resize,然后把短邊的尺寸盡量少地填充為32的倍數(shù)。
這種方法在推理階段稱為矩形推理(Rectangular Inference),在訓練階段則稱為矩形訓練(Rectangular Training)。推理階段直接對圖像進行resize和pad就行,但是訓練階段輸入的是一個批次的圖像集合,需要保持批次內(nèi)的圖像尺寸一致,因此處理邏輯相對復雜一些。
8.非極大值抑制——NMS
在目標檢測的預測階段時,會輸出許多候選的anchor box,其中有很多是明顯重疊的預測邊界框都圍繞著同一個目標,這時候我就可以使用NMS來合并同一目標的類似邊界框,或者說是保留這些邊界框中最好的一個。
9. 斷點訓練
在用yolov5訓練數(shù)據(jù)的過程中由于突發(fā)情況訓練過程突然中斷,從頭訓練耗時,想接著上次訓練繼續(xù)訓練怎么辦。放心,在yolov5中給我們提供現(xiàn)成的參數(shù)–resume文章來源:http://www.zghlxwxcb.cn/news/detail-417109.html
10.早停機制(Early Stopping)
patience:訓練了多少個epoch,如果模型效果未提升,就讓模型提前停止訓練。
fitness監(jiān)控的是增大的數(shù)值,例如mAP,如果mAP在連續(xù)訓練patience次內(nèi)沒有增加就停止訓練。文章來源地址http://www.zghlxwxcb.cn/news/detail-417109.html
11.多GPU訓練
到了這里,關于YOLOv5網(wǎng)絡結構,訓練策略詳解的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!