yolov5基礎--yolov5源碼閱讀(common.py)

在這里插入圖片描述

  • 🍨 本文為🔗365天深度學習訓練營 中的學習記錄博客
  • 🍖 原作者:K同學啊

博主簡介:努力學習的22級本科生一枚 🌟?;探索AI算法,C++,go語言的世界;在迷茫中尋找光芒?🌸
博客主頁:羊小豬~~-CSDN博客
內容簡介common.py詳解,common.py文件講述的是yolo網絡具體實現 🙏 🙏 🙏
往期–>yolov5網絡結構講解:深度學習基礎–yolov5網絡結構簡介,C3模塊構建_yolov5的c3模塊結構-CSDN博客

文章目錄

  • 1、導入庫
  • 2、基本組件
    • autopad
    • Conv
    • Focus
    • Bottlenck
    • BottlenckCSP
    • C3
    • SPP
    • ConCat
    • Contract、Expand

📖 前言:

common.py文件是實現YOLO算法中各個模塊的地方,如果我們需要修改某一模塊(例如C3),那么就需要修改這個文件中對應模塊的的定義。*.yaml文件是yolo網絡結構的搭建,而common.py是每個網絡模塊具體實現的地方。

YOLOv5網絡結構

在這里插入圖片描述

1、導入庫

這部分是導入需要用到的包和庫。

import ast
import contextlib
import json
import math
import platform
import warnings
import zipfile
from collections import OrderedDict, namedtuple
from copy import copy
from pathlib import Path
from urllib.parse import urlparseimport cv2
import numpy as np
import pandas as pd
import requests
import torch
import torch.nn as nn
from PIL import Image
from torch.cuda import amp

2、基本組件

autopad

這個模塊是自動計算padding值的。

def autopad(k, p=None, d=1):"""Pads kernel to 'same' output shape, adjusting for optional dilation; returns padding size.`k`: kernel, `p`: padding, `d`: dilation."""if d > 1:k = d * (k - 1) + 1 if isinstance(k, int) else [d * (x - 1) + 1 for x in k]  # actual kernel-sizeif p is None:p = k // 2 if isinstance(k, int) else [x // 2 for x in k]  # auto-padreturn p

Conv

這個模塊是整個網絡中最基礎的組件,由卷積層 + BN層 + SiLU激活函數組成。

在這里插入圖片描述

class Conv(nn.Module):# Standard convolution with args(ch_in, ch_out, kernel, stride, padding, groups, dilation, activation)default_act = nn.SiLU()  # default activationdef __init__(self, c1, c2, k=1, s=1, p=None, g=1, d=1, act=True):"""Initializes a standard convolution layer with optional batch normalization and activation."""'''c1:輸入的channel值c2:輸出的channel值k:卷積的kernel sizeparamss:卷積的strideparams p:卷積的padding一般是None 可以通過autopad自行計算需要pad的paddingparams g:卷積的groups數=1就是普通的卷積 >1就是深度可分離卷積params 		act:激活函數類型True就是SiLU()/Swish,False就是不使用激活函數類型是nn.Module就使用傳進來的激活函數類型'''super().__init__()self.conv = nn.Conv2d(c1, c2, k, s, autopad(k, p, d), groups=g, dilation=d, bias=False)self.bn = nn.BatchNorm2d(c2)self.act = self.default_act if act is True else act if isinstance(act, nn.Module) else nn.Identity()def forward(self, x):"""Applies a convolution followed by batch normalization and an activation function to the input tensor `x`."""return self.act(self.bn(self.conv(x)))def forward_fuse(self, x):"""Applies a fused convolution and activation function to the input tensor `x`."""return self.act(self.conv(x))

Focus

這個模塊是作者設計出來的,目的是為了減少浮點數和提高精度。

📘 本質:將圖片進行切片,將圖片的寬、高進行切分,然后聚合到通道中,即實現了圖片縮放、也提高了特征提前取。

