注意力機制添加方法

?

要將注意力機制模塊添加到YoloV5工程項目中的yolo.py中,可參考以下四種情況。

以下4個elif代碼來自https://yolov5.blog.csdn.net/article/details/129108082

elif m in [SimAM, ECA, SpatialGroupEnhance,TripletAttention]:args = [*args[:]]elif m in [CoordAtt, GAMAttention]:c1, c2 = ch[f], args[0]if c2 != no:c2 = make_divisible(c2 * gw, 8)args = [c1, c2, *args[1:]]elif m in [SE, ShuffleAttention, CBAM, SKAttention, DoubleAttention, CoTAttention, EffectiveSEModule,GlobalContext, GatherExcite, MHSA]:c1 = ch[f]args = [c1, *args[0:]]elif m in [S2Attention, NAMAttention, CrissCrossAttention, SequentialPolarizedSelfAttention,ParallelPolarizedSelfAttention, ParNetAttention]:c1 = ch[f]args = [c1]

?

根據這4種情況,我們在yaml文件中,填寫args時(比如下圖中RefConv的[1024,3,1]以及SE中的[1024]),需要填入的參數個數是不同的

# 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]],  #2[-1, 1, Conv, [256, 3, 2]],  # 3-P3/8[-1, 6, C3, [256]],  #4[-1, 1, Conv, [512, 3, 2]],  # 5-P4/16[-1, 9, C3, [512]],  #6[-1, 1, Conv, [1024, 3, 2]],  # 7-P5/32[-1, 3, C3, [1024]],  # 8[-1,1,SE,[1024]],  #9[[-1, 1, SimAM, [1e-4]],  # 10[-1, 1, SPPF, [1024, 5]],  # 11[-1, 1, RefConv, [1024, 3, 1]],  # 12]

具體來說,是要將elif模塊添加到yolo.py文件中的parse_model函數里。在編寫elif模塊代碼時,我們需要關注的是,你的注意力機制模塊代碼(在common.py)中的__init__里面的參數,是否設置了“輸入通道數”和“輸出通道數”,這兩個參數。

?

一、先上結論

情況1:_init_中不包含“輸入通道數”和“輸出通道數”,但含有其它參數

以下這些模塊:SimAM,ECA,SpatialGroupEnhance,TripletAttention 全都滿足情況1

elif m in [SimAM, ECA, SpatialGroupEnhance,TripletAttention]:args = [*args[:]]

以下是SimAM,ECA,SpatialGroupEnhance,TripletAttention 的__init__

class SimAM(torch.nn.Module):def __init__(self, e_lambda=1e-4):class ECA(nn.Module):def __init__(self, k_size=3):class SpatialAttention(nn.Module):def __init__(self, kernel_size=7):class SpatialGroupEnhance(nn.Module):def __init__(self, groups=8):class TripletAttention(nn.Module):def __init__(self, no_spatial=False):

這里解釋一下args = [*args[:]]是什么意思

在Python中,*args 是一個特殊的語法,用于在函數定義中處理不確定數量的位置參數。args 是一個元組,包含了所有傳遞給函數的位置參數。

args[:] 是一個切片操作,它會創建一個 args 的淺拷貝。這意味著如果你修改了 args[:] 的內容,原始的 args 不會被改變。

[*args[:]] 則是將 args[:] 中的元素解包(unpack)成一個列表。這樣做的目的通常是為了創建一個新的列表,而不是修改原始的 args。

例如:

args = [1, 2, 3, 4]
new_args = [*args[:]]
print(new_args) #輸出為[1,2,3,4]

情況2:_init_中同時包含“輸入通道數”和“輸出通道數”,且含有其它參數

以下這些模塊:CoordAtt, GAMAttention 全都滿足情況2

elif m in [CoordAtt, GAMAttention]:c1, c2 = ch[f], args[0]if c2 != no:c2 = make_divisible(c2 * gw, 8)args = [c1, c2, *args[1:]]

以下是CoordAtt, GAMAttention 的__init__

class CoordAtt(nn.Module):def __init__(self, inp, oup, reduction=32):class GAMAttention(nn.Module):def __init__(self, c1, c2, group=True, rate=4):

情況3:_init_中只包含“輸入通道數”,不包含“輸出通道數”,且含有其它參數

以下這些模塊:SE, ShuffleAttention, CBAM, SKAttention, DoubleAttention, CoTAttention, EffectiveSEModule,GlobalContext, GatherExcite, MHSA全都滿足情況3

