
Mona(Multi-cognitive Visual Adapter)是一種新型視覺介面卡微調方法,旨在打破傳統全引數微調(full fine-tuning)在視覺識別任務中的效能瓶頸。
Mona 方法透過引入多認知視覺濾波器和最佳化輸入分佈,僅調整 5% 的骨幹網路引數,就能在例項分割、目標檢測、旋轉目標檢測等多個經典視覺任務中超越全引數微調的效果,顯著降低了適配和儲存成本,為視覺模型的高效微調提供了新的思路。

論文題目:
5%>100%: Breaking Performance Shackles of Full Fine-Tuning on Visual Recognition Tasks
論文地址:
https://arxiv.org/pdf/2408.08345
程式碼地址:
https://github.com/Leiyi-Hu/mona
作者單位:
清華、國科大、上海交大、阿里巴巴
收錄情況:
已被 CVPR 2025 接受

論文亮點
隨著現代深度學習的發展,訓練資料和模型規模的增加成為模型效能的重要增長點,但隨之而來的是模型的垂直應用和微調成本和難度的提升。
傳統全量微調需要更新模型所有引數(如 GPT-3 的 1750 億引數 ),計算成本極高。即使以早期的 BERT 為例,單卡訓練 100 萬資料也需 5-7 小時,對硬體資源和時間的要求限制了研究復現和實際應用。
同時,隨著模型引數從億級邁向萬億級,直接微調不僅成本高昂,還可能因過擬合導致效能下降。此外,多工場景下需為每個任務儲存完整模型副本,儲存成本劇增加。
引數高效微調(Parameter Efficient Fine-Tuning,PEFT)透過保持預訓練模型引數凍結,僅調整少量引數就可實現大模型在垂直應用領域的高效適配。但目前大多數 PEFT 方法,尤其是視覺領域的 PEFT 方法的效能相較於全量微調而言還存在劣勢。
Mona 透過更適合視覺訊號處理的設計以及對預訓練特徵分佈的動態最佳化在小於 5% 的引數成本下首次突破了全量微調的效能枷鎖,為視覺微調提供了新的解決方案。
本文的核心在於強調:
1. PEFT 對於視覺模型效能上限的提升(尤其是引數量較大的模型);
2. 視覺模型在全微調(尤其是少樣本情況)會存在嚴重的過擬合問題;
3. 1*LVM+n*Adapter 模式在實際業務中潛在的效能和效率優勢。
對於具體業務來說,有些用到 LVM 或者多模態大模型(如 OCR 等任務)的任務會對視覺編碼器部分進行固定或僅微調 linear 層來適應下游資料。Mona 的存在理論上可以進一步提升 LVM、多模態大模型對視覺特徵的理解和重構,尤其是對於一些少樣本 post-training 問題。

方法
Mona 包含降維、多認知視覺濾波器、啟用函式和升維等模組,並在介面卡內部加入了跳躍連線(Skip-Connections),以增強模型的適應能力。這種結構設計使得 Mona 能夠在保持高效的同時,顯著提升視覺任務的效能。

2.1 多認知視覺濾波器
Mona 方法的核心在於引入了多認知視覺濾波器,這些濾波器透過深度可分離卷積(Depth-Wise Convolution)和多尺度卷積核(3×3、5×5、7×7)來增強介面卡對視覺訊號的處理能力。
與傳統的線性介面卡不同,Mona 專門針對視覺任務設計,能夠更好地處理二維視覺特徵,透過多尺度特徵融合提升模型對視覺資訊的理解能力。
2.2 輸入最佳化
Mona 在介面卡的前端加入了分佈適配層(Scaled LayerNorm),用於調整輸入特徵的分佈。這種設計能夠最佳化從固定層傳遞過來的特徵分佈,使其更適合介面卡的處理,從而提高微調效率。

實驗結果
3.1 實驗設定
論文在多個代表性視覺任務上進行了實驗,包括:
-
例項分割(COCO)
-
語義分割(ADE20K)
-
目標檢測(Pascal VOC)
-
旋轉目標檢測(DOTA/STAR)
-
影像分類(Flowers102、Oxford-IIIT Pet、VOC2007)
實驗使用了 SwinTransformer 系列作為骨幹網路,並基於 ImageNet-22k 資料集進行預訓練。

