策略【卷積層篇】| NeurIPS 2022 gnConv 遞歸門控卷積,把自注意力翻譯成一個(gè)卷積算子)
本文基于YOLOv13 官方倉(cāng)庫(kù)iMoonLab/yolov13ultralytics 8.3.63 fork實(shí)測(cè)整理Windows/CPU 全程可跑。HorNetRao et al., NeurIPS 2022的核心洞察自注意力的 q·k 加權(quán)求和本質(zhì)就是逐點(diǎn)乘門控 線性投影的遞歸——把它寫成卷積形式就是 gnConvrecursive gated convolution。輸入經(jīng) 1×1 分成查詢與門控兩路門控路過大核深度卷積后按維度切成 order 份遞歸地乘門控→升維——以普通卷積的復(fù)雜度建模高階空間交互。本文基于官方 raoyongming/HorNet 等價(jià)內(nèi)嵌替換進(jìn) v13n 的層 22P3 引導(dǎo)投影 1×1 卷積實(shí)測(cè)13,200 參數(shù)。前言卷積層篇的替換式玩法層數(shù)不變、無順移但替換對(duì)象不是下采樣而是Neck 里 P3 引導(dǎo)分支的 1×1 投影卷積層 22——它負(fù)責(zé)把 HyperACE 的引導(dǎo)特征壓到檢測(cè)分辨率是引導(dǎo)信息怎么喂給檢測(cè)頭的咽喉。gnConv 出自 NeurIPS 2022《HorNet: Efficient High-Order Spatial Interactions with Recursive Gated Convolutions》官方源碼 github.com/raoyongming/HorNet官方類名gnconv本文僅把類名規(guī)范為GnConv。本文所有數(shù)據(jù)均在 v13n 上實(shí)測(cè)。專欄目錄YOLOv13改進(jìn)目錄一覽專欄地址YOLOv13改進(jìn)專欄——持續(xù)更新各方向即插即用改進(jìn)一、替換點(diǎn)分析head: ... - [-1, 2, DSC3k2, [256, True]] # 21 主干 P3 分支 - [10, 1, Conv, [256, 1, 1]] # 22 ← 本文替換這一層 - [[21, 22], 1, FullPAD_Tunnel, []] # 23 ...層數(shù)不變無順移。層 22 的輸入輸出都是 64 通道width0.25 縮放后——gnConv 是保形算子輸出通道輸入通道嚴(yán)絲合縫。原層是 1×1 卷積8,320 參數(shù)零空間感受野gnConv 內(nèi)置 7×7 深度卷積 遞歸門控的高階交互替換后該路徑的空間建模能力大幅增強(qiáng)參數(shù)只增加 13,200。FullPAD 的 [21, 22] 引用、Detect 的引用全部原樣可用。二、gnConv 原理速覽自注意力的卷積翻譯自注意力 q·k 相似度加權(quán) v 的求和。HorNet 指出這等價(jià)于用 k 的函數(shù)門控 v、再用線性層混合的遞歸形式——于是用卷積件替換注意力件投影分叉1×1 卷積把輸入升到 2C切成pwa查詢C/16與abc被門控特征其余門控路abc 過 7×7深度卷積空間交互后按維度切成 order 份維度從 C/16 逐級(jí)到 C/2遞歸門控x pwa * dw_1x pw_i(x) * dw_{i1}循環(huán) order-1 次——每輪乘一份門控 → 1×1 升維order5 時(shí)實(shí)現(xiàn)五階空間交互輸出投影1×1 卷積回到 C為什么強(qiáng)高階交互多輪乘法門控讓特征之間的依賴從二階普通注意力擴(kuò)展到五階而全部計(jì)算都是深度卷積 1×1——沒有 softmax、沒有 (HW)2 矩陣分辨率越高越劃算保形模塊輸出通道輸入通道注冊(cè)走只需輸入通道數(shù)的分支yaml 寫[]要求通道能被 2^(order-1)16 整除。三、實(shí)現(xiàn)代碼官方 raoyongming/HorNet 的gnconv等價(jià)內(nèi)嵌僅去掉 gflayer 分支與打印、forward 收斂為單輸入簽名已做同權(quán)重輸出逐位比對(duì)max diff 0import torch import torch.nn as nn def get_dwconv(dim, kernel, bias): return nn.Conv2d(dim, dim, kernel_sizekernel, padding(kernel - 1) // 2, biasbias, groupsdim) class GnConv(nn.Module): gnConv 遞歸門控卷積 (Rao et al., NeurIPS 2022, HorNet)官方 raoyongming/HorNet 的 gnconv 等價(jià)內(nèi)嵌僅去掉 gflayer 分支與打印、 forward 收斂為單輸入簽名官方類名 gnconv此處僅規(guī)范命名便于 yaml 調(diào)用。 把自注意力的 q·k 加權(quán)求和翻譯成卷積1×1 投影出 pwa查詢與 abc 被門控特征abc 經(jīng) 7×7 深度卷積后按維度切成 order 份然后遞歸地 乘上門控 → 1×1 升維 → 再乘下一份門控——以遠(yuǎn)低于注意力的代價(jià)實(shí)現(xiàn) 高階空間交互。要求 channel 能被 2^(order-1) 整除。 保形模塊輸入輸出同形狀。 def __init__(self, dim, order5, s1.0): super().__init__() self.order order self.dims [dim // 2 ** i for i in range(order)] self.dims.reverse() assert dim % 2 ** (order - 1) 0, channel 必須能被 2^(order-1) 整除 self.proj_in nn.Conv2d(dim, 2 * dim, 1) self.dwconv get_dwconv(sum(self.dims), 7, True) self.proj_out nn.Conv2d(dim, dim, 1) self.pws nn.ModuleList( [nn.Conv2d(self.dims[i], self.dims[i 1], 1) for i in range(order - 1)] ) self.scale s def forward(self, x): fused_x self.proj_in(x) pwa, abc torch.split(fused_x, (self.dims[0], sum(self.dims)), dim1) dw_abc self.dwconv(abc) * self.scale dw_list torch.split(dw_abc, self.dims, dim1) x pwa * dw_list[0] for i in range(self.order - 1): x self.pws[i](x) * dw_list[i 1] x self.proj_out(x) return x注意簽名是保形風(fēng)格yaml 寫[]parse_model 自動(dòng)注入 c1注冊(cè)走只需輸入通道數(shù)的分支。四、添加步驟v13 版1. 修改ultralytics/nn/modules/conv.pyget_dwconv函數(shù)與GnConv類粘貼到 conv.py 末尾。2. 修改ultralytics/nn/modules/__init__.pyfrom .conv import (...)里追加GnConv,__all__里給最后一項(xiàng)DSConv補(bǔ)逗號(hào)后追加GnConv。3. 修改ultralytics/nn/tasks.py頂部導(dǎo)入塊加GnConvparse_model()里新增分支保形模塊yaml 寫[]通道數(shù)自動(dòng)注入elif m is GnConv: # GnConv保形模塊只需輸入通道數(shù) args.insert(0, ch[f])插入位置elif m is FullPAD_Tunnel:之后、else:之前。五、yaml 模型文件只改第 22 層其余與官方 yolov13.yaml 逐行一致# Ultralytics YOLOv13n GnConv 遞歸門控卷積 nc: 80 scales: n: [0.50, 0.25, 1024] s: [0.50, 0.50, 1024] l: [1.00, 1.00, 512] x: [1.00, 1.50, 512] backbone: # [from, repeats, module, args] - [-1, 1, Conv, [64, 3, 2]] # 0-P1/2 - [-1, 1, Conv, [128, 3, 2, 1, 2]] # 1-P2/4 - [-1, 2, DSC3k2, [256, False, 0.25]] # 2 - [-1, 1, Conv, [256, 3, 2, 1, 4]] # 3-P3/8 - [-1, 2, DSC3k2, [512, False, 0.25]] # 4 - [-1, 1, DSConv, [512, 3, 2]] # 5-P4/16 - [-1, 4, A2C2f, [512, True, 4]] # 6 - [-1, 1, DSConv, [1024, 3, 2]] # 7-P5/32 - [-1, 4, A2C2f, [1024, True, 1]] # 8 head: - [[4, 6, 8], 2, HyperACE, [512, 8, True, True, 0.5, 1, both]] # 9 - [-1, 1, nn.Upsample, [None, 2, nearest]] # 10 - [ 9, 1, DownsampleConv, []] # 11 - [[6, 9], 1, FullPAD_Tunnel, []] # 12 - [[4, 10], 1, FullPAD_Tunnel, []] # 13 - [[8, 11], 1, FullPAD_Tunnel, []] # 14 - [-1, 1, nn.Upsample, [None, 2, nearest]] # 15 - [[-1, 12], 1, Concat, [1]] # 16 cat backbone P4 - [-1, 2, DSC3k2, [512, True]] # 17 - [[-1, 9], 1, FullPAD_Tunnel, []] # 18 - [17, 1, nn.Upsample, [None, 2, nearest]] # 19 - [[-1, 13], 1, Concat, [1]] # 20 cat backbone P3 - [-1, 2, DSC3k2, [256, True]] # 21 - [-1, 1, GnConv, []] # 22 ★GnConv替換1×1投影卷積層數(shù)不變 - [[21, 22], 1, FullPAD_Tunnel, []] # 23 - [-1, 1, Conv, [256, 3, 2]] # 24 - [[-1, 18], 1, Concat, [1]] # 25 cat head P4 - [-1, 2, DSC3k2, [512, True]] # 26 - [[-1, 9], 1, FullPAD_Tunnel, []] # 27 - [26, 1, Conv, [512, 3, 2]] # 28 - [[-1, 14], 1, Concat, [1]] # 29 cat head P5 - [-1, 2, DSC3k2, [1024,True]] # 30 - [[-1, 11], 1, FullPAD_Tunnel, []] # 31 - [[23, 27, 31], 1, Detect, [nc]] # 32 Detect(P3, P4, P5)六、成功運(yùn)行結(jié)果yolo detect train modelyolov13n-GnConv.yaml datamydata.yaml epochs100 imgsz640 batch4Python 方式from ultralytics import YOLO model YOLO(yolov13n-GnConv.yaml).load(yolov13n.pt) model.train(datamydata.yaml, epochs100, imgsz640, batch4)本文實(shí)測(cè)YOLOv13 官方倉(cāng)庫(kù)Windows CPUv13n 結(jié)構(gòu)替換層 22基線 yolov13n: 2,494,151 parameters, 6.5 GFLOPs GnConv: 2,507,351 parameters, 6.7 GFLOPs 第22層GnConv 3 epochs completed. Results saved to runs\detect\v13_gnconv_smoke? 斷言全部通過① 適配版與官方gnconv同權(quán)重輸出逐位一致max diff 0② 第 22 層為GnConv總參數(shù)量恰為基線 13,200模塊 21,520 ? 原 1×1 卷積 8,320③model.save引用包含第 22 層FullPAD [21, 22] 消費(fèi)其輸出梯度可達(dá)無懸空層④ 層數(shù)不變整網(wǎng) 640 前向正常3 輪冒煙訓(xùn)練正常收斂。參數(shù)量分解64 通道order5部件參數(shù)量說明proj_in 1×164→1288,320分出查詢與門控兩路dwconv 7×7 深度卷積124 組6,076門控路的空間交互pws 四段 1×14→8→16→32→642,840遞歸升維proj_out 1×164→644,224輸出投影合計(jì)21,52013,200原層為 1×1 卷積 8,320模型ParamsGFLOPs說明YOLOv13n 基線2,494,1516.5官方結(jié)構(gòu)GnConv2,507,3516.7五階遞歸門控空間交互七、總結(jié)gnConv 的三點(diǎn)記憶錨注意力→卷積的翻譯乘門控 線性投影的遞歸等價(jià)于高階空間交互、order 控制階數(shù)order5 時(shí)維度按 C/16→C/8→C/4→C/2→C 遞歸升維通道需能被 16 整除、替換零感受野的 1×1 最劃算本篇替換的 P3 引導(dǎo)投影原來完全沒有空間建模能力。它與 Involution上篇同走動(dòng)態(tài)核路線Involution 逐位置生成核、交互只在 k2 鄰域內(nèi)gnConv 用遞歸門控把交互階數(shù)堆到五階——一個(gè)空間更深一個(gè)階數(shù)更高。覺得有幫助的話點(diǎn)贊收藏關(guān)注三連支持一下評(píng)論區(qū)歡迎交流你的實(shí)驗(yàn)結(jié)果~專欄目錄YOLOv13改進(jìn)目錄一覽 專欄地址YOLOv13改進(jìn)專欄——持續(xù)更新各方向即插即用改進(jìn)