elif m in [SE, ShuffleAttention, CBAM, SKAttention, DoubleAttention, CoTAttention, EffectiveSEModule,GlobalContext, GatherExcite, MHSA]:c1 = ch[f]args = [c1, *args[0:]]

以下是SE, ShuffleAttention, CBAM, SKAttention, DoubleAttention, CoTAttention, EffectiveSEModule,GlobalContext, GatherExcite, MHSA的__init__

#SE機制它的輸入通道和輸出通道是一樣的,所以在實現上可以只傳入輸入通道c1,但如果也給出輸出通道c2的參數也是可以的。下面這兩種都是在迪菲赫爾曼博客中實現過的SE模塊
class SE(nn.Module):def __init__(self, c1, ratio=16):
class SE(nn.Module):def __init__(self, c1, c2, ratio=16):class ShuffleAttention(nn.Module):def __init__(self, channel=512, G=8):class CBAM(nn.Module):def __init__(self, c1, ratio=16, kernel_size=7):class SKAttention(nn.Module):def __init__(self, channel=512, kernels=[1, 3, 5, 7], reduction=16, group=1, L=32):class DoubleAttention(nn.Module):def __init__(self, in_channels, reconstruct=True):class CoTAttention(nn.Module):def __init__(self, dim=512, kernel_size=3):class EffectiveSEModule(nn.Module):def __init__(self, channels, add_maxpool=False, gate_layer='hard_sigmoid'):class GlobalContext(nn.Module):def __init__(self, channels, use_attn=True, fuse_add=False, fuse_scale=True, init_last_zero=False,rd_ratio=1. / 8, rd_channels=None, rd_divisor=1, act_layer=nn.ReLU, gate_layer='sigmoid'):
class GatherExcite(nn.Module):def __init__(self, channels, feat_size=None, extra_params=False, extent=0, use_mlp=True,rd_ratio=1. / 16, rd_channels=None, rd_divisor=1, add_maxpool=False,act_layer=nn.ReLU, norm_layer=nn.BatchNorm2d, gate_layer='sigmoid'):class MHSA(nn.Module):def __init__(self, n_dims, width=14, height=14, heads=4, pos_emb=False):    

情況4:_init_中只包含“輸入通道數”,不包含“輸出通道數”,且不含有其他參數(注意對比情況3)

以下這些模塊:S2Attention, NAMAttention, CrissCrossAttention, SequentialPolarizedSelfAttention,ParallelPolarizedSelfAttention, ParNetAttention全都滿足情況4

elif m in [S2Attention, NAMAttention, CrissCrossAttention, SequentialPolarizedSelfAttention,ParallelPolarizedSelfAttention, ParNetAttention]:c1 = ch[f]args = [c1]

以下是S2Attention, NAMAttention, CrissCrossAttention, SequentialPolarizedSelfAttention,ParallelPolarizedSelfAttention, ParNetAttention的__init__

class S2Attention(nn.Module):def __init__(self, channels=512):class NAMAttention(nn.Module):def __init__(self, channels):class CrissCrossAttention(nn.Module):def __init__(self, in_dim):class SequentialPolarizedSelfAttention(nn.Module):def __init__(self, channel=512):class ParallelPolarizedSelfAttention(nn.Module):def __init__(self, channel=512):class ParNetAttention(nn.Module):def __init__(self, channel=512):

?

二、解釋代碼

在理解代碼前,我們需要知道,在parse_model函數中,args列表的前兩個位置被設計為存放輸入通道數(c1)和輸出通道數(c2)。這是因為在創建這些模塊時,我們通常會按照這個順序傳遞參數。例如,對于nn.Conv2d,其構造函數的簽名為Conv2d(in_channels, out_channels, kernel_size, stride=1, padding=0, dilation=1, groups=1, bias=True),其中in_channels和out_channels就對應于我們的c1和c2。因此,當我們在parse_model函數中創建這些模塊時,我們需要先獲取c1和c2,然后將它們放在args的前兩個位置,以確保它們能被正確地傳遞給模塊的構造函數。

情況1

