Fine-Tuning-HunyuanOCR / evaluate.py
stevafernandes's picture
Upload 247 files
2bc8d17 verified
Raw History Blame Contribute Delete
2.91 kB
"""Score predictions against ground truth: normalized edit distance and AURC.
AURC (area under the risk-coverage curve) follows Geifman & El-Yaniv (2017):
sort predictions by confidence descending, then average the running mean risk
(normalized edit distance) over all coverage levels. Lower is better. The
competition score is the mean of the date AURC and the locality AURC.
Usage:
python evaluate.py --predictions val_predictions.csv --truth-csv ../train.csv
"""
import argparse
import csv
from common import normalized_edit_distance
def aurc(risks: list[float], confidences: list[float]) -> float:
order = sorted(range(len(risks)), key=lambda i: -confidences[i])
# Average risk within equal-confidence groups so the result does not
# depend on input order among ties.
smoothed: list[float] = []
i = 0
while i < len(order):
j = i
while j < len(order) and confidences[order[j]] == confidences[order[i]]:
j += 1
group = [risks[idx] for idx in order[i:j]]
smoothed.extend([sum(group) / len(group)] * len(group))
i = j
total = 0.0
running = 0.0
for k, risk in enumerate(smoothed, start=1):
running += risk
total += running / k
return total / len(smoothed)
def main() -> None:
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument("--predictions", required=True)
parser.add_argument("--truth-csv", required=True)
args = parser.parse_args()
with open(args.truth_csv, encoding="utf-8") as f:
truth = {row["image_file"]: row for row in csv.DictReader(f)}
with open(args.predictions, encoding="utf-8") as f:
preds = list(csv.DictReader(f))
preds = [p for p in preds if p["image_file"] in truth]
if not preds:
raise SystemExit("no overlapping image_file between predictions and truth")
report = {}
for field in ("verbatimDate", "verbatimLocality"):
risks, confidences, exact = [], [], 0
for p in preds:
t = truth[p["image_file"]][field].strip()
risk = normalized_edit_distance(p[field], t)
risks.append(risk)
confidences.append(float(p[f"{field}_confidence"]))
exact += risk == 0.0
report[field] = {
"n": len(risks),
"exact_match": round(exact / len(risks), 4),
"mean_ned": round(sum(risks) / len(risks), 4),
"aurc": round(aurc(risks, confidences), 4),
}
for field, metrics in report.items():
print(
f"{field}: n={metrics['n']} exact={metrics['exact_match']} "
f"mean_ned={metrics['mean_ned']} aurc={metrics['aurc']}"
)
score = (report["verbatimDate"]["aurc"] + report["verbatimLocality"]["aurc"]) / 2
print(f"competition score (mean AURC, lower is better): {round(score, 4)}")
if __name__ == "__main__":
main()