Files
E01_textural_features_blast…/docs/reproducibility_guide.md
T
2026-09-11 08:28:02 +03:00

399 lines
14 KiB
Markdown

# E01 Reproducibility Guide
## 1. Зачем нужна эта структура
Эксперимент разбит на:
- один общий блок `foundation`, который готовит данные, split, ROI и признаки;
- пять отдельных блоков `H1-H5`, каждый из которых проверяет одну научную гипотезу;
- один общий блок `all`, который запускает все последовательно.
Это сделано для того, чтобы человек мог:
- пересобрать весь эксперимент целиком;
- отдельно запустить только одну гипотезу;
- быстро понять, какие артефакты относятся к какой гипотезе.
Дополнительно все новые entrypoint-скрипты работают в resumable-режиме:
- если артефакты уже есть, они не пересчитываются без необходимости;
- если чего-то не хватает, достраивается только отсутствующий этап;
- в summary каждого блока фиксируется, что именно было пересчитано в текущем запуске.
## 2. Основные команды
Все команды ниже выполняются из корня клонированного репозитория E01:
```bash
cd E01_textural_features_blast_pipeline
```
Перед запуском нужно подготовить окружение и указать пути к данным.
### 2.1. Установка зависимостей
Проект не хранит `.venv` в репозитории. Код проверен на CPython 3.12. После клонирования создайте окружение и установите зависимости:
```bash
python3.12 -m venv .venv
./.venv/bin/python -m pip install --upgrade pip
./.venv/bin/python -m pip install -r requirements.txt
```
### 2.2. Где должны лежать тяжелые данные
В репозиторий не включаются:
- исходный датасет `data`;
- датасет масок `data_masks`;
- все артефакты из `outputs/`.
Ожидается, что у вас уже есть две директории:
- `data_root` — каталог с исходными изображениями и label-файлами;
- `masks_root` — каталог с масками объектов.
Проект не требует, чтобы эти каталоги лежали внутри репозитория. Они могут находиться в любом месте файловой системы.
### 2.3. Как указать пути к данным
Рекомендуемый способ:
1. Скопируйте [local_paths.template.json](../configs/datasets/local_paths.template.json) в `configs/datasets/local_paths.json`.
2. Впишите абсолютные пути:
```json
{
"data_root": "/absolute/path/to/Data/data",
"masks_root": "/absolute/path/to/Data/data_masks"
}
```
Этот файл специально не коммитится.
Альтернативы:
- переменные среды:
```bash
export E01_DATA_ROOT="/absolute/path/to/Data/data"
export E01_MASKS_ROOT="/absolute/path/to/Data/data_masks"
```
- аргументы командной строки:
```bash
./.venv/bin/python scripts/run_all_hypotheses.py --data-root /absolute/path/to/Data/data --masks-root /absolute/path/to/Data/data_masks
```
- передача путей прямо через `make`:
```bash
make all DATA_ROOT=/absolute/path/to/Data/data MASKS_ROOT=/absolute/path/to/Data/data_masks
```
После этого можно использовать либо `make`, либо прямой вызов Python.
### Вариант A. Самый удобный: через `make`
```bash
make foundation
make h1
make h2
make h3
make h4
make h5
make all
make test
make repro-check
```
Если вы не хотите создавать `configs/datasets/local_paths.json`, можно сразу передать пути:
```bash
make foundation DATA_ROOT=/absolute/path/to/Data/data MASKS_ROOT=/absolute/path/to/Data/data_masks
make all DATA_ROOT=/absolute/path/to/Data/data MASKS_ROOT=/absolute/path/to/Data/data_masks
```
### Вариант B. Прямой запуск Python
```bash
./.venv/bin/python scripts/run_foundation.py
./.venv/bin/python scripts/run_h1_interpretable_features.py
./.venv/bin/python scripts/run_h2_mask_effect.py
./.venv/bin/python scripts/run_h3_noise_regimes.py
./.venv/bin/python scripts/run_h4_aggregation.py
./.venv/bin/python scripts/run_h5_deep_vs_handcrafted.py
./.venv/bin/python scripts/run_all_hypotheses.py
./.venv/bin/python -m unittest discover -s tests -v
```
Какие скрипты предназначены для прямого запуска человеком, а какие являются внутренними реализациями этапов, указано в [scripts/README.md](../scripts/README.md).
## 3. Что запускает каждый блок
### `foundation`
Файл:
- [run_foundation.py](../scripts/run_foundation.py)
Что делает:
- `A0`: аудит данных и индексы;
- `A1`: подмножества корпуса;
- `A2`: patient-level split;
- `A4`: постановки бинарных задач;
- `A3`: ROI по bbox и маскам;
- `A5`: извлечение признаков.
Главный смысл:
- один раз подготовить все базовые артефакты для всех следующих гипотез.
Что ожидается на выходе:
- `outputs/dataset_index/` — индексы пациентов, изображений и объектов;
- `outputs/splits/` — patient-level split;
- `outputs/crops/` — bbox и mask ROI;
- `outputs/features/` — таблицы признаков;
- `outputs/reports/` — QC-отчеты этапов `A0-A5`.
Ключевой summary:
- [foundation_summary.md](../outputs/reports/hypotheses/foundation_summary.md)
### `h1`
Файл:
- [run_h1_interpretable_features.py](../scripts/run_h1_interpretable_features.py)
Что делает:
- `A6`: baseline-модели на признаках;
- `A7`: устойчивость и интерпретация признаков.
Проверяемая гипотеза:
- интерпретируемые признаки действительно помогают отличать бласты.
Что ожидается на выходе:
- `outputs/tables/object_level_metrics_baselines.csv`;
- `outputs/tables/baseline_model_leaderboard.csv`;
- `outputs/predictions/object_level_baseline_predictions.parquet`;
- `outputs/tables/top_features_stability.csv`;
- `outputs/figures/pr_curves_baselines.png`;
- `outputs/figures/roc_curves_baselines.png`;
- `outputs/reports/feature_interpretation_notes.md`.
Summary:
- [h1_interpretable_features_summary.md](../outputs/reports/hypotheses/h1_interpretable_features_summary.md)
### `h2`
Файл:
- [run_h2_mask_effect.py](../scripts/run_h2_mask_effect.py)
Что делает:
- масочная часть `A8`.
Проверяемая гипотеза:
- маска клетки улучшает признаки и/или качество классификации.
Что ожидается на выходе:
- `outputs/tables/ablation_mask_usage.csv`.
Summary:
- [h2_mask_effect_summary.md](../outputs/reports/hypotheses/h2_mask_effect_summary.md)
### `h3`
Файл:
- [run_h3_noise_regimes.py](../scripts/run_h3_noise_regimes.py)
Что делает:
- режимы корпуса и шумовая часть `A8`.
Проверяемая гипотеза:
- шумовые классы и более реалистичный режим корпуса усложняют задачу.
Что ожидается на выходе:
- `outputs/tables/ablation_dataset_regimes.csv`;
- `outputs/figures/ablation_summary.png` при совместном запуске с `H2` или через `all`.
Summary:
- [h3_noise_regimes_summary.md](../outputs/reports/hypotheses/h3_noise_regimes_summary.md)
### `h4`
Файл:
- [run_h4_aggregation.py](../scripts/run_h4_aggregation.py)
Что делает:
- `A10-A11`: image-level и patient-level агрегирование, итоговые фигуры и таблицы.
Проверяемая гипотеза:
- object-level score можно превратить в practically useful оценку изображения и пациента.
Что ожидается на выходе:
- `outputs/tables/image_level_metrics.csv`;
- `outputs/tables/patient_level_ranking_metrics.csv`;
- `outputs/predictions/image_level_scores.parquet`;
- `outputs/predictions/patient_level_scores.parquet`;
- `outputs/tables/figure_manifest.csv`;
- `outputs/tables/table_manifest.csv`.
Summary:
- [h4_aggregation_summary.md](../outputs/reports/hypotheses/h4_aggregation_summary.md)
### `h5`
Файл:
- [run_h5_deep_vs_handcrafted.py](../scripts/run_h5_deep_vs_handcrafted.py)
Что делает:
- подготовка `modeling_workset`;
- `A9`: ограниченные deep-baseline.
Проверяемая гипотеза:
- lightweight deep-модели можно честно сравнить с handcrafted baseline на тех же данных.
Что ожидается на выходе:
- `outputs/dataset_index/task_a43_full_realistic_modeling_workset.parquet`;
- `outputs/crops/roi_manifest_modeling_workset.parquet`;
- `outputs/tables/deep_vs_handcrafted.csv`;
- `outputs/predictions/object_level_deep_predictions.parquet`;
- `outputs/figures/deep_training_curves.png`;
- `outputs/reports/a9_deep_qc.md`.
Summary:
- [h5_deep_vs_handcrafted_summary.md](../outputs/reports/hypotheses/h5_deep_vs_handcrafted_summary.md)
### `all`
Файл:
- [run_all_hypotheses.py](../scripts/run_all_hypotheses.py)
Что делает:
- последовательно запускает `foundation`, `H1`, `H2`, `H3`, `H4`, `H5`.
Summary:
- [run_all_hypotheses_summary.md](../outputs/reports/hypotheses/run_all_hypotheses_summary.md)
## 4. Порядок запуска по зависимостям
Если вы хотите выполнять эксперимент по частям, используйте такой порядок:
1. `foundation`
2. `h1`
3. `h2`
4. `h3`
5. `h4`
6. `h5`
Почему именно так:
- `H1-H5` зависят от базовых артефактов `foundation`;
- `H2`, `H3`, `H4`, `H5` используют результаты `H1`;
- `H5` дополнительно строит `modeling_workset`.
Если нужна полная пересборка без ручного контроля, используйте:
```bash
make all
```
или
```bash
./.venv/bin/python scripts/run_all_hypotheses.py
```
Если артефакты уже собраны, эта команда отработает быстро и просто переиспользует проверенные результаты.
## 5. Где смотреть результаты
Основные директории:
- [outputs/reports/hypotheses](../outputs/reports/hypotheses) — короткие summary по каждому блоку;
- [outputs/tables](../outputs/tables) — численные таблицы метрик;
- [outputs/figures](../outputs/figures) — итоговые графики;
- [outputs/predictions](../outputs/predictions) — предсказания моделей;
- [outputs/checkpoints](../outputs/checkpoints) — сохраненные модели.
Практически это означает:
- если нужен “сырой” численный результат — смотрите `outputs/tables/`;
- если нужны предсказания моделей — смотрите `outputs/predictions/`;
- если нужны изображения и графики для статьи или диссертации — смотрите `outputs/figures/`;
- если нужна проверка корректности этапов — смотрите `outputs/reports/` и `outputs/reports/hypotheses/`.
Подробный человекочитаемый отчет:
- [E01_detailed_report.md](../reports/E01_detailed_report.md)
## 6. Как проверять, что все прошло корректно
Минимальная проверка:
```bash
make repro-check
```
Что это означает:
- выполнен полный воспроизводимый запуск с пересчётом отсутствующих этапов;
- после этого выполнены локальные тесты.
Проверенный сценарий публикационного репозитория:
1. Установить зависимости из `requirements.txt`.
2. Создать `configs/datasets/local_paths.json`.
3. Выполнить `make all`.
4. Выполнить `make test`.
5. Открыть `outputs/reports/hypotheses/run_all_hypotheses_summary.md`.
Также полезно открыть:
- [run_all_hypotheses_summary.md](../outputs/reports/hypotheses/run_all_hypotheses_summary.md)
## 7. Важное ограничение среды
`xgboost` не входит в обязательные зависимости. Соответствующие конфигурации
автоматически используют `HistGradientBoostingClassifier` из scikit-learn.
Практическое следствие:
- конфигурации, которые в таблицах помечены как `xgboost`, фактически выполняются через `HistGradientBoosting` fallback.
Это ограничение уже отражено в:
- [a6_baseline_qc.md](../outputs/reports/a6_baseline_qc.md)
- [a9_deep_qc.md](../outputs/reports/a9_deep_qc.md)