'''
這段代碼的目的是為了處理SimAM模塊的參數。elif m in [SimAM]:
這行代碼檢查當前的模塊m是否是SimAM模塊。如果是,那么就執行下一行代碼。args = [*args[:]]:
這行代碼創建了args的一個淺拷貝。在Python中,args[:]會創建一個新的列表,這個新列表包含了args中的所有元素。*操作符會將這個新列表解包,然后我們再用[]將解包后的元素重新組裝成一個新的列表。所以,[*args[:]]就等于args[:],它們都會創建args的一個淺拷貝。綜上,這段代碼使args列表保持不變,因為SimAM模塊不需要修改輸入和輸出通道數。
'''elif m in [SimAM, ECA, SpatialGroupEnhance,TripletAttention]:args = [*args[:]]

?

情況2

'''
這段代碼的目的是為了處理CoordAtt和GAMAttention模塊的參數。elif m in [CoordAtt, GAMAttention]:
這行代碼檢查當前的模塊m是否是CoordAtt模塊或GAMAttention模塊。如果是,那么就執行下面的代碼。c1, c2 = ch[f], args[0]:
這行代碼從ch和args兩個列表中獲取了兩個值c1和c2。ch是一個列表,它保存了模型中每一層的輸出通道數。f是一個索引,它指向ch中的某個元素,這個元素表示當前層的輸入通道數。所以ch[f]就是當前層的輸入通道數。args也是一個列表,它保存了當前層的參數。在模型配置文件中,每一層的參數都被保存在一個列表中,例如[64, 6, 2, 2]。這個列表的第一個元素通常是當前層的輸出通道數。所以args[0]就是當前層的輸出通道數。if c2 != no:
這行代碼檢查當前層的輸出通道數c2是否不等于no。no是模型的總輸出通道數。c2 = make_divisible(c2 * gw, 8):
如果c2不等于no,那么就重新計算c2的值。gw是模型的寬度倍數,make_divisible(c2 * gw, 8)會將c2 * gw調整為最接近的8的倍數。這是因為某些硬件(如GPU)在處理通道數為8的倍數的數據時,可以獲得更好的性能。args = [c1, c2, *args[1:]]:
這行代碼創建了一個新的參數列表args。新的args列表的第一個元素是c1,第二個元素是c2,剩下的元素是原始args列表的第二個元素及其后面的所有元素。*args[1:]是Python的解包(unpack)操作,它可以將列表args[1:]中的所有元素解包出來。所以,[c1, c2, *args[1:]]就等于[c1, c2]和args[1:]兩個列表的連接。
'''elif m in [CoordAtt, GAMAttention]:c1, c2 = ch[f], args[0]if c2 != no:c2 = make_divisible(c2 * gw, 8)args = [c1, c2, *args[1:]] 

情況3

'''
這段代碼的目的是為了處理SE, ShuffleAttention等模塊的參數。elif m in [SE, ShuffleAttention, CBAM, SKAttention, DoubleAttention, CoTAttention, EffectiveSEModule,GlobalContext, GatherExcite, MHSA]:
這行代碼檢查當前的模塊m是否是SE, ShuffleAttention等模塊中的一個。如果是,那么就執行下面的代碼。c1 = ch[f]:
這行代碼從ch列表中獲取了一個值c1。ch是一個列表,它保存了模型中每一層的輸出通道數。f是一個索引,它指向ch中的某個元素,這個元素表示當前層的輸入通道數。所以ch[f]就是當前層的輸入通道數。args = [c1, *args[0:]]:
這行代碼創建了一個新的參數列表args。新的args列表的第一個元素是c1,剩下的元素是原始args列表的第一個元素及其后面的所有元素。*args[0:]是Python的解包(unpack)操作,它可以將列表args[0:]中的所有元素解包出來。所以,[c1, *args[0:]]就等于[c1]和args[0:]兩個列表的連接。綜上,這段代碼將當前層的輸入通道數c1添加到參數列表args的開始位置,因為這些模塊的初始化函數通常需要輸入通道數作為第一個參數。'''elif m in [SE, ShuffleAttention, CBAM, SKAttention, DoubleAttention, CoTAttention, EffectiveSEModule,GlobalContext, GatherExcite, MHSA]:c1 = ch[f]args = [c1, *args[0:]]

?

情況4