實現:分組卷積。

在這里插入圖片描述

class Focus(nn.Module):# Focus wh information into c-spacedef __init__(self, c1, c2, k=1, s=1, p=None, g=1, act=True):"""Initializes Focus module to concentrate width-height info into channel space with configurable convolutionparameters."""''' 在yolo.py的parse_model函數中被調用理論:從高分辨率圖像中,周期性的抽出像素點重構到低分辨率圖像中,即將圖像相鄰的四個位置進行堆疊,聚焦wh維度信息到c通道,提高每個點感受野,并減少原始信息的丟失,該模塊的設計主要是減少計算量加快速度。Focus wh information into c-space 把寬度w和高度h的信息整合到c空間中先做4個slice 再concat 最后再做Convslice后 (b,c1,w,h) -> 分成4個slice 每個slice(b,c1,w/2,h/2)concat(dim=1)后 4個slice(b,c1,w/2,h/2)) -> (b,4c1,w/2,h/2)conv后 (b,4c1,w/2,h/2) -> (b,c2,w/2,h/2):params c1: slice后的channel:params c2: Focus最終輸出的channel:params k: 最后卷積的kernel:params s: 最后卷積的stride:params p: 最后卷積的padding:params g: 最后卷積的分組情況  =1普通卷積  >1深度可分離卷積:params act: bool激活函數類型  默認True:SiLU()/Swish  False:不用激活函數'''super().__init__()self.conv = Conv(c1 * 4, c2, k, s, p, g, act=act)# self.contract = Contract(gain=2)def forward(self, x):"""Processes input through Focus mechanism, reshaping (b,c,w,h) to (b,4c,w/2,h/2) then applies convolution."""return self.conv(torch.cat((x[..., ::2, ::2], x[..., 1::2, ::2], x[..., ::2, 1::2], x[..., 1::2, 1::2]), 1))# return self.conv(self.contract(x))

Bottlenck

模型結構:

在這里插入圖片描述

作用:采用殘差連接,解決梯度消失問題。

class Bottleneck(nn.Module):# Standard bottleneckdef __init__(self, c1, c2, shortcut=True, g=1, e=0.5):"""在BottleneckCSP和yolo.py的parse_model中調用Standard bottleneck  Conv+Conv+shortcut:params c1: 第一個卷積的輸入channel:params c2: 第二個卷積的輸出channel:params shortcut: bool 是否有shortcut連接 默認是True:params g: 卷積分組的個數  =1就是普通卷積  >1就是深度可分離卷積:params e: expansion ratio  e*c2就是第一個卷積的輸出channel=第二個卷積的輸入channel"""super().__init__()c_ = int(c2 * e)  # hidden channelsself.cv1 = Conv(c1, c_, 1, 1)self.cv2 = Conv(c_, c2, 3, 1, g=g)self.add = shortcut and c1 == c2def forward(self, x):"""Processes input through two convolutions, optionally adds shortcut if channel dimensions match; input is atensor."""return x + self.cv2(self.cv1(x)) if self.add else self.cv2(self.cv1(x))

BottlenckCSP

這個模塊有Bottleneck模塊和CSP結構組成。這個模塊和C3等效,但是一般YOLO用的是C3結構。

網絡結構:

在這里插入圖片描述

