sakha-ocr / src /postprocess.py
loalkota's picture
Детектор строк и распознаватель якутского текста с рецептом обучения
d4d4e7b verified
Raw History Blame Contribute Delete
3.09 kB
"""Постобработка распознанного текста словарём якутского языка.
Прямое исправление текста спеллчекером вредит: на 5400 реальных строках оно
подняло долю ошибок с 0.24% до 0.89%, испортив 838 строк против 44 улучшенных.
Спеллчекер не видит изображение и «чинит» имена, русские вставки и обрывки
слов на переносах.
Поэтому словарь здесь только предлагает кандидатов, а решение принимает сама
сеть: замена принимается, если выигрыш языковой модели перевешивает потерю
по CTC. При весе 1.0 такая постобработка не испортила ни одной строки ни на
одной из проверочных выборок, снимая при этом 5–8% ошибок там, где
распознаватель слаб.
Пакет sakhaspell необязателен: без него обработка просто не применяется.
"""
import os
ALPHA = float(os.environ.get("SAKHA_LM_ALPHA", "1.0"))
_state = {"ready": False, "rescore": None}
def _load():
if _state["ready"]:
return _state["rescore"]
_state["ready"] = True
try:
import sakhaspell # noqa: F401
except ImportError:
return None
try:
from lm_rescore import Rescorer
except ImportError:
return None
_state["rescore"] = Rescorer
return Rescorer
class Corrector:
"""Ленивая обёртка: словарь и языковая модель грузятся при первом вызове."""
def __init__(self, charset, alpha=ALPHA):
self.charset = charset
self.alpha = alpha
self._r = None
self._tried = False
def available(self):
if not self._tried:
self._tried = True
cls = _load()
if cls is not None:
try:
self._r = cls(self.charset, alpha=self.alpha)
except Exception:
self._r = None
return self._r is not None
def __call__(self, texts, logprobs):
"""Строки идут в порядке чтения, поэтому перенос виден по предыдущей."""
if not self.available():
return texts
out, prev_hyphen = [], False
for t, lp in zip(texts, logprobs):
if not t or lp is None:
out.append(t)
prev_hyphen = bool(t) and t.rstrip().endswith(("-", "\u2010", "\u2011"))
continue
try:
out.append(self._r(lp, t, prev_hyphen=prev_hyphen))
except Exception:
out.append(t)
prev_hyphen = t.rstrip().endswith(("-", "\u2010", "\u2011"))
return out