'''
這段代碼的目的是為了處理S2Attention, NAMAttention等模塊的參數。elif m in [S2Attention, NAMAttention, CrissCrossAttention, SequentialPolarizedSelfAttention,ParallelPolarizedSelfAttention, ParNetAttention]:
這行代碼檢查當前的模塊m是否是S2Attention, NAMAttention等模塊中的一個。如果是,那么就執行下面的代碼。c1 = ch[f]:
這行代碼從ch列表中獲取了一個值c1。ch是一個列表,它保存了模型中每一層的輸出通道數。f是一個索引,它指向ch中的某個元素,這個元素表示當前層的輸入通道數。所以ch[f]就是當前層的輸入通道數。args = [c1]:這行代碼創建了一個新的參數列表args。新的args列表只有一個元素,就是c1。綜上,這段代碼將當前層的輸入通道數c1作為唯一的參數傳遞給這些模塊,因為這些模塊的初始化函數通常只需要輸入通道數作為參數。
'''elif m in [S2Attention, NAMAttention, CrissCrossAttention, SequentialPolarizedSelfAttention,ParallelPolarizedSelfAttention, ParNetAttention]:c1 = ch[f]args = [c1]

?

?

?

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

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

相關文章

【1day】致遠系統A6版本operaFileActionController.jsp接口任意文件讀取漏洞學習

注:該文章來自作者日常學習筆記,請勿利用文章內的相關技術從事非法測試,如因此產生的一切不良后果與作者無關。 目錄 一、漏洞描述 二、影響版本 三、資產測繪 四、漏洞復現

基于ResNet模型的908種超大規模中草藥圖像識別系統

中草藥藥材圖像識別相關的實踐在前文中已有對應的實踐了,感興趣的話可以自行移步閱讀即可: 《python基于輕量級GhostNet模型開發構建23種常見中草藥圖像識別系統》 《基于輕量級MnasNet模型開發構建40種常見中草藥圖像識別系統》 在上一篇文章中&…

RocketMQ-RocketMQ高性能核心原理(流程圖)

1.NamesrvStartup 2.BrokerStartup 3. DefualtMQProducer 4.DefaultMQPushConsumer

maven工程的pom.xml文件中增加了依賴,但偶爾沒有下載到本地倉庫

maven工程pom.xml文件中的個別依賴沒有下載到本地maven倉庫。以前沒有遇到這種情況,今天就遇到了這個問題,把解決過程記錄下來。 我在eclipse中編輯maven工程的pom.xml文件,增加對mybatis的依賴,但保存文件后,依賴的j…

Java--1v1雙向通信-控制臺版

文章目錄 前言客戶端服務器端輸出線程端End 前言 TCP(Transmission Control Protocol)是一種面向連接的、可靠的網絡傳輸協議,它提供了端到端的數據傳輸和可靠性保證。 本程序就是基于tcp協議編寫而成的。 利用 TCP 協議進行通信的兩個應用…

HarmonyOS(鴻蒙操作系統)與Android系統 各自特點 架構對比 各自優勢

綜合對比 HarmonyOS(鴻蒙操作系統)是由華為開發的操作系統,旨在跨多種設備和平臺使用。HarmonyOS的架構與谷歌開發的廣泛使用的Android操作系統有顯著不同。以下是兩者之間的一些主要比較點: 設計理念和使用案例: Harm…

go語言 grpc 攔截器

文章目錄 攔截器服務端攔截器一元攔截器流攔截器 客戶端攔截器一元攔截器流攔截 多個攔截器 代碼倉庫 攔截器 gRPC攔截器(interceptor)是一種函數,它可以在gRPC調用之前和之后執行一些邏輯,例如認證、授權、日志記錄、監控和統計…

iOS app切換后臺時添加模糊遮罩層

仿 支付寶 退出后臺后,App整個 增加模糊遮罩層 此處只介紹 在iOS13后 SceneDelegate 下的操作 原理就是 在 App 進入后臺后 在 主window上添加一個 UIVisualEffectView 在進入前臺后移除 直接上代碼: 先聲明: //先聲明 /* blurView */ property (strong, nonatomic) UI…

逆波蘭表達式求解計算器

利用逆波蘭表達式求解計算器有以下幾個步驟: 1. 去掉字符串中的空格 s s.replaceAll(" ", "")2. 講字符串轉換為中序表達式數組 def string_to_infixlist(s):ans []keep_num ""for i in range(len(s)):if s[i].isdigit():if i < len(s)…

docker學習(四、修改容器創建新的鏡像推送到云上)

鏡像是只讀的&#xff0c;容器是可編輯的。Docker鏡像是分層的&#xff0c;支持通過擴展鏡像&#xff0c;創建新的鏡像。 學到這里感覺docker跟git很想~~ 通過docker commit將修改的容器做成新的鏡像 # 將容器做成新的鏡像 docker commit -m"提交備注" -a"作…