class BottleneckCSP(nn.Module):# CSP Bottleneck https://github.com/WongKinYiu/CrossStagePartialNetworksdef __init__(self, c1, c2, n=1, shortcut=True, g=1, e=0.5):"""在C3模塊和yolo.py的parse_model模塊調用CSP Bottleneck https://github.com/WongKinYiu/CrossStagePartialNetworks:params c1: 整個BottleneckCSP的輸入channel:params c2: 整個BottleneckCSP的輸出channel:params n: 有n個Bottleneck:params shortcut: bool Bottleneck中是否有shortcut,默認True:params g: Bottleneck中的3x3卷積類型  =1普通卷積  >1深度可分離卷積:params e: expansion ratio c2xe=中間其他所有層的卷積核個數/中間所有層的輸入輸出channel數"""super().__init__()c_ = int(c2 * e)  # hidden channelsself.cv1 = Conv(c1, c_, 1, 1)self.cv2 = nn.Conv2d(c1, c_, 1, 1, bias=False)self.cv3 = nn.Conv2d(c_, c_, 1, 1, bias=False)self.cv4 = Conv(2 * c_, c2, 1, 1)self.bn = nn.BatchNorm2d(2 * c_)  # applied to cat(cv2, cv3)self.act = nn.SiLU()self.m = nn.Sequential(*(Bottleneck(c_, c_, shortcut, g, e=1.0) for _ in range(n)))def forward(self, x):"""Performs forward pass by applying layers, activation, and concatenation on input x, returning feature-enhanced output."""y1 = self.cv3(self.m(self.cv1(x)))y2 = self.cv2(x)return self.cv4(self.act(self.bn(torch.cat((y1, y2), 1))))

C3

這個是BottlenckCSP的簡化版,常用,作用是緩解梯度消失、提取特征。

👓 網絡結構:

在這里插入圖片描述

class C3(nn.Module):# CSP Bottleneck with 3 convolutionsdef __init__(self, c1, c2, n=1, shortcut=True, g=1, e=0.5):"""在C3TR模塊和yolo.py的parse_model模塊調用CSP Bottleneck with 3 convolutions:params c1: 整個BottleneckCSP的輸入channel:params c2: 整個BottleneckCSP的輸出channel:params n: 有n個Bottleneck:params shortcut: bool Bottleneck中是否有shortcut,默認True:params g: Bottleneck中的3x3卷積類型  =1普通卷積  >1深度可分離卷積:params e: expansion ratio c2xe=中間其他所有層的卷積核個數/中間所有層的輸入輸出channel數"""super().__init__()c_ = int(c2 * e)  # hidden channelsself.cv1 = Conv(c1, c_, 1, 1)self.cv2 = Conv(c1, c_, 1, 1)self.cv3 = Conv(2 * c_, c2, 1)  # optional act=FReLU(c2)self.m = nn.Sequential(*(Bottleneck(c_, c_, shortcut, g, e=1.0) for _ in range(n)))def forward(self, x):"""Performs forward propagation using concatenated outputs from two convolutions and a Bottleneck sequence."""return self.cv3(torch.cat((self.m(self.cv1(x)), self.cv2(x)), 1))

SPP

空間金字塔池化(Spatial Pyramid Pooling,SPP)是目標檢測算法中對高層特征進行多尺度池化以增加感受野的重要措施之一。

經典的空間金字塔池化模塊首先將輸入的卷積特征分成不同的尺寸,然后每個尺寸提取固定維度的特征,最后將這些特征拼接成個固定的維度

如圖所示:

  • 輸入的卷積特征圖的大小為(w,h),第一層空間金字塔采用 4x4 的刻度對特征圖進行劃分,其將輸入的特征圖分成了16個塊,每塊的大小為(w/4,h/4);
  • 第二層空間金字塔采用2x2刻度對特征圖進行劃分,其將特征圖分為4個快每塊大小為(w/2,h/2);
  • 第三層空間金字塔將整張特征圖作為一塊,進行特征提取操作,最終的特征向量為 21=16+4+1 維

在這里插入圖片描述

SPP模塊

在這里插入圖片描述

class SPP(nn.Module):# Spatial Pyramid Pooling (SPP) layer https://arxiv.org/abs/1406.4729def __init__(self, c1, c2, k=(5, 9, 13)):"""Initializes SPP layer with Spatial Pyramid Pooling, ref: https://arxiv.org/abs/1406.4729, args: c1 (input channels), c2 (output channels), k (kernel sizes)."""super().__init__()c_ = c1 // 2  # hidden channelsself.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):"""Applies convolution and max pooling layers to the input tensor `x`, concatenates results, and returns outputtensor."""x = self.cv1(x)with warnings.catch_warnings():warnings.simplefilter("ignore")  # suppress torch 1.9.0 max_pool2d() warningreturn self.cv2(torch.cat([x] + [m(x) for m in self.m], 1))

