Files
PracticeClassif/PROTOCOL_HPO_EdgeNeXt_NarutoSign.md
2026-06-30 15:44:41 +03:00

40 KiB
Raw Blame History

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
Optuna
timm
UMAP
B134_BB_2022_EdgeNeXt_Efficient_CNN-Transformer_Mobile_Vision
PROTOCOL_text_encoder_benchmark_StripNet_GTA_UAV
ПРАКТИКА_2026-07-01_задания_16_студентов
HYP_SOFIA_v77_design
protocol
methodology
hpo
optuna
edgenext
mona
transfer-learning
classification
component/backbone
task/experiment
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, раскраска по классам, кластеризация на промежуточном (1020-мерном) вложении, 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 ~810 дней): рабочий честный 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.35.6M params, SDTA channel-attention). Этот эксперимент — песочница для SDTA/adaptive-kernels интуиций.
  • MONAу проекта уже есть Conv-MONA в text-encoder бенчмарке (PROTOCOL_text_encoder_benchmark_StripNet_GTA_UAV §2.1): здесь студент реализует и измеряет тот же класс PEFT на чистой классификации.
  • Optuna-методология переиспользуема для всего проекта (E0E9 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 после скачивания (числа могли измениться). Документ трека Устенко может находиться в другой ветке репозитория.

Ключевые решения протокола:

  1. Источник по умолчанию: Kaggle vikranthkanumuru/naruto-hand-sign-dataset (формат ImageFolder, заточен под классификацию). Roboflow-наборы — детекционные, использовать как запасные (crop по bbox).
  2. Сверить статистику после скачивания скриптом dataset_stats.py: число классов (12 или 13?), всего изображений, per-class, разрешения, дисбаланс. Это первый артефакт студента — таблица статистики в отчёте.
  3. Стратифицированный split (seed=42), доли 70/15/15. Реализация — data.py (_stratified_indices).
  4. Утечка из видео — главный риск честности. Кадры извлечены из видео покадрово ⇒ соседние кадры почти идентичны. Случайный per-frame split завышает метрику. Если в именах файлов есть id видео/серии — делать group-split (StratifiedGroupKFold, см. SECTION_naruto_dataset §5). Если id нет — отметить риск в отчёте и сделать дедупликацию near-duplicate (perceptual hash). Базовый data.py делает per-frame split — это допустимо для учебного MVP, но факт и риск утечки обязательно фиксируется в REPORT.md.
  5. Размер входа — 256×256 (дефолт EdgeNeXt), нормализация ImageNet (берётся из timm.data.resolve_model_data_config).

[!danger] Horizontal flip — отключён по умолчанию Печать — это конкретная конфигурация левой/правой руки; зеркалирование меняет семантику жеста ⇒ label noise. В data.py use_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_featuresforward_head(pre_logits=True) → L2-норма → матрица [N,D] → (а) UMAP→2D (раскраска по истинному классу, random_state=42, metric=cosine) для визуализации; (б) UMAP→1020D для кластеризации (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.py suggest_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 (разморозить 12 верхние стадии), а не 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: лучший режим; если monafull при <5% params — H3 поддержана
E2 Optuna single-obj TPE+pruner, objective=val macro-F1, 4080 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↓, 60100 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.
  • Заморозка BNfreeze_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. Что сдаёт студент

  1. Код (папка code/) с README.md и requirements.txt — запускается на чужой машине по инструкции.
  2. STATS.md — таблица статистики Naruto Sign по факту скачивания (dataset_stats.py) + источник/версия/лицензия.
  3. REPORT.md — результаты всех этапов: таблицы (B0/E1/E2/E3), кривые обучения, importance-график Optuna, Pareto-фронт, UMAP-картинки (до/после) + confusion matrix, проверка каждой гипотезы H1H6 с вердиктом (поддержана/опровергнута/неубедительно), анализ ошибок (35 примеров), честные caveat.
  4. Артефакты: *_trials.csv, *_best.json, umap_2d.png, cluster_report.json, лучший чекпойнт + config, папка PNG.

MVP (≈810 дней): статистика + 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 дней)

Дни Задача
12 Скачать датасет, 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
56 E1 ablation режимов (full/partial 04/mona); таблица + кривые
6 Прочитать SECTION_hpo_methods, SECTION_optuna
79 E2 Optuna single-objective (TPE+pruner), importance/history/slice; побить B0
9 E4 UMAP (до/после), сверка с confusion matrix
10 Воспроизводимый прогон зафиксирован; черновик REPORT
1112 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.