399 lines
14 KiB
Markdown
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)
|