ConCat

這個模塊作用是:對兩個維度進行合并,合并成一個新的特征圖(一般是通道進行合并).

class Concat(nn.Module):# Concatenate a list of tensors along dimensiondef __init__(self, dimension=1):"""在yolo.py的parse_model模塊調用Concatenate a list of tensors along dimension:params dimension: 沿著哪個維度進行concat"""super().__init__()self.d = dimensiondef forward(self, x):"""Concatenates a list of tensors along a specified dimension; `x` is a list of tensors, `dimension` is anint."""return torch.cat(x, self.d)

Contract、Expand

這兩個函數用于改變 feature map 維度。

  • Contract 函數改變輸入特征的shape,將feature map 的 w和h 維度(縮小)的數據收縮到 channel 維度上(放大)。如:x(1,64,80,80) to x(1,256,40,40)

  • Expand 函數也是改變輸入特征的 shape,不過與 Contract 的相反,是將 channel 維度(變小)的數據擴展到W和H維度(變大)。如:x(1,64,80,80)to x(1,16,160,160)

class Contract(nn.Module):# Contract width-height into channels, i.e. x(1,64,80,80) to x(1,256,40,40)def __init__(self, gain=2):"""Initializes a layer to contract spatial dimensions (width-height) into channels, e.g., input shape(1,64,80,80) to (1,256,40,40)."""super().__init__()self.gain = gaindef forward(self, x):"""Processes input tensor to expand channel dimensions by contracting spatial dimensions, yielding output shape`(b, c*s*s, h//s, w//s)`."""b, c, h, w = x.size()  # assert (h / s == 0) and (W / s == 0), 'Indivisible gain's = self.gainx = x.view(b, c, h // s, s, w // s, s)  # x(1,64,40,2,40,2)x = x.permute(0, 3, 5, 1, 2, 4).contiguous()  # x(1,2,2,64,40,40)return x.view(b, c * s * s, h // s, w // s)  # x(1,256,40,40)class Expand(nn.Module):# Expand channels into width-height, i.e. x(1,64,80,80) to x(1,16,160,160)def __init__(self, gain=2):"""Initializes the Expand module to increase spatial dimensions by redistributing channels, with an optional gainfactor.Example: x(1,64,80,80) to x(1,16,160,160)."""super().__init__()self.gain = gaindef forward(self, x):"""Processes input tensor x to expand spatial dimensions by redistributing channels, requiring C / gain^2 ==0."""b, c, h, w = x.size()  # assert C / s ** 2 == 0, 'Indivisible gain's = self.gainx = x.view(b, s, s, c // s**2, h, w)  # x(1,2,2,16,80,80)x = x.permute(0, 3, 4, 1, 5, 2).contiguous()  # x(1,16,80,2,80,2)return x.view(b, c // s**2, h * s, w * s)  # x(1,16,160,160)

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/82368.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/82368.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/82368.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

5.0.5 變換(旋轉、縮放、扭曲)

WPF變換可以產生特殊效果,如平移、旋轉、扭曲。 變換類 描述TranslateTransform沿著X軸和Y軸平移ScaleTransform 沿著定義的中心點縮放RotateTransform沿著定義的中心點旋轉SkewTransform 扭曲元素MatrixTransfrom提供3x3矩陣,用于定義一個自定義變換 1…

如何設置內網映射端口到外網訪問?哪些軟件可以進行端口映射?

大多數時候我們所使用的服務器都是在內網搭建的,而且內網是可以訪問外網的,但外網是沒法直接訪問內網IP和端口服務的。也就是說外網無法直接訪問到內網的網絡地址,需要大家去搭建一個內外網互通的橋梁,把內網服務器指定端口映射到…

