# Mona-layer (Multi-cognitive Visual Adapter) — adapter-based PEFT для зрения > Источники: статья [Yin, Hu, Li, Zhang, Yang — «5%>100%: Breaking Performance Shackles of Full Fine-Tuning on Visual Recognition Tasks», arXiv:2408.08345 (CVPR 2025)](https://arxiv.org/abs/2408.08345); официальная реализация [GitHub Leiyi-Hu/mona](https://github.com/Leiyi-Hu/mona). > Все формулы блока и псевдокод ниже выверены по файлу [`swin_transformer_mona.py`](https://raw.githubusercontent.com/Leiyi-Hu/mona/master/Swin-Transformer-Classification/mmcls/models/backbones/swin_transformer_mona.py) (классы `Mona` и `MonaOp`). --- ## 1. Проблема: full fine-tuning против PEFT Классическая схема переноса — *pre-train & fine-tune*: большой backbone обучается на крупном корпусе (ImageNet-21k, LVD-142M и т.п.), затем **все** его веса дообучаются на целевой задаче. На больших целевых датасетах это работает, но имеет два дефекта на **малых** данных: - **Стоимость.** Для Swin-L это ~198M обучаемых параметров и отдельная полная копия весов на каждую задачу/чекпойнт ([Yin et al., 2024](https://arxiv.org/abs/2408.08345)). - **Переобучение.** При малом числе примеров обновление всех параметров подгоняет backbone под шум обучающей выборки; обобщение падает. **PEFT (parameter-efficient fine-tuning, она же delta-tuning)** решает обе проблемы: backbone **заморожен** ($\nabla_\theta = 0$), обучается лишь малая доля новых параметров $\Delta$ (обычно 0.1–5 %). Семейства PEFT: | Семейство | Что обучается | Представитель | |-----------|---------------|---------------| | Bias-tuning | только bias-векторы | BitFit | | Low-rank | низкоранговые добавки $BA$ к линейным слоям | LoRA | | Adapter (последовательный) | bottleneck-MLP внутри блока | Houlsby Adapter, AdaptFormer | | Prompt-tuning | обучаемые prompt-токены на входе | VPT | | Side-tuning | внешняя «боковая» сеть | LST | Главная претензия статьи Mona: до неё **ни один visual delta-tuning не превосходил full fine-tuning на сложных плотных задачах** (detection, segmentation). Mona — первый метод, который это делает на всех протестированных задачах ([arXiv:2408.08345, abstract](https://arxiv.org/abs/2408.08345)). --- ## 2. Что такое Mona-блок Mona — это **последовательный adapter** (вставляется в residual-ветку трансформерного блока), но с двумя ключевыми отличиями от языковых адаптеров: 1. **Multi-cognitive фильтры** — внутри bottleneck стоят не линейные слои, а набор **depth-wise свёрток разных масштабов** (3×3, 5×5, 7×7), которые усредняются. Это даёт «vision-friendly» обработку (локальность, разные рецептивные поля). 2. **Scaled LayerNorm на входе** — нормализация с **двумя обучаемыми покомпонентными масштабами** $\gamma$ и $\gamma_x$, регулирующая распределение признаков перед визуальными фильтрами. ### 2.1. Структура (по реализации) Внутренний модуль `MonaOp` (multi-scale conv-агрегатор), работает на тензоре $z \in \mathbb{R}^{B\times C_b\times H\times W}$ с $C_b = 64$ (bottleneck), все свёртки **depth-wise** (`groups = C_b`): $$ \mathrm{MonaOp}(z) = z' + \mathrm{Proj}_{1\times1}(z'),\qquad z' = \frac{\mathrm{DW}_{3}(z) + \mathrm{DW}_{5}(z) + \mathrm{DW}_{7}(z)}{3} + z $$ где $\mathrm{DW}_{k}$ — depth-wise conv с ядром $k\times k$ и padding $k//2$, $\mathrm{Proj}_{1\times1}$ — pointwise conv $1\times1$. Обе агрегации обёрнуты в residual. Внешний модуль `Mona` (вход — последовательность токенов $x \in \mathbb{R}^{B\times N\times C}$, $N = H\cdot W$): $$ \hat{x} = \mathrm{LayerNorm}(x)\odot \gamma + x \odot \gamma_x \qquad\text{(scaled norm, обучаемые } \gamma,\gamma_x\in\mathbb{R}^{C}) $$ $$ u = W_{\text{down}}\,\hat{x} \in \mathbb{R}^{B\times N\times 64}\quad\text{(down-projection, Linear } C\to 64) $$ $$ u' = \mathrm{MonaOp}\big(\mathrm{reshape}(u)\big)\quad\text{(токены} \to \text{карта } H\times W \to \text{токены)} $$ $$ y = W_{\text{up}}\,\mathrm{Dropout}\big(\mathrm{GELU}(u')\big)\in\mathbb{R}^{B\times N\times C}\quad\text{(up-projection, Linear } 64\to C) $$ $$ \boxed{\;\mathrm{Mona}(x) = x + y\;}\quad\text{(внешний residual)} $$ Инициализация масштабов в коде: $\gamma = 10^{-6}\cdot\mathbf{1}$ (LayerNorm-ветка стартует почти «выключенной»), $\gamma_x = \mathbf{1}$ (тождественный проброс входа). Это делает Mona при инициализации **близкой к identity** — стабильный старт для дообучения. > Замечание по терминологии: «scaled LayerNorm» здесь = `LayerNorm(x)*γ + x*γx`, то есть **выпуклоподобная** смесь нормированного и исходного признака с обучаемыми покомпонентными весами, а не нормировка с фиксированным множителем. --- ## 3. Куда вставляется и сколько добавляет В Swin-блоке Mona вставляется **дважды на каждый трансформерный блок** — после attention-ветки и после FFN-ветки (см. `SwinTransformerBlock.forward`): ``` shortcut → (W-MSA/SW-MSA) → x = shortcut + drop_path(x) x = Mona_1(x, (H,W)) # adapter после attention identity = x; x = norm2(x); x = MLP(x) x = identity + drop_path(x) x = Mona_2(x, (H,W)) # adapter после FFN ``` - **Замороженным остаётся весь backbone** (attention, MLP, patch-merging, embeddings). Обучаются: параметры всех `Mona`-модулей (down/up Linear, 3 depth-wise conv + 1×1 projector, $\gamma$, $\gamma_x$) и task-head/decoder. - **Доля обучаемых параметров backbone:** ~**2.56 %** на Swin-L и ~**4.67 %** на Swin-B (см. таблицы §4) ([arXiv:2408.08345, Tables](https://arxiv.org/abs/2408.08345)). Bottleneck фиксирован на 64 каналов, поэтому стоимость adapter не растёт квадратично с $C$. --- ## 4. Результаты статьи Сравнение проведено на Swin-B/Swin-L (ImageNet-21k pre-train) против full fine-tuning и набора PEFT. Ниже — выверенные числа из [arXiv:2408.08345](https://arxiv.org/html/2408.08345v1). ### 4.1. COCO instance segmentation (Cascade Mask R-CNN, Swin-B) | Метод | Обуч. параметры | % | AP$_{box}$ | AP$_{mask}$ | |-------|------------------|------|-----------|-------------| | Full fine-tuning | 89.14M | 100.0 | 52.40 | 45.10 | | Fixed (frozen) | 0M | 0.0 | 48.00 | 41.60 | | BitFit | 0.21M | 0.23 | 50.10 | 43.60 | | LoRA | 3.06M | 3.43 | 50.40 | 43.90 | | Adapter (Houlsby) | 3.19M | 3.58 | 52.10 | 45.00 | | AdaptFormer | 1.60M | 1.79 | 51.70 | 44.60 | | **Mona** | **4.16M** | **4.67** | **53.40** | **46.00** | ### 4.2. ADE20K semantic segmentation (UperNet, Swin-L) | Метод | Обуч. параметры | % | mIoU | |-------|------------------|------|------| | Full fine-tuning | 198.58M | 100.0 | 51.18 | | Fixed | 0M | 0.0 | 46.84 | | BitFit | 0.30M | 0.15 | 48.37 | | LoRA | 4.57M | 2.31 | 50.34 | | Adapter | 4.61M | 2.33 | 50.78 | | AdaptFormer | 2.34M | 1.18 | 50.83 | | **Mona** | **5.08M** | **2.56** | **51.36** | ### 4.3. Pascal VOC detection (RetinaNet, Swin-L) и DOTA oriented (Oriented R-CNN, Swin-B) | Метод | VOC AP$_{box}$ | DOTA mAP | |-------|----------------|----------| | Full fine-tuning | 83.70 | 78.31 | | BitFit | 85.40 | 76.05 | | LoRA | 85.40 | 75.91 | | Adapter | 86.70 | 78.27 | | AdaptFormer | 86.60 | 77.43 | | **Mona** | **87.30** | **78.44** | ### 4.4. Image classification (Swin-L, усреднение по датасетам) | Метод | Top-1 Acc | Top-5 Acc | |-------|-----------|-----------| | Full fine-tuning | 92.79 | 98.81 | | BitFit | 93.51 | 99.69 | | LoRA | 93.47 | 99.69 | | Adapter | 93.99 | 99.61 | | AdaptFormer | 93.70 | 99.65 | | **Mona** | **94.04** | **99.76** | ### 4.5. Почему «5 % > 100 % full FT» - На **плотных** задачах (detection, segmentation) full FT — сильный baseline, и линейные PEFT (LoRA, BitFit, AdaptFormer) его **не достают**. Mona обходит full FT на всех задачах: +1.0 AP$_{box}$ / +0.9 AP$_{mask}$ на COCO, +0.18 mIoU на ADE20K, +3.6 AP на VOC. - Причина: **conv-фильтры разных масштабов** дают индуктивное смещение, подходящее под изображения (локальность, многомасштабность), которого нет у линейных адаптеров; а **заморозка backbone** регуляризует — на малых данных полная подгонка переобучается, а 5 % параметров «достаточно гибки, но не настолько, чтобы запомнить шум». --- ## 5. Mona vs LoRA vs обычный Adapter | Критерий | LoRA | Adapter (Houlsby) | **Mona** | |----------|------|-------------------|----------| | Куда вставляется | добавка $\Delta W = \frac{\alpha}{r}BA$ к линейным слоям (q,v) | bottleneck-MLP внутри блока | bottleneck **с conv** в residual-ветке (после attn и после FFN) | | Внутренние операторы | две линейные матрицы $A,B$ | down-Linear → нелинейность → up-Linear | down-Linear → **3× depth-wise conv (3/5/7) + 1×1** → GELU → up-Linear | | Учёт пространства | нет (работает потокенно) | нет | **да** (reshape в карту $H\times W$, multi-scale свёртки) | | Нормализация входа | нет | обычно нет | **scaled LayerNorm** с обучаемыми $\gamma,\gamma_x$ | | Слияние в инференсе | можно слить в веса (zero-cost) | нет (доп. слой) | нет (доп. слой) | | Сильная сторона | дёшево, мерджится | универсален | **vision-friendly, превосходит full FT на dense-задачах** | | Доля параметров | ~2–3 % | ~2.3–3.6 % | ~2.5–4.7 % | Ключевое отличие: LoRA и Houlsby-Adapter оперируют **только линейными** преобразованиями признаков и не используют 2D-структуру; Mona добавляет **визуальное индуктивное смещение** (multi-scale depth-wise conv) и **adaptive scaled norm**, поэтому выигрывает именно на изображениях. --- ## 6. Минимальный PyTorch-скелет Mona Рабочий минимум, эквивалентный официальному коду (`bottleneck=64` по умолчанию, как в репозитории; здесь параметризован). ```python import torch import torch.nn as nn import torch.nn.functional as F class MonaOp(nn.Module): """Multi-cognitive conv aggregator: depthwise 3x3/5x5/7x7 + 1x1 projector.""" def __init__(self, dim: int): super().__init__() self.conv1 = nn.Conv2d(dim, dim, 3, padding=1, groups=dim) # depthwise 3x3 self.conv2 = nn.Conv2d(dim, dim, 5, padding=2, groups=dim) # depthwise 5x5 self.conv3 = nn.Conv2d(dim, dim, 7, padding=3, groups=dim) # depthwise 7x7 self.projector = nn.Conv2d(dim, dim, 1) # pointwise 1x1 def forward(self, x): # x: (B, dim, H, W) identity = x x = (self.conv1(x) + self.conv2(x) + self.conv3(x)) / 3.0 + identity identity = x return identity + self.projector(x) # second residual class Mona(nn.Module): """Multi-cognitive visual adapter (Yin et al., CVPR 2025).""" def __init__(self, in_dim: int, bottleneck: int = 64): super().__init__() self.norm = nn.LayerNorm(in_dim) self.gamma = nn.Parameter(torch.ones(in_dim) * 1e-6) # scaled-norm branch self.gammax = nn.Parameter(torch.ones(in_dim)) # identity branch self.project1 = nn.Linear(in_dim, bottleneck) # down-projection self.adapter_conv = MonaOp(bottleneck) # multi-scale conv self.nonlinear = F.gelu self.dropout = nn.Dropout(0.1) self.project2 = nn.Linear(bottleneck, in_dim) # up-projection def forward(self, x, hw_shape): # x: (B, N, C), hw_shape=(H, W) identity = x x = self.norm(x) * self.gamma + x * self.gammax # scaled LayerNorm u = self.project1(x) # (B, N, bottleneck) b, n, c = u.shape h, w = hw_shape u = u.reshape(b, h, w, c).permute(0, 3, 1, 2) # -> (B, c, H, W) u = self.adapter_conv(u) u = u.permute(0, 2, 3, 1).reshape(b, n, c) # -> (B, N, c) u = self.dropout(self.nonlinear(u)) return identity + self.project2(u) # outer residual ``` Вставка в трансформерный блок (frozen backbone, обучается только Mona): ```python # внутри SwinBlock.forward после attention и после FFN: x = shortcut + drop_path(attn_out) x = mona_after_attn(x, (H, W)) x = x + drop_path(mlp_out) x = mona_after_ffn(x, (H, W)) ``` --- ## 7. Применимость к маленькому датасету Naruto Sign на EdgeNeXt Naruto Sign (распознавание ручных «печатей»/жестов) — **малый** датасет, EdgeNeXt — компактный backbone. Здесь Mona особенно уместен: - **Снижение переобучения.** Backbone EdgeNeXt замораживается (предобученные веса сохраняют общие визуальные признаки), обучается лишь ~2.5–5 % параметров — меньше степеней свободы → меньше шансов запомнить шум малой выборки. - **Доменная адаптация через conv.** Жесты рук — локальные многомасштабные паттерны (пальцы, контуры). Multi-scale depth-wise свёртки (3/5/7) подстраивают предобученные признаки под этот домен лучше линейных адаптеров. - **Дёшево по памяти.** Хранится один frozen backbone + лёгкие Mona-веса; для edge-сценария это критично. > Замечание по совместимости: EdgeNeXt — гибрид conv+SDTA, а не чистый Swin. Mona-блок (`Mona`/`MonaOp`) переносим почти без изменений: ему нужны лишь токенизированные признаки `(B, N, C)` + `(H, W)` для reshape, либо его можно применять прямо к feature-map `(B, C, H, W)`, опустив permute. Точку вставки (после каждой стадии / после SDTA-блоков) выносим в гиперпараметры. ### Гиперпараметры для Optuna | Гиперпараметр | Диапазон / варианты поиска | Комментарий | |---------------|----------------------------|-------------| | `bottleneck` (down-dim) | {16, 32, 64, 96} | меньше → сильнее регуляризация, дешевле | | набор ядер conv | {(3), (3,5), (3,5,7), (5,7)} | trade-off рецептивное поле vs параметры | | агрегация ветвей | {mean, learnable-weighted sum} | взвешенная сумма даёт ещё ~$k$ обучаемых скаляров | | init `gamma` | {1e-6, 1e-4, 1e-2} | насколько «включена» scaled-norm-ветка на старте | | init `gammax` | {1.0, 0.5} | сила identity-проброса | | dropout в bottleneck | [0.0, 0.3] | регуляризация под малый датасет | | стадии вставки | подмножество {stage1..stage4} | в ранние/поздние стадии или только в часть | | позиции в блоке | {after-attn, after-ffn, both} | both = как в оригинале | | LR для Mona-параметров | log-uniform [1e-4, 5e-3] | adapter-веса часто требуют LR выше backbone | | `weight_decay` Mona | log-uniform [1e-5, 1e-2] | — | Эмпирическое правило (из статьи): на малых/плотных задачах лучше вставлять Mona **во все стадии и обе позиции** (after-attn + after-ffn); сокращать набор ядер до (3,5) или bottleneck до 32 имеет смысл, если Optuna показывает переобучение или упор в бюджет параметров. --- ## Источники - [Yin D., Hu L., Li B., Zhang Y., Yang X. «5%>100%: Breaking Performance Shackles of Full Fine-Tuning on Visual Recognition Tasks». arXiv:2408.08345, 2024 (CVPR 2025)](https://arxiv.org/abs/2408.08345) — [HTML-версия](https://arxiv.org/html/2408.08345v1). - [Официальная реализация — GitHub Leiyi-Hu/mona](https://github.com/Leiyi-Hu/mona); исходник блока — [`swin_transformer_mona.py`](https://raw.githubusercontent.com/Leiyi-Hu/mona/master/Swin-Transformer-Classification/mmcls/models/backbones/swin_transformer_mona.py). - PEFT-baselines: LoRA ([Hu et al., 2021, arXiv:2106.09685](https://arxiv.org/abs/2106.09685)); Adapter/Houlsby ([Houlsby et al., 2019, arXiv:1902.00751](https://arxiv.org/abs/1902.00751)); AdaptFormer ([Chen et al., 2022, arXiv:2205.13535](https://arxiv.org/abs/2205.13535)); VPT ([Jia et al., 2022, arXiv:2203.12119](https://arxiv.org/abs/2203.12119)); BitFit ([Zaken et al., 2021, arXiv:2106.10199](https://arxiv.org/abs/2106.10199)).