Instructions to use kesha-humonen/runic-reader-2 with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- PEFT
How to use kesha-humonen/runic-reader-2 with PEFT:
Task type is invalid.
- Notebooks
- Google Colab
- Kaggle
File size: 3,470 Bytes
ed46c5d | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 | """Personal names that reach the translation from a photograph (reviewer 2, point 2; reviewer 1, point 1).
Name recall (capitalized words of the reference translation other than a stop list, as in analyze.py) for the
4B translator on reference transliterations and on the crop recognizer's output; by recognizer CER and for the most
confidently read photographs (mean token NLL of the recognizer output, as in Appendix C). Writes results/names_e2e.json.
"""
import json
import os
import re
import sys
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
import metrics # noqa: E402
ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
P = f"{ROOT}/preds"
KEEP = set(json.load(open(f"{ROOT}/data/leakfree.json"))["keep_test"])
STOP = {"May", "God", "Christ", "The", "This", "These", "He", "She", "They", "His", "Her", "And", "In", "I", "A",
"Holy", "Mary", "Lord", "Jesus", "Amen", "Saint", "St", "Gud", "Han", "Hon", "De", "Och", "Den", "Denna",
"Detta", "Dessa", "Kristus"}
def names(t):
return {w for w in re.findall(r"\b[A-ZÁÉÍÓÚÝÞÆØÖÄÅ][\w'-]+", t or "") if w not in STOP}
def load(n):
return {r["id"]: r for r in metrics.read(f"{P}/{n}.jsonl") if (r.get("row_id") or r["id"]) in KEEP}
def recall(rows):
hit = tot = 0
for r in rows:
ref = names(r["tgt"])
tot += len(ref)
hit += len(ref & names(r.get("pred")))
return dict(n=len(rows), names=tot, recall=100 * hit / max(tot, 1))
def precision(rows):
"""Share of names in the output that are names of the reference (the rest are wrong or invented names)."""
hit = tot = 0
for r in rows:
out = names(r.get("pred"))
tot += len(out)
hit += len(out & names(r["tgt"]))
return 100 * hit / max(tot, 1)
ocr = load("ocr_test_ocr4b_cropcut")
fo = load("e2e_ocr4b_cropcut_mt4b_fromocr")
fg = load("e2e_ocr4b_mixcut_mt4b_fromgold")
ids = [i for i in ocr if i in fo and i in fg]
cer = {i: 100 * metrics.cer_parts(ocr[i]["target"], ocr[i]["pred"])[0] / metrics.cer_parts(ocr[i]["target"], ocr[i]["pred"])[1] for i in ids}
res = {"all": {"from_reference": recall([fg[i] for i in ids]), "from_photo": recall([fo[i] for i in ids]),
"precision_from_reference": precision([fg[i] for i in ids]), "precision_from_photo": precision([fo[i] for i in ids])}}
for lo, hi in ((0, 25), (25, 50), (50, 75), (75, 1e9)):
s = [i for i in ids if lo <= cer[i] < hi]
res[f"cer_{lo}_{hi if hi < 1e9 else 'inf'}"] = {"from_reference": recall([fg[i] for i in s]), "from_photo": recall([fo[i] for i in s]),
"precision_from_photo": precision([fo[i] for i in s])}
sc = {r["id"]: r for r in metrics.read(f"{P}/score_test_ocr4b_cropcut.jsonl")}
key = next(k for k in ("nll", "mean_nll", "score") if k in next(iter(sc.values())))
order = sorted(ids, key=lambda i: (sc[i][key] if i in sc and sc[i][key] is not None else 1e9))
for f in (0.1, 0.2, 0.3, 0.5):
s = order[: round(f * len(order))]
res[f"top_{f}"] = {"from_reference": recall([fg[i] for i in s]), "from_photo": recall([fo[i] for i in s]),
"precision_from_photo": precision([fo[i] for i in s])}
json.dump(res, open(f"{ROOT}/results/names_e2e.json", "w"), indent=1)
for k, v in res.items():
print(f"{k:12s} " + " ".join(f"{a}={b['recall']:.1f}(n={b['n']},names={b['names']})" if isinstance(b, dict) else f"{a}={b:.1f}" for a, b in v.items()))
|