Buckets:
| """Inspect high-confidence development false positives against labeled boxes.""" | |
| import argparse | |
| from collections import Counter, defaultdict | |
| import json | |
| from pathlib import Path | |
| from shapely.geometry import Polygon | |
| from evaluation.metrics import _match_class | |
| def geometry(points): | |
| return Polygon(list(zip(points[::2], points[1::2]))).buffer(0) | |
| def main(): | |
| parser = argparse.ArgumentParser() | |
| parser.add_argument("records", type=Path) | |
| parser.add_argument("comparison", type=Path) | |
| parser.add_argument("output", type=Path) | |
| args = parser.parse_args() | |
| rows = json.loads(args.records.read_text())["candidate"] | |
| previous = json.loads(args.comparison.read_text())["results"]["initial"]["selection_precision_99_frontier"] | |
| targets = {row["sample_id"]: row for row in rows["targets"]} | |
| ignored = {sid: row.get("ignored_annotations", []) for sid, row in targets.items()} | |
| result = {} | |
| for cls in (4, 5): | |
| threshold = previous[str(cls)]["best"]["threshold"] | |
| truth = {sid: [a for a in row["annotations"] if int(a["category_id"]) == cls] | |
| for sid, row in targets.items()} | |
| pool = [(row["sample_id"], a) for row in rows["predictions"] for a in row["annotations"] | |
| if int(a["category_id"]) == cls] | |
| scores, _, _ = _match_class(pool, truth, ignored, .5, ignore_prediction_fraction=.5) | |
| by_score = defaultdict(list) | |
| for sid, prediction in pool: | |
| by_score[float(prediction["confidence"])].append((sid, prediction)) | |
| errors, ambiguous = [], 0 | |
| for score, positive in scores: | |
| if score < threshold or positive: | |
| continue | |
| if len(by_score[score]) != 1: | |
| ambiguous += 1 | |
| continue | |
| sid, prediction = by_score[score][0] | |
| poly = geometry(prediction["obb_polygon"]) | |
| nearest = {"same_class_iou": 0.0, "other_class_iou": 0.0, "other_class_id": None} | |
| for target in targets[sid]["annotations"]: | |
| other = geometry(target["obb_polygon"]) | |
| union = poly.union(other).area | |
| iou = poly.intersection(other).area / union if union else 0.0 | |
| if int(target["category_id"]) == cls: | |
| nearest["same_class_iou"] = max(nearest["same_class_iou"], iou) | |
| elif iou > nearest["other_class_iou"]: | |
| nearest["other_class_iou"] = iou | |
| nearest["other_class_id"] = target["category_id"] | |
| errors.append({"sample_id": sid, "confidence": score, "obb_polygon": prediction["obb_polygon"], **nearest}) | |
| buckets = Counter("same_class_iou>=0.5" if e["same_class_iou"] >= .5 else | |
| "same_class_iou>=0.1" if e["same_class_iou"] >= .1 else | |
| "other_class_iou>=0.1" if e["other_class_iou"] >= .1 else "no_labeled_overlap>=0.1" | |
| for e in errors) | |
| result[str(cls)] = {"threshold_from_initial_selection": threshold, "false_positive_count": len(errors), | |
| "ambiguous_tied_scores": ambiguous, "categories": dict(buckets), "errors": errors} | |
| with args.output.open("x") as stream: | |
| json.dump(result, stream, indent=2) | |
| stream.write("\n") | |
| print(json.dumps({key: {k: v for k, v in value.items() if k != "errors"} for key, value in result.items()})) | |
| if __name__ == "__main__": | |
| main() | |
Xet Storage Details
- Size:
- 3.45 kB
- Xet hash:
- b54cfa55ef8b95320bf618493ba837cb5cec48aaa169552d55209147ff679d58
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.