3.2 效能對比

-
在 COCO 資料集上,Mona 方法相比全引數微調提升了 1% 的 mAP,僅調整了不到 5% 的引數。

-
在 ADE20K 資料集上,Mona 提升了 0.18% 的 mIoU,表現出色。
-
在 Pascal VOC 資料集上,Mona 提升了 3.6% 的 APbox,顯示出顯著的效能提升。

-
在旋轉目標檢測任務(DOTA/STAR)中,Mona 在多個框架下均優於其他方法。

-
在影像分類任務上,Mona 也有不俗的效能。
3.3 收斂性分析

在所有方法中, Mona 收斂速度更快,並且明顯超過了全微調。

即插即用模組
import torch.nn as nnimport torch.nn.functional as F# ---------------------------- Mona 模組 ----------------------------INNER_DIM = 64class MonaOp(nn.Module): def __init__(self, in_features): super().__init__() self.conv1 = nn.Conv2d(in_features, in_features, kernel_size=3, padding=3 // 2, groups=in_features) self.conv2 = nn.Conv2d(in_features, in_features, kernel_size=5, padding=5 // 2, groups=in_features) self.conv3 = nn.Conv2d(in_features, in_features, kernel_size=7, padding=7 // 2, groups=in_features) self.projector = nn.Conv2d(in_features, in_features, kernel_size=1, ) def forward(self, x): identity = x conv1_x = self.conv1(x) conv2_x = self.conv2(x) conv3_x = self.conv3(x) x = (conv1_x + conv2_x + conv3_x) / 3.0 + identity identity = x x = self.projector(x)return identity + xclass Mona(BaseModule): def __init__(self, in_dim, factor=4): super().__init__() self.project1 = nn.Linear(in_dim, INNER_DIM) self.nonlinear = F.gelu self.project2 = nn.Linear(INNER_DIM, in_dim) self.dropout = nn.Dropout(p=0.1) self.adapter_conv = MonaOp(INNER_DIM) self.norm = nn.LayerNorm(in_dim) self.gamma = nn.Parameter(torch.ones(in_dim) * 1e-6) self.gammax = nn.Parameter(torch.ones(in_dim)) def forward(self, x, hw_shapes=None): identity = x x = self.norm(x) * self.gamma + x * self.gammax project1 = self.project1(x) b, n, c = project1.shape h, w = hw_shapes project1 = project1.reshape(b, h, w, c).permute(0, 3, 1, 2) project1 = self.adapter_conv(project1) project1 = project1.permute(0, 2, 3, 1).reshape(b, n, c) nonlinear = self.nonlinear(project1) nonlinear = self.dropout(nonlinear) project2 = self.project2(nonlinear)return identity + project2 # ---------------------------- 插入模式 -----------------------------# 此處省略部分 Swin 元件實現,僅提供 Mona 插入模式。class SwinBlock(BaseModule):"""" Args: embed_dims (int): The feature dimension. num_heads (int): Parallel attention heads. feedforward_channels (int): The hidden dimension for FFNs. window_size (int, optional): The local window scale. Default: 7.shift (bool, optional): whether to shift window or not. Default False. qkv_bias (bool, optional): enable bias for qkv if True. Default: True. qk_scale (float | None, optional): Override default qk scale of head_dim ** -0.5 ifset. Default: None. drop_rate (float, optional): Dropout rate. Default: 0. attn_drop_rate (float, optional): Attention dropout rate. Default: 0. drop_path_rate (float, optional): Stochastic depth rate. Default: 0. act_cfg (dict, optional): The config dict of activation function. Default: dict(type='GELU'). norm_cfg (dict, optional): The config dict of normalization. Default: dict(type='LN'). with_cp (bool, optional): Use checkpoint or not. Using checkpoint will save some memory while slowing down the training speed. Default: False. init_cfg (dict | list | None, optional): The init config. Default: None.""" def __init__(self, embed_dims, num_heads, feedforward_channels, window_size=7, shift=False, qkv_bias=True, qk_scale=None, drop_rate=0., attn_drop_rate=0., drop_path_rate=0., act_cfg=dict(type='GELU'), norm_cfg=dict(type='LN'), with_cp=False, init_cfg=None): super(SwinBlock, self).__init__() self.init_cfg = init_cfg self.with_cp = with_cp self.norm1 = build_norm_layer(norm_cfg, embed_dims)[1] self.attn = ShiftWindowMSA( embed_dims=embed_dims, num_heads=num_heads, window_size=window_size, shift_size=window_size // 2 if shift else 0, qkv_bias=qkv_bias, qk_scale=qk_scale, attn_drop_rate=attn_drop_rate, proj_drop_rate=drop_rate, dropout_layer=dict(type='DropPath', drop_prob=drop_path_rate), init_cfg=None) self.norm2 = build_norm_layer(norm_cfg, embed_dims)[1] self.ffn = FFN( embed_dims=embed_dims, feedforward_channels=feedforward_channels, num_fcs=2, ffn_drop=drop_rate, dropout_layer=dict(type='DropPath', drop_prob=drop_path_rate), act_cfg=act_cfg, add_identity=True, init_cfg=None) self.mona1 = Mona(embed_dims, 8) self.mona2 = Mona(embed_dims, 8) def forward(self, x, hw_shape): def _inner_forward(x): identity = x x = self.norm1(x) x = self.attn(x, hw_shape) x = x + identity x = self.mona1(x, hw_shape) identity = x x = self.norm2(x) x = self.ffn(x, identity=identity) x = self.mona2(x, hw_shape) return x if self.with_cp and x.requires_grad: x = cp.checkpoint(_inner_forward, x) else: x = _inner_forward(x) return x

