Hsyshasuzh's picture
download
raw
4.44 kB
"""Explicit DIOR-R four-class OBB benchmark, separate from historical DOTA tests."""
import copy
import json
import time
from pathlib import Path
import numpy as np
import torch
from evaluation.quick_eval import detection_target,detection_metrics
from training.dior_extension import Extension,EXTENSION,sha
from training.model_factory import ROOT
EXACT={'plane':6,'bridge':3,'ship':7,'storage-tank':8}
def predict(wrapper,extension,rows,*,device='cpu'):
names={i:n.replace(' ','-') for i,n in wrapper.names.items()}
mapping={i:EXACT[n] for i,n in names.items() if n in EXACT}
predictions=[];targets=[];broad_predictions=[];broad_targets=[];invalid=0
start=time.monotonic()
for row in rows:
sample=extension.load(row)
with torch.inference_mode():r=wrapper.predict(sample['image'][:,:,::-1].copy(),imgsz=1024,device=device,conf=.001,max_det=300,save=False,verbose=False)[0]
objects=[];vehicles=[]
for p,c,s in zip(r.obb.xyxyxyxy.cpu().numpy(),r.obb.cls.cpu().numpy(),r.obb.conf.cpu().numpy()):
c=int(c);center=p.mean(axis=0).astype(int)
if not(0<=center[0]<800 and 0<=center[1]<800) or np.all(sample['image'][center[1],center[0]]==0):invalid+=1;continue
a={'confidence':float(s),'obb_polygon':p.reshape(-1).tolist()}
if c in mapping:objects.append({**a,'category_id':mapping[c]})
if names[c] in {'small-vehicle','large-vehicle'}:vehicles.append({**a,'category_id':4})
provenance=row.get('evaluation_role','train_diagnostic')
predictions.append({'sample_id':row['id'],'split':row['split'],'provenance':provenance,'annotations':objects})
target=detection_target(sample,provenance);target['split']=row['split'];targets.append(target)
vehicle_truth=[];vehicle_ignore=[]
for a in sample['ignored_annotations']:
if a.get('source_original_class')=='vehicle' and not a['source_difficult'] and a['visible_fraction']>=.7 and min(a['bbox'][2:])>=2:
vehicle_truth.append({**a,'category_id':4})
else:vehicle_ignore.append(a)
broad_predictions.append({'sample_id':row['id'],'annotations':vehicles})
broad_targets.append({'sample_id':row['id'],'annotations':vehicle_truth,'ignored_annotations':vehicle_ignore})
return {'predictions':predictions,'targets':targets,'broad_predictions':broad_predictions,'broad_targets':broad_targets,
'invalid_center_predictions_removed':invalid,'elapsed_seconds':time.monotonic()-start}
def score(pool,thresholds):
metrics=detection_metrics(pool['predictions'],pool['targets'],thresholds)
count=sum(len(r['annotations']) for r in pool['predictions'])
metrics['raw_predictions']=count
metrics['ignored_predictions_at_iou50']=count-metrics['ap']['true_positives']-metrics['ap']['false_positives']
return metrics
if __name__=='__main__':
from training.model_factory import configure_local_settings
configure_local_settings()
from ultralytics import YOLO
torch.set_num_threads(4);torch.manual_seed(42)
ext=Extension();rows=[r for r in ext.rows if r.get('evaluation_role')=='selection_validation']
output=ROOT/'evaluation/runs/2026-10-30-dior-baselines';output.mkdir(exist_ok=False)
thresholds=json.loads((ROOT/'model/model.json').read_text())['detection_thresholds']
report={'split':'selection_validation','sample_ids':[r['id'] for r in rows],
'extension_content_sha256':ext.approval['content_sha256'],'models':{},
'limitations':['Four exactly mapped classes only; broad vehicle metric is separate and cannot verify size-class correctness.',
'Unknown categories use conservative class-agnostic ignore polygons, which can suppress false positives.',
'Image-level duplicate screening does not establish geographic independence.','No held-out audit or original test predictions used.']}
for name in ['yolo26n-obb.pt','yolo26s-obb.pt']:
path=ROOT/'training/cache/checkpoints'/name
pool=predict(YOLO(str(path),task='obb'),ext,rows)
(output/(name+'.predictions.json')).write_text(json.dumps(pool))
report['models'][name]={'checkpoint_sha256':sha(path.read_bytes()),'metrics':score(pool,thresholds),'elapsed_seconds':pool['elapsed_seconds']}
print(name,report['models'][name]['metrics']['ap']['map50_95'],flush=True)
(output/'BASELINES.json').write_text(json.dumps(report,indent=2))

Xet Storage Details

Size:
4.44 kB
·
Xet hash:
8b78572cf57a2cdd35c0d317b52e8ce1dcc8d07ea4ac7e99f1e6234706b01ab3

Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.