【1day】泛微e-office OA系統sms_page.php接口SQL 注入漏洞學習

注:該文章來自作者日常學習筆記,請勿利用文章內的相關技術從事非法測試,如因此產生的一切不良后果與作者無關。 目錄 一、漏洞描述 二、影響版本 三、資產測繪 四、漏洞復現

大創項目推薦 交通目標檢測-行人車輛檢測流量計數 - 大創項目推薦

文章目錄 0 前言1\. 目標檢測概況1.1 什么是目標檢測&#xff1f;1.2 發展階段 2\. 行人檢測2.1 行人檢測簡介2.2 行人檢測技術難點2.3 行人檢測實現效果2.4 關鍵代碼-訓練過程 最后 0 前言 &#x1f525; 優質競賽項目系列&#xff0c;今天要分享的是 &#x1f6a9; 畢業設計…

什么是Nginx反向代理?Nginx反向代理配置指南

Nginx反向代理是一種常見的服務器架構模式&#xff0c;它可以將客戶端請求轉發到多個后端服務器上&#xff0c;從而實現負載均衡、高可用性和安全性。本文將介紹Nginx反向代理的基本概念和配置方法。 什么是Nginx反向代理&#xff1f; 在傳統的Web服務器架構中&#xff0c;客戶…

解決selenium使用.get()報錯:unknown error: unsupported protocol

解決方法 將原來的&#xff1a; url "https://www.baidu.com" browser.get(url)替換為&#xff1a; url "https://www.baidu.com" browser.execute_script(f"window.location.replace({url});") # 直接平替 .get()問題解析 之前運行都是正…

【后端學前端學習記錄】學習計劃

1、個人背景 寫了足夠久的后端了&#xff0c;常用的語言基本上都接觸過&#xff0c;沒有在工作中寫過前端 一直想做一些前端的工作&#xff0c;但是前端技能不足加上自己審美不行&#xff0c;寫出的界面總是很丑 所以一直對前端做不好&#xff0c;也沒有真正下手。 2、動機 種…

Navicat 技術指引 | 連接 GaussDB 分布式

Navicat Premium&#xff08;16.3.3 Windows 版或以上&#xff09;正式支持 GaussDB 分布式數據庫。GaussDB 分布式模式更適合對系統可用性和數據處理能力要求較高的場景。Navicat 工具不僅提供可視化數據查看和編輯功能&#xff0c;還提供強大的高階功能&#xff08;如模型、結…

SLAM ORB-SLAM2(11)單目初始化

SLAM ORB-SLAM2(11)單目初始化 1. 初始化工作1.1. 單應矩陣(Homography Matrix)1.2. 基礎矩陣(Fundamental Matrix)1.3. 本質矩陣(Essential Matrix)1.4. 初始化過程2. 業務流程2.1. 創建單目初始化器2.2. 判斷連續幀的特征點數目2.3. 在兩幀中找匹配的特征點對2.4. 估…

軟件兼容性測試:保障多樣化用戶體驗的重要功能

隨著移動設備和操作系統的快速發展&#xff0c;軟件兼容性測試變得越發重要。這項測試確保軟件在不同平臺、設備和環境下都能夠正常運行&#xff0c;提供一致而穩定的用戶體驗。下面是軟件兼容性測試中的一些關鍵功能&#xff1a; 1. 跨平臺兼容性測試 在不同操作系統上運行的軟…

【flink番外篇】1、flink的23種常用算子介紹及詳細示例(3)-window、distinct、join等

Flink 系列文章 一、Flink 專欄 Flink 專欄系統介紹某一知識點&#xff0c;并輔以具體的示例進行說明。 1、Flink 部署系列 本部分介紹Flink的部署、配置相關基礎內容。 2、Flink基礎系列 本部分介紹Flink 的基礎部分&#xff0c;比如術語、架構、編程模型、編程指南、基本的…

macOS Big Sur/Mac電腦安裝vscode顯示您沒有權限來打開應用程序‘Visual Studio Code‘ 請聯系您的電腦或網絡管理員問題修復

錯誤方法 首先我以為我的權限不足。&#xff0c;需要去用戶群組里設置。結果根本不是這個的問題。 1.在系統偏好設置->用戶與群組檢查了一下我的用戶是不是管理員 結果發現是管理員 2.根據蘋果提示&#xff0c;右鍵我的文件夾->顯示簡介->最下面的共享與權限 解鎖&…