init commit
This commit is contained in:
258
_research/SECTION_mona.md
Normal file
258
_research/SECTION_mona.md
Normal file
@@ -0,0 +1,258 @@
|
||||
# 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)).
|
||||
Reference in New Issue
Block a user