Files
PracticeClassif/code/README.md
2026-06-30 15:23:37 +03:00

92 lines
5.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# EdgeNeXt × Optuna × Naruto Sign — код HPO-эксперимента
Учебно-исследовательский код к методичке [`../PROTOCOL_HPO_EdgeNeXt_NarutoSign.md`](../PROTOCOL_HPO_EdgeNeXt_NarutoSign.md)
(научный руководитель — мнс Павленко Б.В.). Задача: подбор гиперпараметров дообучения
компактного энкодера **EdgeNeXt** на наборе **Naruto Sign** (классификация ручных печатей).
## Установка
```bash
# Python 3.103.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 <PATH> --out results/dataset_stats.json
```
## Запуск экспериментов
```bash
# B0 — baseline (один честный прогон, test + confusion matrix)
python -m src.run_baseline --data-root <PATH> --regime partial --n-unfrozen 1 --epochs 30
# E1 — ablation режимов (повторить для full / partial(0..4) / mona)
python -m src.run_baseline --data-root <PATH> --regime full --epochs 30 --out results/e1_full
python -m src.run_baseline --data-root <PATH> --regime partial --n-unfrozen 0 --out results/e1_lp
python -m src.run_baseline --data-root <PATH> --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 <PATH> --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 <PATH> --multi-objective --sampler nsga \
--n-trials 80 --study-name nss_mo
# E4 — UMAP анализ признаков (до дообучения и с чекпойнтом — после)
python -m src.umap_analysis --data-root <PATH> --split val --out results/umap_pretrained
python -m src.umap_analysis --data-root <PATH> --checkpoint <best.pt> --out results/umap_finetuned
# E5 (опц.) — контроль метода: random vs TPE при равном бюджете
python -m src.optuna_search --data-root <PATH> --sampler random --n-trials 60 --study-name nss_random
```
Все скрипты — модули пакета `src`, запускать из папки `code/` через `python -m src.<name>`.
## Визуализация 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.