Support dense full-AOI building evaluation
This commit is contained in:
@@ -31,6 +31,8 @@ def test_training_command_is_cuda_deterministic_and_bound_to_frozen_inputs(tmp_p
|
|||||||
assert "deterministic=True" in command
|
assert "deterministic=True" in command
|
||||||
assert "seed=42" in command
|
assert "seed=42" in command
|
||||||
assert "epochs=160" in command
|
assert "epochs=160" in command
|
||||||
|
assert "max_det=1000" in command
|
||||||
|
assert "imgsz=640" in command
|
||||||
assert f"data={tmp_path / 'dataset.yaml'}" in command
|
assert f"data={tmp_path / 'dataset.yaml'}" in command
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ data. A new iteration adds independent training AOIs instead.
|
|||||||
| Temporal truth | Unknown per-pixel dates remain unknown; acquisition dates may not masquerade as observation dates |
|
| Temporal truth | Unknown per-pixel dates remain unknown; acquisition dates may not masquerade as observation dates |
|
||||||
| Threshold selection | Calibration set only; maximise the worst regional F1 before aggregate F1 |
|
| Threshold selection | Calibration set only; maximise the worst regional F1 before aggregate F1 |
|
||||||
| Test aggregate | F1 at least 0.55 at the frozen footprint/detection match IoU 0.25 contract |
|
| Test aggregate | F1 at least 0.55 at the frozen footprint/detection match IoU 0.25 contract |
|
||||||
|
| Dense-tile capacity | Retain up to 1000 detections per tile; the library default of 300 is below observed Belgian urban label density |
|
||||||
| Regional test | Every region: F1 at least 0.45, precision at least 0.50 and recall at least 0.40 |
|
| Regional test | Every region: F1 at least 0.45, precision at least 0.50 and recall at least 0.40 |
|
||||||
| Pure background | Zero detections on every pure-empty tile at the selected threshold |
|
| Pure background | Zero detections on every pure-empty tile at the selected threshold |
|
||||||
| Production | Exact candidate checksum and fail-closed promotion report required |
|
| Production | Exact candidate checksum and fail-closed promotion report required |
|
||||||
|
|||||||
@@ -82,6 +82,12 @@ def main() -> int:
|
|||||||
parser.add_argument("--split", default="val")
|
parser.add_argument("--split", default="val")
|
||||||
parser.add_argument("--augment", action="store_true", help="Enable deterministic YOLO test-time augmentation.")
|
parser.add_argument("--augment", action="store_true", help="Enable deterministic YOLO test-time augmentation.")
|
||||||
parser.add_argument("--imgsz", type=int, default=640)
|
parser.add_argument("--imgsz", type=int, default=640)
|
||||||
|
parser.add_argument(
|
||||||
|
"--max-det",
|
||||||
|
type=int,
|
||||||
|
default=1000,
|
||||||
|
help="Maximum detections retained per tile; dense Belgian urban tiles exceed YOLO's default 300.",
|
||||||
|
)
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
from ultralytics import YOLO
|
from ultralytics import YOLO
|
||||||
@@ -106,6 +112,7 @@ def main() -> int:
|
|||||||
device=args.device,
|
device=args.device,
|
||||||
augment=args.augment,
|
augment=args.augment,
|
||||||
imgsz=args.imgsz,
|
imgsz=args.imgsz,
|
||||||
|
max_det=args.max_det,
|
||||||
verbose=False,
|
verbose=False,
|
||||||
)
|
)
|
||||||
observations: list[dict[str, Any]] = []
|
observations: list[dict[str, Any]] = []
|
||||||
@@ -155,6 +162,7 @@ def main() -> int:
|
|||||||
"match_iou": args.match_iou,
|
"match_iou": args.match_iou,
|
||||||
"test_time_augmentation": args.augment,
|
"test_time_augmentation": args.augment,
|
||||||
"inference_imgsz": args.imgsz,
|
"inference_imgsz": args.imgsz,
|
||||||
|
"max_detections_per_tile": args.max_det,
|
||||||
"tile_count": len(tiles),
|
"tile_count": len(tiles),
|
||||||
"sweeps": sweeps,
|
"sweeps": sweeps,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,6 +40,8 @@ def training_command(
|
|||||||
seed: int,
|
seed: int,
|
||||||
batch: int,
|
batch: int,
|
||||||
workers: int,
|
workers: int,
|
||||||
|
max_det: int = 1000,
|
||||||
|
imgsz: int = 640,
|
||||||
) -> list[str]:
|
) -> list[str]:
|
||||||
return [
|
return [
|
||||||
yolo,
|
yolo,
|
||||||
@@ -47,13 +49,14 @@ def training_command(
|
|||||||
f"model={model}",
|
f"model={model}",
|
||||||
f"data={data}",
|
f"data={data}",
|
||||||
f"epochs={epochs}",
|
f"epochs={epochs}",
|
||||||
"imgsz=640",
|
f"imgsz={imgsz}",
|
||||||
f"batch={batch}",
|
f"batch={batch}",
|
||||||
"device=0",
|
"device=0",
|
||||||
f"workers={workers}",
|
f"workers={workers}",
|
||||||
"patience=35",
|
"patience=35",
|
||||||
"cache=disk",
|
"cache=disk",
|
||||||
"close_mosaic=20",
|
"close_mosaic=20",
|
||||||
|
f"max_det={max_det}",
|
||||||
f"seed={seed}",
|
f"seed={seed}",
|
||||||
"deterministic=True",
|
"deterministic=True",
|
||||||
f"project={project}",
|
f"project={project}",
|
||||||
@@ -88,6 +91,8 @@ def main() -> int:
|
|||||||
parser.add_argument("--epochs", type=int, default=160)
|
parser.add_argument("--epochs", type=int, default=160)
|
||||||
parser.add_argument("--batch", type=int, default=2)
|
parser.add_argument("--batch", type=int, default=2)
|
||||||
parser.add_argument("--workers", type=int, default=4)
|
parser.add_argument("--workers", type=int, default=4)
|
||||||
|
parser.add_argument("--max-det", type=int, default=1000)
|
||||||
|
parser.add_argument("--imgsz", type=int, default=640)
|
||||||
parser.add_argument("--seed", type=int, default=20260731)
|
parser.add_argument("--seed", type=int, default=20260731)
|
||||||
parser.add_argument("--yolo", default="yolo")
|
parser.add_argument("--yolo", default="yolo")
|
||||||
parser.add_argument("--dry-run", action="store_true")
|
parser.add_argument("--dry-run", action="store_true")
|
||||||
@@ -133,6 +138,8 @@ def main() -> int:
|
|||||||
seed=args.seed + index,
|
seed=args.seed + index,
|
||||||
batch=args.batch,
|
batch=args.batch,
|
||||||
workers=args.workers,
|
workers=args.workers,
|
||||||
|
max_det=args.max_det,
|
||||||
|
imgsz=args.imgsz,
|
||||||
)
|
)
|
||||||
if args.dry_run:
|
if args.dry_run:
|
||||||
print(json.dumps({"training_command": command}, indent=2))
|
print(json.dumps({"training_command": command}, indent=2))
|
||||||
@@ -166,6 +173,10 @@ def main() -> int:
|
|||||||
str(report),
|
str(report),
|
||||||
"--device",
|
"--device",
|
||||||
"cuda:0",
|
"cuda:0",
|
||||||
|
"--max-det",
|
||||||
|
str(args.max_det),
|
||||||
|
"--imgsz",
|
||||||
|
str(args.imgsz),
|
||||||
],
|
],
|
||||||
iteration_dir / f"{role}.log",
|
iteration_dir / f"{role}.log",
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user