🚀🚀🚀本專欄所有的改進均可成功執行🚀🚀🚀
盡管Ultralytics 推出了最新版本的 YOLOv8 模型。但YOLOv5作為一個anchor base的目標檢測的算法,YOLOv5可能比YOLOv8的效果更好。但是針對不同的數據集仍然有提升改進的空間,本文給大家帶來的教程是修改BiFPN到Neck中。文章在簡單介紹原理后,將手把手教學如何進行模塊的代碼添加和修改,并將修改后的完整代碼放在文章的最后,方便大家一鍵運行,小白也可輕松上手實踐。以幫助您更好地學習深度學習目標檢測YOLO系列的挑戰。
專欄地址:YOLOv5改進+入門——持續更新各種有效漲點方法?
目錄
1.原理
2.BiFPN代碼
2.1 添加BiFPN代碼
2.2 新增yaml文件
2.3 注冊模塊
2.4 執行程序
3.總結
?1.原理
論文地址:EfficientDet: Scalable and Efficient Object Detection點擊即可跳轉?
官方代碼:官方代碼倉庫點擊即可跳轉
BiFPN,即Bilateral Feature Pyramid Network,是一種用于目標檢測任務的神經網絡結構。它是對FPN(Feature Pyramid Network)的改進,旨在提高特征金字塔網絡的性能,特別是在處理高分辨率圖像時。
BiFPN最初是在EfficientDet模型中提出的,EfficientDet是一種高效的目標檢測模型,結合了BiFPN、EfficientNet和其他一些技巧。BiFPN的主要目標是處理FPN中存在的信息損失和模糊性的問題。
BiFPN引入了兩個關鍵的概念來改善FPN:
1. 雙向連接(Bilateral Connections):BiFPN不僅在不同層級之間進行自上而下的特征傳遞,還引入了自下而上的特征傳遞,這樣可以更好地利用不同層級的特征信息。
2. 雙線性匯聚(Bilinear Pooling):BiFPN使用雙線性匯聚來融合不同分辨率的特征圖,從而提高了特征的表征能力。
通過這些改進,BiFPN在目標檢測任務中取得了很好的效果,尤其是在處理大分辨率圖像和小目標時,相比于傳統的FPN結構,BiFPN能夠提供更加準確和穩定的特征表征,從而提高了目標檢測的性能。
2.BiFPN代碼
2.1 添加BiFPN代碼
關鍵步驟一:在\yolov5-6.1\models\common.py中添加下面代碼
# 結合BiFPN 設置可學習參數 學習不同分支的權重
# 兩個分支concat操作
class BiFPN_Concat2(nn.Module):def __init__(self, dimension=1):super(BiFPN_Concat2, self).__init__()self.d = dimensionself.w = nn.Parameter(torch.ones(2, dtype=torch.float32), requires_grad=True)self.epsilon = 0.0001def forward(self, x):w = self.wweight = w / (torch.sum(w, dim=0) + self.epsilon) # 將權重進行歸一化# Fast normalized fusionx = [weight[0] * x[0], weight[1] * x[1]]return torch.cat(x, self.d)# 三個分支concat操作
class BiFPN_Concat3(nn.Module):def __init__(self, dimension=1):super(BiFPN_Concat3, self).__init__()self.d = dimension# 設置可學習參數 nn.Parameter的作用是:將一個不可訓練的類型Tensor轉換成可以訓練的類型parameter# 并且會向宿主模型注冊該參數 成為其一部分 即model.parameters()會包含這個parameter# 從而在參數優化的時候可以自動一起優化self.w = nn.Parameter(torch.ones(3, dtype=torch.float32), requires_grad=True)self.epsilon = 0.0001def forward(self, x):w = self.wweight = w / (torch.sum(w, dim=0) + self.epsilon) # 將權重進行歸一化# Fast normalized fusionx = [weight[0] * x[0], weight[1] * x[1], weight[2] * x[2]]return torch.cat(x, self.d)
BiFPN的主要流程可以分為以下幾個步驟:
1. 特征提取:首先,輸入圖像經過卷積神經網絡(如EfficientNet等)進行特征提取,得到一系列特征圖,這些特征圖包含了不同層級的語義信息。
2. 自下而上特征傳遞:BiFPN從底層開始,利用雙線性池化將低分辨率特征圖上采樣到高分辨率,然后使用雙向連接,將上一層的特征圖與下一層的上采樣特征圖進行融合。這種自下而上的特征傳遞可以幫助從更低層級獲取更豐富的信息。
3. 自上而下特征傳遞:接著,BiFPN沿著特征金字塔網絡的自上而下路徑進行特征傳遞。在這個過程中,BiFPN利用雙向連接,將上一層的特征圖與下一層的上采樣特征圖進行融合,以獲得更加豐富和準確的特征表征。
4. 多尺度特征融合:BiFPN在每個層級上都進行多尺度特征融合,將不同分辨率的特征圖通過雙線性池化進行融合,從而提高特征的表征能力和魯棒性。
5. 最終特征輸出:最后,BiFPN輸出的特征圖經過一系列后續處理,如分類器和回歸器等,用于目標檢測任務中的目標分類和邊界框回歸等。
通過這樣的流程,BiFPN能夠充分利用不同層級的特征信息,并通過雙向連接和雙線性池化等技巧,提高了特征的表征能力和目標檢測的性能。
2.2 新增yaml文件
關鍵步驟二:在 /yolov5/models/ 下新建文件 yolov5_bifpn.yaml并將下面代碼復制進去
# YOLOv5 🚀 by Ultralytics, GPL-3.0 license# Parameters
nc: 2 # number of classes
depth_multiple: 0.33 # model depth multiple
width_multiple: 0.50 # layer channel multiple
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# YOLOv5 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]], # 10]# YOLOv5 v6.0 BiFPN head
head:[[-1, 1, Conv, [512, 1, 1]],[-1, 1, nn.Upsample, [None, 2, 'nearest']],[[-1, 6], 1, BiFPN_Concat2, [1]], # cat backbone P4 <--- BiFPN change[-1, 3, C3, [512, False]], # 13[-1, 1, Conv, [256, 1, 1]],[-1, 1, nn.Upsample, [None, 2, 'nearest']],[[-1, 4], 1, BiFPN_Concat2, [1]], # cat backbone P3 <--- BiFPN change[-1, 3, C3, [256, False]], # 17 (P3/8-small)[-1, 1, Conv, [256, 3, 2]],[[-1, 14, 6], 1, BiFPN_Concat3, [1]], # cat P4 <--- BiFPN change[-1, 3, C3, [512, False]], # 20 (P4/16-medium)[-1, 1, Conv, [512, 3, 2]],[[-1, 10], 1, BiFPN_Concat2, [1]], # cat head P5 <--- BiFPN change[-1, 3, C3, [1024, False]], # 23 (P5/32-large)[[17, 20, 23], 1, Detect, [nc, anchors]], # Detect(P3, P4, P5)]
溫馨提示:因為本文只是對yolov5n基礎上添加swin模塊,如果要對yolov5n/l/m/x進行添加則只需要修改對應的depth_multiple 和 width_multiple。
yolov5n/l/m/x對應的depth_multiple 和 width_multiple如下:
# YOLOv5n
depth_multiple: 0.33 # model depth multiple
width_multiple: 0.25 # layer channel multiple# YOLOv5s
depth_multiple: 0.33 # model depth multiple
width_multiple: 0.50 # layer channel multiple# YOLOv5l
depth_multiple: 1.0 # model depth multiple
width_multiple: 1.0 # layer channel multiple# YOLOv5m
depth_multiple: 0.67 # model depth multiple
width_multiple: 0.75 # layer channel multiple# YOLOv5x
depth_multiple: 1.33 # model depth multiple
width_multiple: 1.25 # layer channel multiple
2.3 注冊模塊
關鍵步驟三:在yolov5/models/yolo.py中注冊,大概在270行左右添加下面內容
# 添加bifpn_concat結構
elif m is BiFPN_Concat2:c2 = sum(ch[x] for x in f)
# 添加bifpn_concat結構
elif m is BiFPN_Concat3:c2 = sum(ch[x] for x in f)
關鍵步驟四:在yolov5/train.py中注冊,大概在160行左右添加下面內容?
# BiFPN_Concat
elif isinstance(v, BiFPN_Concat2) and hasattr(v, 'w') and isinstance(v.w, nn.Parameter):g1.append(v.w)
elif isinstance(v, BiFPN_Concat3) and hasattr(v, 'w') and isinstance(v.w, nn.Parameter):g1.append(v.w)
2.4 執行程序
在train.py中,將cfg的參數路徑設置為yolov5_bifpn.yaml的路徑,如下圖所示
建議大家寫絕對路徑,確保一定能找到
?🚀運行程序,如果出現下面的內容則說明添加成功🚀
我修改后的代碼:鏈接: https://pan.baidu.com/s/1g1FREXzvRT4PpyYi9XYkzg?pwd=9m3b 提取碼: 9m3b
3.總結
BiFPN是一種用于目標檢測任務的改進型特征金字塔網絡,旨在解決傳統FPN在處理高分辨率圖像和小目標時存在的信息損失和模糊性問題。其主要流程包括特征提取、自下而上特征傳遞、自上而下特征傳遞、多尺度特征融合和最終特征輸出。BiFPN通過引入雙向連接和雙線性池化等關鍵技術,有效地提高了特征的表征能力和目標檢測的性能,特別是在處理大分辨率圖像和小目標時具有顯著優勢。?