養生:塑造健康生活的良方

養生是一場貫穿生活的自我關愛行動,從飲食、運動、睡眠到心態調節,每一個環節都對健康有著深遠影響。以下為你帶來全面且實用的養生策略。 飲食養生:科學搭配,呵護腸胃 合理規劃三餐,遵循 “早營養、午均衡、晚清淡”…

YOLOv12云端GPU谷歌免費版訓練模型

1.效果 2.打開 https://colab.research.google.com/?utm_sourcescs-index 3.上傳代碼 4.解壓 !unzip /content/yolov12-main.zip -d /content/yolov12-main 5.進入yolov12-main目錄 %cd /content/yolov12-main/yolov12-main 6.安裝依賴庫 !pip install -r requirements.…

機器人手臂的坐標變換:一步步計算齊次矩陣過程 [特殊字符]

大家好!今天我們來學習如何計算機器人手臂的坐標變換。別擔心,我會用最簡單的方式解釋這個過程,就像搭積木一樣簡單! 一、理解問題 我們有一個機器人手臂,由多個關節組成。每個關節都有自己的坐標系,我們需要計算從世界坐標系(W)到末端執行器(P?)的完整變換。 二、已…

CSS中的@import指令

一、什么是import指令&#xff1f; import 是CSS提供的一種引入外部樣式表的方式&#xff0c;允許開發者在CSS文件中引入其他CSS文件&#xff0c;或者在HTML的<style>標簽中引入外部樣式。與常見的<link>標簽相比&#xff0c;import 提供了一種更“CSS原生”的樣式…

[學成在線]23-面試題總結

1. 詳細說說你的項目吧 從以下幾個方面進行項目介紹: 項目的背景&#xff0c;包括: 是自研還是外包、什么業務、服務的客戶群是誰、誰去運營等問題。項目的業務流程項目的功能模塊項目的技術架構個人工作職責個人負責模塊的詳細說明&#xff0c;包括模塊的設計&#xff0c;所…

C++編程語言:標準庫:標準庫概觀(Bjarne Stroustrup)

第30章 標準庫概觀(Standard-Library Overview) 目錄 30.1 引言 30.1.1 標準庫設施 30.1.2 設計約束 30.1.3 描述風格 30.2 頭文件 30.3 語言支持 30.3.1 對initializer_list的支持 30.3.2 對范圍for的支持 30.4 異常處理 30.4.1 異常 30.4.1…

spring5.x講解介紹

Spring 5.x 是 Spring Framework 的重要版本升級&#xff0c;全面擁抱現代 Java 技術棧&#xff0c;其核心改進涵蓋響應式編程、Java 8支持、性能優化及開發模式創新。以下從特性、架構和應用場景三個維度詳細解析&#xff1a; 一、核心特性與架構改進 Java 8 全面支持 Spring …

【C++進階】第2課—多態

文章目錄 1. 認識多態2. 多態的定義和實現2.1 構成多態的必要條件2.2 虛函數2.3 虛函數的重寫或覆蓋2.4 協變(了解)2.5 析構函數的重寫2.6 override和final關鍵字2.7 重載、重寫、隱藏對比 3. 純虛函數和抽象類4. 多態原理4.1 虛函數表指針4.2 多態的實現4.3 靜態綁定和動態綁定…

Dive into LVGL (1) —— How LVGL works from top to down

0.briefly speaking 由于工作原因&#xff0c;最近開始接觸到一些圖形圖像處理相關的知識&#xff0c;在這個過程中逐漸接觸到了LVGL。作為一個開源的圖形庫&#xff0c;LVGL可以高效地為MCU、MPU等嵌入式設備構建美觀的UI界面。我的手頭也正好有一塊集成了Vivante 2.5D GPU的…

【HarmonyOS 5】鴻蒙中進度條的使用詳解

