40 KiB
type, status, date, component, supervisor, task_type, topic, model, dataset, tools, related, tags, author
| type | status | date | component | supervisor | task_type | topic | model | dataset | tools | related | tags | author | |||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| protocol | draft | 2026-06-26 | backbone | мнс Павленко Б.В. | student-research | hyperparameter-optimization | EdgeNeXt | Naruto Sign |
|
|
|
claude |
PROTOCOL: Подбор гиперпараметров для классификации изображений (EdgeNeXt × Naruto Sign × Optuna)
Учебно-исследовательская методичка для студента под руководством мнс Павленко Б.В. Тема: оптимизация/подбор гиперпараметров (HPO) для задачи классификации изображений на наборе Naruto Sign с компактным энкодером визуальных признаков EdgeNeXt. Сквозные инструменты: Optuna (поиск), timm (модель), UMAP (анализ признаков). Дополнительно изучаются заморозка / частичная заморозка / MONA-адаптер как точки на оси «ёмкость адаптации ↔ риск переобучения», подбираемые наравне с прочими гиперпараметрами.
§0. TL;DR
| Что | Решение |
|---|---|
| Цель | Освоить и применить методы HPO: на малом датасете Naruto Sign подобрать гиперпараметры дообучения EdgeNeXt так, чтобы максимизировать macro-F1 на валидации, и обосновать выбор экспериментально |
| Энкодер (фикс. семейство) | EdgeNeXt (timm): edgenext_xx_small.in1k (1.3M) / edgenext_x_small.in1k (2.3M) / edgenext_small.usi_in1k (5.6M), ImageNet-pretrained — вариант сам по себе является гиперпараметром |
| Датасет | Naruto Sign — классификация ручных печатей. Verified (сиблинг-трек, см. §3): 13 классов (12 печатей + zero), ~2245 изобр. (train 2159 / test 86, val нет), PNG+JPG, лицензия «Unknown». Источник — Kaggle vikranthkanumuru (ImageFolder). Числа пересчитать после скачивания |
| Режимы переноса | full (full fine-tuning) · partial (разморозить последние n стадий, n=0 ⇒ linear probing) · mona (frozen backbone + Conv-MONA адаптеры, PEFT) |
| Поиск | Optuna, default = TPESampler(multivariate=True) + MedianPruner/HyperbandPruner; затем multi-objective (NSGAIISampler): macro-F1 ↑ vs trainable-params ↓ |
| Главная метрика | macro-F1 (валидация). Доп.: balanced accuracy, top-1, MCC, confusion matrix. При дисбалансе accuracy — вводит в заблуждение |
| Анализ данных | Статистика датасета + UMAP эмбеддингов EdgeNeXt, раскраска по классам, кластеризация на промежуточном (10–20-мерном) вложении, ARI/NMI/silhouette → предсказание «трудных» классов |
| Гипотезы | H1 (TPE+pruning ≫ random/grid при равном бюджете) · H2 (оптимум — partial freeze, не full FT и не linear probing) · H3 (MONA ≥ full FT при <5% параметров) · H4 (loss/sampler против дисбаланса ↑ macro-F1) · H5 (multi-objective находит Pareto-лучшие edge-конфигурации) · H6 (UMAP-перекрытие классов предсказывает ошибки) — см. §8 |
| Численные эксперименты | B0 baseline → E1 ablation режимов → E2 Optuna single-objective → E3 Optuna multi-objective → E4 UMAP-анализ → (опц.) E5 sampler/random vs TPE — см. §9 |
| Сроки | 14 дней (MVP ~8–10 дней): рабочий честный baseline > богатство экспериментов |
| Compute | 1×RTX 4090; EdgeNeXt малый → прогон минуты; десятки trial-ов Optuna реалистичны |
§1. Контекст, цель и зачем проекту
1.1 Учебная цель
Студент осваивает полный цикл HPO на «чистой» автономной CV-задаче: (1) что такое кодирование визуальных признаков и почему backbone = feature encoder; (2) какие бывают методы подбора гиперпараметров и чем Bayesian/TPE лучше grid/random; (3) как устроена Optuna; (4) что подбирать в DL-классификации (lr, wd, loss, аугментации, глубина заморозки, PEFT); (5) как честно мерить качество при дисбалансе; (6) как анализировать признаковое пространство (UMAP) и превращать наблюдения в гипотезы; (7) как провести и описать численные эксперименты.
1.2 Зачем это проекту MERIDIAN/SOFIA
Задача автономна (публичные данные, не трогает проприетарный Triple-Teacher), но методически прямо питает проект:
- EdgeNeXt — критически релевантный для SOFIA-Tiny edge-backbone (см. конспект B134_BB_2022_EdgeNeXt_Efficient_CNN-Transformer_Mobile_Vision: 256×256 вход, Jetson-деплой, 1.3–5.6M params, SDTA channel-attention). Этот эксперимент — песочница для SDTA/adaptive-kernels интуиций.
- MONA — у проекта уже есть Conv-MONA в text-encoder бенчмарке (PROTOCOL_text_encoder_benchmark_StripNet_GTA_UAV §2.1): здесь студент реализует и измеряет тот же класс PEFT на чистой классификации.
- Optuna-методология переиспользуема для всего проекта (E0–E9 recipe-tuning), а decision-rule-культура (равный бюджет, фикс. seed, p<0.05, честные caveat) — общая для практики (ПРАКТИКА_2026-07-01_задания_16_студентов §«Общие правила»).
1.3 Что НЕ изучаем
- ❌ Детекцию/сегментацию печатей (только классификация, ImageFolder→softmax).
- ❌ Архитектурный NAS (варьируем только пресет EdgeNeXt XXS/XS/S, не перестраиваем блоки).
- ❌ Дистилляцию от Teacher (это E2 MERIDIAN, не эта задача).
§2. Карта теоретических глав (читать перед экспериментами)
Подробная теория вынесена в самостоятельные главы (папка _research/). Каждая — самодостаточна, с формулами, таблицами и проверенными источниками:
| Глава | Файл | О чём |
|---|---|---|
| Кодирование признаков и EdgeNeXt | SECTION_edgenext | feature encoding, архитектура EdgeNeXt (stem/4 стадии/SDTA/adaptive kernels), варианты, timm-практика (create_model, forward_features, forward_head(pre_logits=True), resolve_model_data_config) |
| Методы HPO (таксономия) | SECTION_hpo_methods | гиперпараметры vs параметры, grid/random ([Bergstra&Bengio 2012]), Bayesian (GP/TPE/SMAC, EI/UCB), CMA-ES/PBT, multi-fidelity (Successive Halving/Hyperband/ASHA/BOHB), фреймворки, методология, типичные ошибки |
| Optuna (полный разбор) | SECTION_optuna | Study/Trial/define-by-run, samplers (TPE/GP/CMA-ES/NSGA-II/III/QMC/AutoSampler), pruners (Median/ASHA/Hyperband/...), multi-objective+constraints, v4.5/v4.6, storage, визуализация, интеграция с PyTorch, шпаргалка «sampler+pruner» |
| Заморозка / частичная заморозка | SECTION_freezing | full FT vs linear probing vs partial freeze, LP-FT ([Kumar 2022]), механика requires_grad/eval()/FrozenBN, gradual unfreezing, discriminative LR, глубина заморозки как гиперпараметр |
| MONA-layer (PEFT) | SECTION_mona | adapter-PEFT, разбор Mona ([arXiv:2408.08345], CVPR 2025) по коду репозитория Leiyi-Hu/mona: scaled-LayerNorm + MonaOp (DW 3/5/7) + down/up-proj; «5%>100% full FT»; vs LoRA/Adapter; PyTorch-скелет |
| UMAP (анализ признаков) | SECTION_umap | интуиция, PCA/t-SNE/UMAP, параметры (n_neighbors/min_dist/metric), пайплайн EdgeNeXt→UMAP, кластеризация на промежуточном вложении, ARI/NMI/AMI/silhouette, предостережения |
| Классификация: метрики/loss/sampling | SECTION_classification | softmax/top-k, метрики (macro/micro/weighted-F1, balanced acc, MCC, ECE), loss (CE/LS/Focal/Class-Balanced/LDAM/KD), семплирование (WeightedRandomSampler, mixup/cutmix), связка loss×sampler |
§3. Датасет Naruto Sign — протокол подготовки
Полное описание и источники — в SECTION_naruto_dataset.
[!info] Verified-факты (из параллельного студенческого трека под рук. Устенко В.Ю. — тот же датасет; зафиксированы в рабочей памяти проекта) Тот же Kaggle-набор
vikranthkanumuru/naruto-hand-sign-datasetуже верифицирован параллельным треком: 13 классов (12 печатей +zero/покой), 2245 изображений (train 2159 / test 86, val отсутствует), 1797 PNG + 448 JPG, реальные фото рук, лицензия «Unknown», числа из notebook 2020. Поэтому:num_classes=13по умолчанию; val нет → выделяется стратифицированно из train (реализовано вdata.py, веткаuse_predefined_split); не переоткрывать эти факты заново — только пересчитатьdataset_stats.pyпосле скачивания (числа могли измениться). Документ трека Устенко может находиться в другой ветке репозитория.
Ключевые решения протокола:
- Источник по умолчанию: Kaggle
vikranthkanumuru/naruto-hand-sign-dataset(формат ImageFolder, заточен под классификацию). Roboflow-наборы — детекционные, использовать как запасные (crop по bbox). - Сверить статистику после скачивания скриптом
dataset_stats.py: число классов (12 или 13?), всего изображений, per-class, разрешения, дисбаланс. Это первый артефакт студента — таблица статистики в отчёте. - Стратифицированный split (seed=42), доли 70/15/15. Реализация —
data.py(_stratified_indices). - Утечка из видео — главный риск честности. Кадры извлечены из видео покадрово ⇒ соседние кадры почти идентичны. Случайный per-frame split завышает метрику. Если в именах файлов есть id видео/серии — делать group-split (
StratifiedGroupKFold, см. SECTION_naruto_dataset §5). Если id нет — отметить риск в отчёте и сделать дедупликацию near-duplicate (perceptual hash). Базовыйdata.pyделает per-frame split — это допустимо для учебного MVP, но факт и риск утечки обязательно фиксируется в REPORT.md. - Размер входа — 256×256 (дефолт EdgeNeXt), нормализация ImageNet (берётся из
timm.data.resolve_model_data_config).
[!danger] Horizontal flip — отключён по умолчанию Печать — это конкретная конфигурация левой/правой руки; зеркалирование меняет семантику жеста ⇒ label noise. В
data.pyuse_hflip=Falseзафиксировано и не подаётся в Optuna. См. SECTION_naruto_dataset §6.
§4. Задача классификации — метрики, loss, семплирование (решения)
Теория — SECTION_classification. Решения протокола:
| Аспект | Решение | Обоснование |
|---|---|---|
| Главная метрика (objective Optuna) | macro-F1 на валидации | равный вес классам; accuracy при дисбалансе вводит в заблуждение |
| Сопутствующие метрики | balanced accuracy, top-1, MCC, Cohen κ, per-class F1, confusion matrix | полная картина; confusion matrix — диагностика похожих печатей |
| Loss (категориальный гиперпараметр) | {ce, ce_ls, weighted_ce, focal} |
от baseline до imbalance-aware; LS для калибровки, focal/weighted/CB для дисбаланса |
| Веса классов | effective-number ([Cui 2019], cb_beta) |
мягче, чем грубая обратная частота |
| Семплирование | WeightedRandomSampler (вкл/выкл — гиперпараметр) |
альтернатива loss-ребалансировке |
| ⚠️ Двойная компенсация | не включать weighted_ce/focal + WeightedRandomSampler одновременно с полной силой |
переусиление minority → падение precision (см. SECTION_classification §5) |
| Аугментации (гиперпараметры) | RandomResizedCrop, лёгкий rotation, color jitter, RandAugment(M), mixup(α) | mixup/RandAugment — «умный oversampling»; без hflip |
Реализация: metrics.py (sklearn), losses.py (FocalLoss, effective_number_weights, build_criterion), data.py (_make_sampler, compute_class_weights).
§5. Модель и режимы переноса (заморозка / частичная / MONA)
Теория — SECTION_edgenext, SECTION_freezing, SECTION_mona. Три режима реализованы в model.py (build_model, ModelConfig.regime):
| Режим | Что обучается | Когда ожидаемо лучше | Параметризация в Optuna |
|---|---|---|---|
full |
весь backbone + голова (2 LR-группы) | данных достаточно / домен далёк | — |
partial |
последние n_unfrozen_stages стадий + голова; n=0 ⇒ linear probing |
малый датасет, нужна частичная адаптация | n_unfrozen_stages ∈ [0,4] |
mona |
frozen backbone + Conv-MONA адаптеры + голова (PEFT, <5% весов) | малый датасет, адаптация без переобучения | mona_bottleneck, mona_kernels, mona_last_only |
Ключевые инженерные детали (см. SECTION_freezing §2):
- Замороженные параметры исключаются из optimizer (
build_param_groupsберёт толькоrequires_grad=True). - Замороженные norm-слои переводятся в
eval()каждый train-шаг (freeze_consistency) — иначе running-статистика BN «уезжает». EdgeNeXt в основном на LayerNorm (этой ловушки нет), но правило соблюдаем для гибридных модулей. - Discriminative LR: backbone получает
base_lr × backbone_lr_mult(по умолчанию 0.1), голова/адаптеры —base_lr.
MONA-адаптер (mona.py) — conv-вариант (вход [B,C,H,W]), верный коду репозитория Leiyi-Hu/mona: scaled-LayerNorm (γ·LN(x)+γx·x) → down 1×1 → MonaOp (DW 3/5/7, два residual) → GELU → up 1×1 (zero-init ⇒ старт = identity). Вставляется forward-hook'ом после выбранных стадий (число каналов определяется dry-run'ом, без зависимости от feature_info).
§6. Анализ признаков через UMAP
Теория и предостережения — SECTION_umap. Реализация — umap_analysis.py.
Пайплайн: forward_features → forward_head(pre_logits=True) → L2-норма → матрица [N,D] →
(а) UMAP→2D (раскраска по истинному классу, random_state=42, metric=cosine) для визуализации;
(б) UMAP→10–20D для кластеризации (KMeans с k=число классов) → silhouette, ARI/NMI относительно истинных меток.
Что извлечь:
- Какие печати образуют изолированные «острова» (легко различимы), какие перекрываются (Ram/Snake/Dragon — сложенные ладони).
- Сверка с confusion matrix: перекрытие в эмбеддинге ⇒ off-diagonal масса. Это валидирует, что ошибки идут от признаков, а не от головы.
- Выполнить анализ дважды: на frozen ImageNet-EdgeNeXt (до дообучения) и на лучшей дообученной модели (после) → показать, как дообучение «растягивает» классы.
[!warning] UMAP — инструмент генерации гипотез, не доказательство. Не интерпретировать абсолютные расстояния/размеры кластеров; фиксировать seed; выводы подтверждать метриками (§5 SECTION_umap).
§7. Выбор метода и настройка Optuna
Обоснование выбора метода — SECTION_hpo_methods; разбор Optuna — SECTION_optuna. Решения:
- Single-objective (E2):
TPESampler(multivariate=True, seed=42)+MedianPruner(илиHyperbandPruner, если бюджет на trial неясен). Прунинг по эпохам черезtrial.report(macro_f1, epoch)+trial.should_prune()— реализовано вtrain.py. - Multi-objective (E3):
NSGAIISamplerилиAutoSampler(OptunaHub),directions=["maximize","minimize"]= macro-F1 ↑ vs trainable-params ↓ → Pareto-фронт edge-конфигураций. - Baseline для честного сравнения метода (E5, опц.):
RandomSamplerпри равном бюджете trial-ов и том же пространстве поиска. - Storage: SQLite (
--storage) для персистентности и дашборда;gc_after_trial=True(VRAM). - Пространство поиска (define-by-run,
optuna_search.pysuggest_configs):model_name,regime(+условныеn_unfrozen/MONA-параметры),lr(log),weight_decay(log),optimizer,backbone_lr_mult(log),loss_name(+условныйfocal_gamma),label_smoothing,weighted_sampler,img_size,batch_size,mixup_alpha,rrc_scale_min,randaug_magnitude,drop_rate,drop_path_rate. - После поиска:
plot_optimization_history,plot_param_importances(fANOVA — какие гиперпараметры реально важны),plot_slice,plot_pareto_front.
[!important] Лог-шкала для
lr/weight_decayобязательна. Их эффект мультипликативен; линейный сэмплинг почти не пробует малые значения (см. SECTION_hpo_methods §8.1).
§8. Гипотезы
Формат: «Если [метод], то [результат], потому что [обоснование]». Каждую проверяем численно (§9) при равном бюджете и фикс. seed; вывод — со стат-проверкой (bootstrap-CI / 3 seed), а не по разнице в 0.1%.
| ID | Гипотеза | Проверка | Основание |
|---|---|---|---|
| H1 | Если искать TPE+pruning, то при равном бюджете trial-ов он найдёт конфиг с macro-F1 не хуже (обычно лучше) random/grid, потому что TPE моделирует \ell(\lambda)/g(\lambda) и концентрирует бюджет в перспективной зоне, а pruner отсеивает плохих рано |
E2 vs E5 (random), та же сетка, тот же бюджет | [Bergstra 2011/2012], [Akiba 2019] — SECTION_hpo_methods, SECTION_optuna |
| H2 | Если варьировать глубину заморозки, то оптимум — partial freeze (разморозить 1–2 верхние стадии), а не full FT и не linear probing, потому что на малом датасете full FT переобучается/искажает признаки (feature distortion), а linear probing не хватает ёмкости адаптации | E1 ablation (n_unfrozen ∈ {0,1,2,3,4}) + важность параметра regime/n_unfrozen в E2 |
[Kumar 2022 LP-FT], CS231n — SECTION_freezing |
| H3 | Если применить MONA (frozen backbone + адаптеры, <5% параметров), то macro-F1 ≥ full FT при многократно меньшем числе обучаемых параметров, потому что multi-scale conv-фильтры дают vision-friendly адаптацию, а заморозка регуляризует на малых данных | E1 (full vs partial vs mona) при равном бюджете; E3 Pareto (F1 vs params) |
[Yin 2024 Mona] — SECTION_mona |
| H4 | Если включить imbalance-aware loss/sampler (weighted/focal/CB или WeightedRandomSampler), то вырастет macro-F1 / balanced accuracy / recall редких классов (ценой лёгкого падения overall accuracy), потому что редкие классы получают больший вклад в обучение | E2: важность loss_name/weighted_sampler; целевой контраст на самых редких классах |
[Cui 2019], [Lin 2017] — SECTION_classification |
| H5 | Если оптимизировать multi-objective (macro-F1 ↑, trainable-params ↓), то Pareto-фронт даст edge-предпочтительные конфигурации (например MONA/partial-малый вариант) при незначимой потере F1, потому что PEFT/малые варианты EdgeNeXt дают высокую точность при низкой ёмкости | E3 (NSGAIISampler/AutoSampler), анализ plot_pareto_front |
SECTION_optuna §4, SECTION_edgenext §3 |
| H6 | Если классы перекрываются в UMAP-эмбеддинге, то именно эти пары дают наибольшую off-diagonal массу в confusion matrix, потому что ошибки классификатора порождаются неразделимостью в признаковом пространстве | E4: сверка UMAP-перекрытий с confusion matrix лучшей модели; ARI/NMI | [McInnes 2018] — SECTION_umap |
§9. План численных экспериментов и decision-rules
Все прогоны: seed=42 (финальные сравнения — 42/123/456), равный бюджет на сравниваемые конфигурации, меняется только один фактор. Эталон метрик — metrics.py.
flowchart TD
D[Naruto Sign<br/>ImageFolder] --> S[dataset_stats.py<br/>STATS.md]
D --> SP[Стратиф. split seed=42<br/>data.py]
SP --> B0[B0 baseline<br/>partial n=1, ce_ls]
B0 --> E1{E1 ablation режимов<br/>full / partial 0..4 / mona}
E1 -->|лучший режим| E2[E2 Optuna single-obj<br/>TPE + MedianPruner<br/>objective = val macro-F1]
E2 -->|best_params| FT[Финал: 3 seed<br/>+ test + bootstrap-CI]
E2 --> E3[E3 Optuna multi-obj<br/>NSGA-II: F1 up vs params down<br/>Pareto-front]
E2 -. контроль .-> E5[E5 random vs TPE<br/>равный бюджет, H1]
FT --> E4[E4 UMAP до/после<br/>2D + кластеризация<br/>ARI/NMI]
E4 --> CM[Сверка с confusion matrix<br/>H6]
E1 --> HYP[Гипотезы H2/H3]
E3 --> HYP5[Гипотеза H5]
E2 --> HYP4[Важность параметров fANOVA<br/>H4]
HYP --> R[REPORT.md<br/>вердикты H1-H6 + caveat]
HYP4 --> R
HYP5 --> R
CM --> R
| Этап | Что делаем | Команда | Артефакт | Decision-rule |
|---|---|---|---|---|
| B0 baseline | Один честный прогон partial, n=1, ce_ls, eval на test + confusion |
python -m src.run_baseline --data-root <...> --regime partial --n-unfrozen 1 |
report.json, confusion.png |
Зафиксировать baseline macro-F1, который HPO обязан побить |
| E1 ablation режимов | full vs partial(n=0..4) vs mona при равном recipe/бюджете |
run_baseline × режимы (скрипт-обёртка) |
таблица режим×(macro-F1, params), кривые | H2/H3: лучший режим; если mona≥full при <5% params — H3 поддержана |
| E2 Optuna single-obj | TPE+pruner, objective=val macro-F1, 40–80 trial | python -m src.optuna_search --data-root <...> --sampler tpe --pruner median --n-trials 60 --storage |
*_best.json, *_trials.csv, importance/history/slice png |
Лучший trial должен побить B0; зафиксировать best_params |
| E3 Optuna multi-obj | NSGA-II/AutoSampler, F1↑ vs params↓, 60–100 trial | python -m src.optuna_search --data-root <...> --multi-objective --sampler nsga --n-trials 80 |
Pareto-front png + таблица недоминируемых | H5: выбрать edge-точку (max F1 при params ≤ бюджета) |
| E4 UMAP-анализ | эмбеддинги до/после дообучения, 2D + кластеризация | python -m src.umap_analysis --data-root <...> [--checkpoint best.pt] |
umap_2d.png, cluster_report.json |
H6: сверить перекрытия с confusion matrix |
| E5 (опц.) метод-контроль | random vs TPE при равном бюджете и пространстве | --sampler random vs --sampler tpe |
кривые «best-so-far vs число trial» | H1: TPE ≥ random; вывод со стат-проверкой |
Финальная переоценка: топ-конфиг(и) из E2/E3 переобучить на 3 seed (42/123/456), сравнить по среднему ± std, оценить на test (трогается один раз) + bootstrap-CI. Только после этого делать выводы.
Абсолютные числа могут быть скромными при малом/«грязном» датасете — оценивается корректность методологии (равный бюджет, фикс. seed, отсутствие утечки, честный eval, признание caveat), а не голый macro-F1.
§10. Воспроизводимость, честность, типичные ловушки
- Seed 42 везде (
set_seedвtrain.py); финал — 3 seed. - Test трогать один раз, в самом конце; подбор — только на val (иначе утечка test в HPO).
- Не сравнивать при разном бюджете методы/конфиги; единое пространство поиска.
- Лог-шкала для lr/wd.
- Заморозка BN —
freeze_consistencyпосле каждогоmodel.train(). - Двойная компенсация дисбаланса — не включать sampler + weighted-loss одновременно на полную (см. SECTION_classification §5).
- Утечка из видео — главный риск Naruto Sign; зафиксировать в REPORT.md, при наличии id — group-split.
- UMAP — не «доказывать» кластерами; фиксировать seed, подтверждать метриками.
- Атомарная запись результатов (
os.replace),gc_after_trialдля VRAM. - Отрицательные результаты и подтверждённые caveat фиксировать явно — это плюс.
§11. Что сдаёт студент
- Код (папка
code/) сREADME.mdиrequirements.txt— запускается на чужой машине по инструкции. STATS.md— таблица статистики Naruto Sign по факту скачивания (dataset_stats.py) + источник/версия/лицензия.REPORT.md— результаты всех этапов: таблицы (B0/E1/E2/E3), кривые обучения, importance-график Optuna, Pareto-фронт, UMAP-картинки (до/после) + confusion matrix, проверка каждой гипотезы H1–H6 с вердиктом (поддержана/опровергнута/неубедительно), анализ ошибок (3–5 примеров), честные caveat.- Артефакты:
*_trials.csv,*_best.json,umap_2d.png,cluster_report.json, лучший чекпойнт + config, папка PNG.
MVP (≈8–10 дней): статистика + B0 baseline + E1 ablation 3 режимов + E2 Optuna (≥40 trial, TPE+pruner) с побитием baseline + E4 UMAP (2D + ARI) + REPORT с проверкой ≥3 гипотез. Stretch: E3 multi-objective + Pareto-анализ; E5 random vs TPE со стат-проверкой; 3-seed переоценка + bootstrap-CI; MONA-абляция (bottleneck/ядра) внутри Optuna; group-split без утечки; AutoSampler.
§12. Календарь (14 дней)
| Дни | Задача |
|---|---|
| 1–2 | Скачать датасет, dataset_stats.py, STATS.md; прочитать главы SECTION_edgenext, SECTION_classification |
| 3 | Поднять окружение (requirements.txt), smoke-тест build_model для 3 режимов; прочитать SECTION_freezing, SECTION_mona |
| 4 | B0 baseline + confusion matrix |
| 5–6 | E1 ablation режимов (full/partial 0–4/mona); таблица + кривые |
| 6 | Прочитать SECTION_hpo_methods, SECTION_optuna |
| 7–9 | E2 Optuna single-objective (TPE+pruner), importance/history/slice; побить B0 |
| 9 | E4 UMAP (до/после), сверка с confusion matrix |
| 10 | Воспроизводимый прогон зафиксирован; черновик REPORT |
| 11–12 | E3 multi-objective + Pareto (stretch); 3-seed переоценка |
| 13 | E5 random vs TPE (stretch); анализ ошибок |
| 14 | Финализация REPORT.md/README.md, графики, выводы, caveat |
§13. Карта кода (code/)
| Файл | Назначение |
|---|---|
src/data.py |
ImageFolder, стратифицированный split, transforms (hflip OFF), WeightedRandomSampler, class weights |
src/model.py |
EdgeNeXt (timm), режимы full/partial/mona, freeze-логика, param-groups (discriminative LR), extract_features |
src/mona.py |
Conv-MONA адаптер (по коду Leiyi-Hu/mona), вставка forward-hook'ом после стадий |
src/losses.py |
CE/LS/weighted/Focal, effective-number weights, build_criterion |
src/metrics.py |
macro-F1, balanced acc, top-k, MCC, κ, confusion (sklearn) |
src/train.py |
train/eval цикл, mixup (timm), early-stop, Optuna pruning (report/should_prune), VRAM-hygiene |
src/optuna_search.py |
пространство поиска (define-by-run), single/multi-objective, sampler+pruner, экспорт best/trials |
src/umap_analysis.py |
эмбеддинги → UMAP 2D + кластеризация → silhouette/ARI/NMI + 2D-картинка |
src/run_baseline.py |
одиночный прогон + test-метрики + confusion-heatmap (B0/E1) |
src/dataset_stats.py |
статистика ImageFolder (число классов, per-class, дисбаланс, разрешения) |
Конфигурация: задача управляется Optuna (define-by-run) + argparse/dataclass, поэтому здесь сознательное отступление от gin-strict (
.claude/rules/python-code.md) — пространство гиперпараметров описывается вsuggest_configs, а не в статическом.gin. Остальные конвенции (type hints, Google-docstrings,from __future__ import annotations, seeds, atomic writes,inference_mode) соблюдены.
§14. Чем задание выявляет сильного студента
Слабый студент сделает MVP буквально (посчитает числа, прогонит Optuna). Сильный проявит критическое мышление:
- осознает и измерит утечку из видео (group-split vs per-frame), не примет завышенный R/F1 за чистую монету;
- проверит H2/H3 честно (равный бюджет) и свяжет вывод с теорией (LP-FT, «5%>100%»), а не просто выберет «что победило»;
- покажет важность гиперпараметров (fANOVA) и сузит пространство во второй итерации;
- сверит UMAP-перекрытия с confusion matrix (H6) — увяжет признаковый анализ с ошибками;
- докажет H1 со стат-проверкой (random vs TPE при равном бюджете), а не на одном seed;
- честно зафиксирует отрицательные результаты и caveat (hflip, двойная компенсация, малый/грязный датасет).
- Сквозной маркер: способность связать эксперимент с проектом (EdgeNeXt ↔ SOFIA-Tiny B134_BB_2022_EdgeNeXt_Efficient_CNN-Transformer_Mobile_Vision; Conv-MONA ↔ PROTOCOL_text_encoder_benchmark_StripNet_GTA_UAV) и сделать честный вывод с признанием caveat.