# 代码结构变动 MMOCR 为了兼顾文本检测、识别和关键信息提取等任务,在初版设计时存在许多欠缺考虑的地方。在本次 1.0 版本的升级中,MMOCR 同步提出了新的模型架构,旨在尽量与 OpenMMLab 整体的设计对齐,且在算法库内部达成结构上的统一。虽然本次升级并非完全后向兼容,但所有的变动都是有迹可循的。因此,我们在本章节总结出了开发者可能会关心的改动,供有需要的用户参考。 ## 整体改动 MMOCR 0.x 存在着对模块功能边界定义不清晰的问题。在 MMOCR 1.0 中,我们重构了模型模块的设计,并定义了它们的模块边界。 - 考虑到方向差异过大,MMOCR 1.0 中取消了对命名实体识别的支持。 - 模型中计算损失(loss)的部分模块被抽象化为 Module Loss,转换原始标注为损失目标(loss target)的功能也被包括在内。另一个模块抽象 Postprocessor 则负责在预测时解码模型原始输出为对应任务的 `DataSample`。 - 所有模型的输入简化为包含图像原始特征的 `inputs` 和图片元信息的 `List[DataSample]`。输出格式也得到统一,训练时是包含 loss 的字典,测试时的输出为包含预测结果的对应任务的 [`DataSample`](<>)。 - Module Loss 来源于 0.x 版本中实现与单个模型强相关的 `XXLoss` 类,它们在 1.0 中均被统一重命名为`XXModuleLoss`的形式(如`DBLoss` 被重命名为 `DBModuleLoss`), `head` 传入的 loss 配置参数名也从 `loss` 改为 `module_loss`。 - 与模型实现无关的通用损失类名称保持 `XXLoss` 的形式,并放置于 `mmocr/models/common/losses` 下,如 [`MaskedBCELoss`](mmocr.models.common.losses.MaskedBCELoss)。 - `mmocr/models/common/losses` 下的改动:0.x 中 `DiceLoss` 被重名为 [`MaskedDiceLoss`](mmocr.models.common.losses.MaskedDiceLoss)。`FocalLoss` 被移除。 - 增加了起源于 label converter 的 Dictionary 模块,它会在文本识别和关键信息提取任务中被用到。 ## 文本检测 ### 关键改动(太长不看版) - 旧版的模型权重仍然适用于新版,但需要将权重字典 `state_dict` 中以 `bbox_head` 开头的字段重命名为 `det_head`。 - 计算 target 有关的变换 `XXTargets` 被转移到了 `XXModuleLoss` 中。 ### SingleStageTextDetector - 原本继承链为 `mmdet.BaseDetector->SingleStageDetector->SingleStageTextDetector`,现在改为直接继承自 `BaseDetector`, 中间的 `SingleStageDetector` 被删除。 - `bbox_head` 改名为 `det_head`。 - `train_cfg`、`test_cfg`和`pretrained`字段被移除。 - `forward_train()` 与 `simple_test()` 分别被重构为 `loss()` 与 `predict()` 方法。其中 `simple_test()` 中负责将模型原始输出拆分并输入 `head.get_bounary()` 的部分被整合进了 `BaseTextDetPostProcessor` 中。 - `TextDetectorMixin` 中只实现了 `show_result()`方法,实现与 `TextDetLocalVisualizer` 重合,因此已经被移除。 ### Head - `HeadMixin` 为`XXXHead` 在 0.x 版本中必须继承的基类,现在被 `BaseTextDetHead` 代替。里面的 `get_boundary()` 和 `resize_boundary()` 方法被重写为 `BaseTextDetPostProcessor` 的 `__call__()` 和 `rescale()` 方法。 ### ModuleLoss - 文本检测中特有的数据变换 `XXXTargets` 全部移动到 `XXXModuleLoss._get_target_single` 中,与生成 target 相关的配置不再在数据流水线(pipeline)中设置,转而在 `XXXLoss` 中被配置。例如,`DBNetTargets` 的实现被移动到 `DBModuleLoss._get_target_single()`中,而用户可以通过设置 `DBModuleLoss` 的初始化参数来控制损失目标的生成。 ### Postprocessor - 原本的 `XXXPostprocessor.__call__()` 中的逻辑转移到重构后的 `XXXPostprocessor.get_text_instances()` 。 - `BasePostprocessor` 重构为 `BaseTextDetPostProcessor`,此基类会将模型输出的预测结果拆分并逐个进行处理,并支持根据 `scale_factor` 自动缩放输出的多边形(polygon)或界定框(bounding box)。 ## 文本识别 ### 关键改动(太长不看版) - 由于字典序发生了变化,且存在部分模型架构上的 bug 被修复,旧版的识别模型权重已经不再能直接应用于 1.0 中,我们将会在后续为有需要的用户推出迁移脚本教程。 - 0.x 版本中的 SegOCR 支持暂时移除,TPS-CRNN 会在后续版本中被支持。 - 测试时增强(test time augmentation)在此版本中暂未支持,但将会在后续版本中更新。 - Label converter 模块被移除,里面的功能被拆分至 Dictionary, ModuleLoss 和 Postprocessor 模块中。 - 统一模型中对 `max_seq_len` 的定义为模型的原始输出长度。 ### Label Converter - 原有的 label converter 存在拼写错误 (label convertor),我们通过删除掉这个类规避了这个问题。 - 负责对字符/字符串与数字索引互相转换的部分被提取至 [`Dictionary`](mmocr.models.common.Dictionary) 类中。 - 在旧版本中,不同的 label converter 会有不一样的特殊字符集和字符序。在 0.x 版本中,字符序如下: | Converter | 字符序 | | ------------------------------- | ----------------------------------------- | | `AttnConvertor`, `ABIConvertor` | ``, ``, ``, characters | | `CTCConvertor` | ``, ``, characters | 在 1.0 中,我们不再以任务为边界设计不同的字典和字符序,取而代之的是统一了字符序的 Dictionary,其字符序为 characters, \, \, \。`CTCConvertor` 中 \ 被等价替换为 \。 - `label_convertor` 中原本支持三种方式初始化字典:`dict_type`、`dict_file` 和 `dict_list`,现在在 `Dictionary` 中被简化为 `dict_file` 一种。同时,我们也把原本在 `dict_type` 中支持的字典格式转化为现在 `dicts/` 目录下的预设字典文件。对应映射如下: | MMOCR 0.x: `dict_type` | MMOCR 1.0: 字典路径 | | ---------------------- | -------------------------------------- | | DICT90 | dicts/english_digits_symbols.txt | | DICT91 | dicts/english_digits_symbols_space.txt | | DICT36 | dicts/lower_english_digits.txt | | DICT37 | dicts/lower_english_digits_space.txt | - `label_converter` 中 `str2tensor()` 的实现被转移到 `ModuleLoss.get_targets()` 中。下面的表格列出了旧版与新版方法实现的对应关系。注意,新旧版的实现并非完全一致。 | MMOCR 0.x | MMOCR 1.0 | 备注 | | --------------------------------------------------------- | --------------------------------------- | -------------------------------------------- | | `ABIConvertor.str2tensor()`, `AttnConvertor.str2tensor()` | `BaseTextRecogModuleLoss.get_targets()` | 原本两个类中的实现存在的差异在新版本中被统一 | | `CTCConvertor.str2tensor()` | `CTCModuleLoss.get_targets()` | | - `label_converter` 中 `tensor2idx()` 的实现被转移到 `Postprocessor.get_single_prediction()` 中。下面的表格列出了旧版与新版方法实现的对应关系。注意,新旧版的实现并非完全一致。 | MMOCR 0.x | MMOCR 1.0 | | --------------------------------------------------------- | ------------------------------------------------ | | `ABIConvertor.tensor2idx()`, `AttnConvertor.tensor2idx()` | `AttentionPostprocessor.get_single_prediction()` | | `CTCConvertor.tensor2idx()` | `CTCPostProcessor.get_single_prediction()` | ## 关键信息提取 ### 关键改动(太长不看版) - 由于模型的输入发生了变化,旧版模型的权重已经不再能直接应用于 1.0 中。 ### KIEDataset & OpensetKIEDataset - 读取数据的部分被简化到 `WildReceiptDataset` 中。 - 对节点和边作额外处理的部分被转移到了 `LoadKIEAnnotation` 中。 - 使用字典对文本进行转化的部分被转移到了 `SDMGRHead.convert_text()` 中,使用 `Dictionary` 实现。 - 计算文本框之间关系的部分`compute_relation()` 被转移到 `SDMGRHead.compute_relations()` 中,在模型内进行。 - 评估模型表现的部分被简化为 `F1Metric`。 - `OpensetKIEDataset` 中处理模型边输出的部分被整理到 `SDMGRPostProcessor`中。 ### SDMGR - `show_result()` 被整合到 `KIEVisualizer` 中。 - `forward_test()` 中对输出进行后处理的部分被整理到 `SDMGRPostProcessor`中。 ## Utils 变动 原本散布在各处的功能函数现已被统一归类在 `mmocr/utils/` 下。以下为该目录下各文件的作用域: - bbox_utils.py:四边界定框(bounding box)有关的功能函数。 - check_argument.py:检查参数类型的功能函数。 - collect_env.py:收集运行环境的功能函数。 - data_converter_utils.py:用于数据集转换的功能函数。 - fileio.py:输入/输出有关的功能函数。 - img_utils.py:处理图片的功能函数。 - mask_utils.py:与掩码有关的功能函数。 - ocr.py:用于 MMOCR 推理的功能函数。 - parsers.py:解码文件的功能函数。 - polygon_utils.py:多边形的功能函数。 - setup_env.py:存放初始化 MMOCR 的功能函数。 - string_utils.py:存放字符串的功能函数。 - typing.py:存放 MMOCR 中常用数据类型的缩写。