結論
Mona 方法透過多認知視覺濾波器和輸入最佳化,顯著提升了視覺任務的微調效能,同時大幅減少了引數調整量。這一方法不僅在多個視覺任務中超越了傳統全引數微調,還為未來視覺模型的高效微調提供了新的方向。
預印版期間,Mona 已被複旦、中科大、南大、武大等多家單位的工作視為 SOTA 方法運用在醫學、遙感等領域。Mona 的開原始碼將進一步推動這一領域的研究和應用。

引用格式
@misc{yin20245100breakingperformanceshackles, title={5%>100%: Breaking Performance Shackles of Full Fine-Tuning on Visual Recognition Tasks}, author={Dongshuo Yin and Leiyi Hu and Bin Li and Youqun Zhang and Xue Yang}, year={2024}, eprint={2408.08345}, archivePrefix={arXiv}, primaryClass={cs.CV}, url={https://arxiv.org/abs/2408.08345}, }
更多閱讀

#投 稿 通 道#
讓你的文字被更多人看到
如何才能讓更多的優質內容以更短路徑到達讀者群體,縮短讀者尋找優質內容的成本呢?答案就是:你不認識的人。
總有一些你不認識的人,知道你想知道的東西。PaperWeekly 或許可以成為一座橋樑,促使不同背景、不同方向的學者和學術靈感相互碰撞,迸發出更多的可能性。
PaperWeekly 鼓勵高校實驗室或個人,在我們的平臺上分享各類優質內容,可以是最新論文解讀,也可以是學術熱點剖析、科研心得或競賽經驗講解等。我們的目的只有一個,讓知識真正流動起來。
📝 稿件基本要求:
• 文章確係個人原創作品,未曾在公開渠道發表,如為其他平臺已發表或待發表的文章,請明確標註
• 稿件建議以 markdown 格式撰寫,文中配圖以附件形式傳送,要求圖片清晰,無版權問題
• PaperWeekly 尊重原作者署名權,並將為每篇被採納的原創首發稿件,提供業內具有競爭力稿酬,具體依據文章閱讀量和文章質量階梯制結算
📬 投稿通道:
• 投稿郵箱:[email protected]
• 來稿請備註即時聯絡方式(微信),以便我們在稿件選用的第一時間聯絡作者
• 您也可以直接新增小編微信(pwbot02)快速投稿,備註:姓名-投稿

△長按新增PaperWeekly小編
🔍
現在,在「知乎」也能找到我們了
進入知乎首頁搜尋「PaperWeekly」
點選「關注」訂閱我們的專欄吧
·