【HarmonyOS 5】鴻蒙中進度條的使用詳解 一、HarmonyOS中Progress進度條的類型 HarmonyOS的ArkUI框架為開發者提供了多種類型的進度條&#xff0c;每種類型都有其獨特的樣式&#xff0c;以滿足不同的設計需求。以下是幾種常見的進度條類型&#xff1a; 線性進度條&#xff08;…

OpenHarmony 開源鴻蒙南向開發——linux下使用make交叉編譯第三方庫——gmp

準備工作 請依照這篇文章搭建環境 OpenHarmony 開源鴻蒙南向開發——linux下使用make交叉編譯第三方庫——環境配置_openharmony交叉編譯-CSDN博客 下載 wget https://gmplib.org/download/gmp/gmp-6.3.0.tar.xz 解壓 tar -xf gmp-6.3.0.tar.xzcd gmp-6.3.0/ 環境變量 e…

量化交易策略的運行

? 什么是“策略的運行”&#xff1f; 在量化交易系統中&#xff0c;“策略的運行”并不一定意味著“每個策略對應一個線程”&#xff0c;但在大多數實際實現中&#xff0c;確實會使用線程、任務、協程或進程等形式來實現每個策略的獨立調度與執行。 “運行”意味著策略開始生…

開平機:從原理到實踐的全面技術剖析

一、開平機核心模塊技術解析 1. 校平輥系的力學建模與輥型設計 校平機精度核心在于輥系設計&#xff0c;需通過彈塑性力學模型計算變形量。典型校平輥配置參數&#xff1a; 輥徑比&#xff1a;校平輥直徑&#xff08;D&#xff09;與板材厚度&#xff08;t&#xff09;需滿足…

2、實驗室測控系統 - /自動化與控制組件/lab-monitoring-system

76個工業組件庫示例匯總 實驗室測控系統開發組件 這是一個專為實驗室設備數據采集與分析設計的可視化測控系統組件。采用工業風格界面設計&#xff0c;提供了豐富的動態數據展示與分析功能&#xff0c;可應用于各類實驗室環境中的設備監控和數據處理。 功能特點 多設備管理…

在 Kotlin 中什么是委托屬性,簡要說說其使用場景和原理

在 Kotlin 中&#xff0c;屬性委托和類委托是兩種通過 by 關鍵字實現的強大特性&#xff0c;它們通過“委托”機制將行為或實現邏輯委托給其他對象&#xff0c;從而實現代碼的復用和解耦。 1 屬性委托 定義&#xff1a; 允許把屬性的 get 和 set 方法的具體實現委托給另一個對…

AI星智協腦:智能驅動的高效協作管理平臺全解讀

前言 想象一下&#xff1a;早上剛開電腦&#xff0c;十幾條未讀消息如機關槍般掃射而來&#xff0c;各路任務像隕石雨一樣砸向你&#xff0c;會議排得比熱播劇還密集&#xff0c;文檔版本堪比宮斗劇劇情反轉&#xff0c;同事圍著你轉圈追KPI&#xff0c;活脫脫一場《職場大逃殺…

Web 架構之數據讀寫分離

文章目錄 一、引言二、數據讀寫分離原理2.1 基本概念2.2 工作流程 三、數據讀寫分離的實現方式3.1 基于中間件實現3.2 應用程序層面實現 四、常見問題及解決方法4.1 數據一致性問題4.2 從數據庫負載均衡問題4.3 主從復制故障問題 五、思維導圖六、總結 一、引言 在 Web應用的開…

【軟件設計師:數據結構】1.數據結構基礎(一)

一 線性表 1.線性表定義 線性表是n個元素的有限序列,通常記為(a1,a2,…,an)。 特點: 存在惟一的表頭和表尾。除了表頭外,表中的每一個元素均只有惟一的直接前驅。除了表尾外,表中的每一個元素均只有惟一的直接后繼。2.線性表的存儲結構 (1)順序存儲 是用一組地址連續…