diff --git a/README.md b/README.md new file mode 100644 index 0000000..1ec84c6 --- /dev/null +++ b/README.md @@ -0,0 +1,91 @@ +# EdgeNeXt × Optuna × Naruto Sign — код HPO-эксперимента + +Учебно-исследовательский код к методичке [`../PROTOCOL_HPO_EdgeNeXt_NarutoSign.md`](../PROTOCOL_HPO_EdgeNeXt_NarutoSign.md) +(научный руководитель — мнс Павленко Б.В.). Задача: подбор гиперпараметров дообучения +компактного энкодера **EdgeNeXt** на наборе **Naruto Sign** (классификация ручных печатей). + +## Установка + +```bash +# Python 3.10–3.12 (PyTorch ещё не собран под 3.14) +python -m venv .venv && . .venv/Scripts/activate # Windows: .venv\Scripts\activate +pip install -r requirements.txt +``` + +## Данные + +```python +import kagglehub +path = kagglehub.dataset_download("vikranthkanumuru/naruto-hand-sign-dataset") +print(path) # внутри — папки-классы (ImageFolder) +``` + +Сразу посчитать реальную статистику (заполнить таблицу в STATS.md): + +```bash +python -m src.dataset_stats --data-root --out results/dataset_stats.json +``` + +## Запуск экспериментов + +```bash +# B0 — baseline (один честный прогон, test + confusion matrix) +python -m src.run_baseline --data-root --regime partial --n-unfrozen 1 --epochs 30 + +# E1 — ablation режимов (повторить для full / partial(0..4) / mona) +python -m src.run_baseline --data-root --regime full --epochs 30 --out results/e1_full +python -m src.run_baseline --data-root --regime partial --n-unfrozen 0 --out results/e1_lp +python -m src.run_baseline --data-root --regime mona --epochs 30 --out results/e1_mona + +# E2 — Optuna single-objective (TPE + median pruning), persist to sqlite +python -m src.optuna_search --data-root --sampler tpe --pruner median \ + --n-trials 60 --epochs 25 --study-name nss_v1 --storage + +# E3 — Optuna multi-objective (macro-F1 ↑ vs trainable params ↓) +python -m src.optuna_search --data-root --multi-objective --sampler nsga \ + --n-trials 80 --study-name nss_mo + +# E4 — UMAP анализ признаков (до дообучения и с чекпойнтом — после) +python -m src.umap_analysis --data-root --split val --out results/umap_pretrained +python -m src.umap_analysis --data-root --checkpoint --out results/umap_finetuned + +# E5 (опц.) — контроль метода: random vs TPE при равном бюджете +python -m src.optuna_search --data-root --sampler random --n-trials 60 --study-name nss_random +``` + +Все скрипты — модули пакета `src`, запускать из папки `code/` через `python -m src.`. + +## Визуализация Optuna + +```python +import optuna +from optuna.visualization import (plot_optimization_history, + plot_param_importances, plot_pareto_front) +study = optuna.load_study(study_name="nss_v1", storage="sqlite:///nss_v1.db") +plot_optimization_history(study).show() +plot_param_importances(study).show() # fANOVA — какие гиперпараметры важны +``` + +## Структура + +| Модуль | Назначение | +|:--|:--| +| `src/data.py` | ImageFolder, стратиф. split, transforms (hflip OFF), sampler, class weights | +| `src/model.py` | EdgeNeXt (timm), режимы full/partial/mona, freeze, param-groups, фичи для UMAP | +| `src/mona.py` | Conv-MONA адаптер (по `Leiyi-Hu/mona`), вставка hook'ом | +| `src/losses.py` | CE / label-smoothing / weighted / Focal / effective-number weights | +| `src/metrics.py` | macro-F1, balanced acc, top-k, MCC, κ, confusion (sklearn) | +| `src/train.py` | train/eval, mixup, early-stop, Optuna pruning, VRAM-hygiene | +| `src/optuna_search.py` | пространство поиска, single/multi-objective, sampler+pruner | +| `src/umap_analysis.py` | эмбеддинги → UMAP 2D + кластеризация + ARI/NMI | +| `src/run_baseline.py` | одиночный прогон + test + confusion-heatmap | +| `src/dataset_stats.py` | статистика датасета | + +## Заметки по воспроизводимости + +- seed=42 по умолчанию (`src/train.py::set_seed`); финальные сравнения — 3 seed (42/123/456). +- test трогать **один раз** в конце; HPO — только по val (macro-F1). +- `lr`/`weight_decay` ищутся в **log**-шкале. +- `RandomHorizontalFlip` **отключён** (печати чувствительны к лево/право). +- Не включать `weighted_ce/focal` одновременно с `--weighted-sampler` на полную силу (двойная компенсация). +- Главный риск Naruto Sign — **утечка кадров из одного видео** в train и test: если в именах файлов есть id видео, использовать `StratifiedGroupKFold` (см. методичку §3). Базовый `data.py` делает per-frame split — отметить риск в REPORT.md. diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..19dc97e --- /dev/null +++ b/requirements.txt @@ -0,0 +1,16 @@ +# EdgeNeXt + Optuna HPO on Naruto Sign — pinned-ish minimums. +# Use a Python 3.10–3.12 env (PyTorch wheels are not yet built for 3.14). +torch>=2.2 +torchvision>=0.17 +timm>=1.0.7 # EdgeNeXt weights + Mixup/SoftTargetCrossEntropy +optuna>=4.5 # AutoSampler / multi-objective / pruners +optunahub>=0.2 # AutoSampler lives here (load_module("samplers/auto_sampler")) +umap-learn>=0.5.5 +scikit-learn>=1.3 +hdbscan>=0.8.33 # optional, density clustering on UMAP mid-dim +matplotlib>=3.7 +numpy>=1.24 +pillow>=10.0 +pandas>=2.0 +kagglehub>=0.3 # optional, dataset download +plotly>=5.18 # optional, optuna.visualization interactive plots