Reject blank positive imagery in training loop
GeoIntel release gates / Compile, test, contracts and builds (push) Canceled after 0s
GeoIntel release gates / Python and npm vulnerability policy (push) Canceled after 0s
GeoIntel release gates / GIS image, SBOM and container scan (push) Canceled after 0s

This commit is contained in:
Jens
2026-07-27 02:57:36 +02:00
parent c717201cb2
commit 70897a3265
9 changed files with 287 additions and 3 deletions
@@ -117,6 +117,27 @@ class OrthophotoAcquisitionService:
valid_from=datetime(2024, 4, 6, tzinfo=UTC),
valid_to=datetime(2024, 9, 21, 23, 59, 59, tzinfo=UTC),
),
OrthophotoProduct(
key="wallonia_2023",
display_name="Zomerorthofoto Wallonië 2023",
observation_label="27 mei tot 25 juni 2023",
temporal_granularity="period",
native_resolution_m=0.25,
wms_url="https://geoservices.wallonie.be/arcgis/services/IMAGERIE/ORTHO_2023_ETE/MapServer/WMSServer",
layer="0",
catalog_url="https://geoportail.wallonie.be/catalogue/ad55c2ce-62ad-4c3c-b3cf-8fbc270a6b6e.html",
limitation_message="Officiële gebiedsdekkende SPW-zomercampagne 2023; exacte vliegdata zijn beschikbaar in het afzonderlijke maillage- en tuilageproduct.",
provider="spw_orthophoto",
source_label="SPW ORTHO_2023_ETE WMS",
attribution="Bron: Service public de Wallonie (SPW), Orthophotos 2023 Été",
license_note="CC BY 4.0; citeer SPW en vermeld wijzigingen.",
series_namespace="spw",
coverage_zone="wallonia",
supports_detection=True,
observed_at=datetime(2023, 5, 27, tzinfo=UTC),
valid_from=datetime(2023, 5, 27, tzinfo=UTC),
valid_to=datetime(2023, 6, 25, 23, 59, 59, tzinfo=UTC),
),
OrthophotoProduct(
key="brussels_latest",
display_name="Meest recente orthofoto Brussel",
@@ -0,0 +1,31 @@
from __future__ import annotations
import importlib.util
from pathlib import Path
SCRIPT = Path(__file__).parents[2] / "scripts" / "run_belgium_building_training_loop.py"
SPEC = importlib.util.spec_from_file_location("training_loop", SCRIPT)
assert SPEC and SPEC.loader
MODULE = importlib.util.module_from_spec(SPEC)
SPEC.loader.exec_module(MODULE)
def test_training_command_is_cuda_deterministic_and_bound_to_frozen_inputs(tmp_path: Path) -> None:
command = MODULE.training_command(
"yolo",
model=tmp_path / "base.pt",
data=tmp_path / "dataset.yaml",
project=tmp_path / "runs",
name="iteration-001",
epochs=160,
seed=42,
batch=2,
workers=4,
)
assert command[:2] == ["yolo", "train"]
assert "device=0" in command
assert "deterministic=True" in command
assert "seed=42" in command
assert "epochs=160" in command
assert f"data={tmp_path / 'dataset.yaml'}" in command
@@ -65,6 +65,7 @@ def test_operator_yolo_dataset_quality_audit_reports_dataset_risks(tmp_path: Pat
"label_count": 2,
"is_negative": False,
"is_repeated_background_negative": False,
"low_visual_variance": True,
},
{
"sample_slug": "postel_bos",
@@ -144,6 +145,7 @@ def test_operator_yolo_dataset_quality_audit_reports_dataset_risks(tmp_path: Pat
assert report["positive_sample_count"] == 2
assert report["background_sample_count"] == 1
assert report["train_negative_tile_count"] == 2
assert report["low_variance_positive_tile_count"] == 1
assert report["repeated_background_negative_tile_count"] == 1
assert report["label_stats"]["parsed_label_count"] == 3
assert report["label_stats"]["invalid_label_count"] == 0
@@ -169,6 +171,7 @@ def test_operator_yolo_dataset_quality_audit_reports_dataset_risks(tmp_path: Pat
assert "repeated_background_negative_share_above_gate" in warning_codes
assert "median_box_area_below_gate" in warning_codes
assert "small_box_share_above_gate" in warning_codes
assert "positive_tiles_have_low_visual_variance" in warning_codes
markdown = (output_dir / "operator_yolo_dataset_quality_audit.md").read_text(encoding="utf-8")
assert "Operator YOLO Dataset Quality Audit" in markdown
@@ -169,7 +169,7 @@ def test_orthophoto_product_registry_exposes_only_governed_official_layers() ->
assert {"2025", "2012", "2008_2011", "2000_2003", "1979_1990", "1971"}.issubset(keys)
assert next(item for item in products if item["key"] == "most_recent")["supports_detection"] is True
detection_keys = {item["key"] for item in products if item["supports_detection"]}
assert {"most_recent", "wallonia_latest", "wallonia_2024", "brussels_latest", "brussels_2025", "2025"} <= detection_keys
assert {"most_recent", "wallonia_latest", "wallonia_2024", "wallonia_2023", "brussels_latest", "brussels_2025", "2025"} <= detection_keys
by_key = {item["key"]: item for item in products}
assert by_key["wallonia_latest"]["provider"] == "spw_orthophoto"
assert by_key["wallonia_latest"]["coverage_zone"] == "wallonia"