Spaces:
Sleeping
Sleeping
| """ | |
| Train the archive conjunctiva screening model. | |
| Usage:: | |
| python scripts/train_archive_model.py [--dataset PATH] [--output-dir PATH] [--quiet] | |
| The script trains the model, writes the artefact and a human-readable | |
| training report, then exits with code 0 on success or 1 on failure. | |
| """ | |
| from __future__ import annotations | |
| import argparse | |
| import json | |
| import sys | |
| import time | |
| from pathlib import Path | |
| ROOT = Path(__file__).resolve().parents[2] | |
| BACKEND_ROOT = ROOT / "backend" | |
| sys.path.insert(0, str(BACKEND_ROOT)) | |
| from app.config import DEFAULT_ARCHIVE_MODEL_PATH, DEFAULT_TRAINING_REPORT_PATH # noqa: E402 | |
| from app.ml.archive_model import save_archive_model, train_archive_model # noqa: E402 | |
| DEFAULT_DATASET = ROOT / "archive" / "dataset anemia" | |
| # --------------------------------------------------------------------------- | |
| # CLI | |
| # --------------------------------------------------------------------------- | |
| def _build_parser() -> argparse.ArgumentParser: | |
| p = argparse.ArgumentParser( | |
| description="Train the AnemiaLens archive conjunctiva screening model.", | |
| formatter_class=argparse.ArgumentDefaultsHelpFormatter, | |
| ) | |
| p.add_argument( | |
| "--dataset", | |
| type=Path, | |
| default=DEFAULT_DATASET, | |
| help="Root directory of the labelled anemia dataset.", | |
| ) | |
| p.add_argument( | |
| "--output-dir", | |
| type=Path, | |
| default=DEFAULT_ARCHIVE_MODEL_PATH.parent, | |
| help="Directory where the model artefact and report are written.", | |
| ) | |
| p.add_argument( | |
| "--quiet", | |
| action="store_true", | |
| help="Suppress progress output (report still written to disk).", | |
| ) | |
| return p | |
| # --------------------------------------------------------------------------- | |
| # Main | |
| # --------------------------------------------------------------------------- | |
| def main(argv: list[str] | None = None) -> int: | |
| args = _build_parser().parse_args(argv) | |
| if not args.dataset.exists(): | |
| print( | |
| f"ERROR: Dataset directory not found: {args.dataset}\n" | |
| " Download the anemia dataset and place it there, or pass --dataset PATH.", | |
| file=sys.stderr, | |
| ) | |
| return 1 | |
| if not args.quiet: | |
| print(f"Dataset : {args.dataset}") | |
| print(f"Output : {args.output_dir}") | |
| print() | |
| t0 = time.perf_counter() | |
| try: | |
| artifact, report = train_archive_model(args.dataset) | |
| except Exception as exc: | |
| print(f"ERROR: Training failed — {exc}", file=sys.stderr) | |
| return 1 | |
| elapsed = time.perf_counter() - t0 | |
| # --- Write artefacts --------------------------------------------------- | |
| args.output_dir.mkdir(parents=True, exist_ok=True) | |
| model_path = args.output_dir / DEFAULT_ARCHIVE_MODEL_PATH.name | |
| report_path = args.output_dir / DEFAULT_TRAINING_REPORT_PATH.name | |
| save_archive_model(artifact, model_path) | |
| report_path.write_text(json.dumps(report, indent=2, ensure_ascii=False), encoding="utf-8") | |
| # --- Summary ----------------------------------------------------------- | |
| if not args.quiet: | |
| metrics = report.get("metrics", {}) | |
| print(json.dumps(report, indent=2)) | |
| print() | |
| print("=" * 56) | |
| print(f" Model : {report.get('primary_model', '?')}") | |
| print(f" Subjects : {report.get('subject_count', '?')}") | |
| print(f" Records : {report.get('record_count', '?')}") | |
| print(f" Accuracy : {metrics.get('accuracy', 0):.3f}") | |
| print(f" F1 : {metrics.get('f1', 0):.3f}") | |
| print(f" Val size : {metrics.get('validation_size', '?')}") | |
| print(f" Elapsed : {elapsed:.1f}s") | |
| print("=" * 56) | |
| print(f" Saved model → {model_path}") | |
| print(f" Saved report → {report_path}") | |
| return 0 | |
| if __name__ == "__main__": | |
| sys.exit(main()) | |