今年,字节AI-Lab与复旦大学合作提出了一种中文文本纠错模型:Soft-Masked BERT[1].这项工作发表在了ACL 2020上,由于论文并没有开源代码,所以我将对这篇论文进行解读与复现。
问题提出:
中文文本纠错是一项挑战性的任务,因为模型要想获得令人满意的解决方案,就必须具备人类水平的语言理解能力。比如:
- eg1 Wrong:埃及有金子塔。Correct: 埃及有金字塔。
- eg2 Wrong: 他的求胜欲很强,为了越狱在挖洞。 Correct: 他的求生欲很强,为了越狱在挖洞。
- eg3 Wrong: 他主动拉了姑娘的手, 心里很高心。 Correct: 他主动拉了姑娘的手, 心里很高兴。
在Soft-Masked BERT被提出之前,最好的方法是先通过在句子的每个位置建立基于BERT的语言表示模型,再从候选字符列表中选择一个字符进行修正。然而,BERT使用了mask的方式进行预训练,没有足够的能力来检测每个位置是否存在误差(只有15%的错误被找出),所以这种方法的精度不够好。
Soft-Masked BERT解决方案:
使用两个网络模型,一个用于错误检测;另一个基于BERT进行纠错。
- Detection Network
Detection Network通过双向的GRU来实现:
输入
输出
那么文本序列中的每一个字符的错误概率计算公式为:
其中
构建Detection_Network中的网络层与实例化代码:
#构建Detection_Network网络层
- Soft Masking Connection
input embeddings
不难看出,上个步骤中得到的
构建Soft Masking Connection层代码
# 中文预训练的Bert模型词表,特殊符[MASK]在词表中的索引都为103
- Correction Network
该层主要的结构就是Bert模型,其中有12个Encoder层,以整个序列作为输入。每个block包含一个多头部的self-attention操作,然后接一个前馈网络:
取Bert模型中最后一层Encoder的所有隐藏状态与input embeddings对应相加进行残差连接(Residual Connection)得到残差连接值
接着将残差连接值
# bert嵌入、encoder、池化、权重.
- 训练
训练数据是原始序列对和修正序列对组成的元组
损失函数是由Detection Network的损失与Correction Network的损失函数线性相加构成:
系数
其中Detection Network与Correction Network的损失均为交叉熵损失,即:
实验结果
论文中使用的数据集有3个:
- Chinese Spelling Check Task(CSC)数据集:选择了其中《对外汉语测试》的作文部分(SIGHAN);
- News Title数据集:来自于今日头条app中的文章的标题部分;
- 5 million news titles数据集:从一些中文新闻app中爬取,该数据集只用来fine-tuning
其中公开数据集为Chinese Spelling Check Task数据集[2],包含1100个文本和461种错误(字符级别).
可以看出,在CSC数据集的测试中,Soft-Masked BERT模型的效果基本上都是比其他Baseline模型的效果要好。
而在Detection部分,HanSpeller++模型的精准率要高于Soft-Masked BERT模型的精准率,且Correction部分HanSpeller++模型的精准率也高于Soft-Masked BERT模型的精准率.
这是因为HanSpeller++模型中有许多人工添加的规则与特征,这些人工添加的规则与特征能在Detection部分过滤错误的识别,虽然这种人工规则与特征效果很好,但这种方式需要很多人工成本,而且泛化性也不好.
综上,在SIGHAN数据集的测试集上,Soft-Masked BERT模型的效果是最优的。
此外作者还用实验证明了:
- fine-tuning的数据集(在5 million news titles数据集上)的规模越大,fine-tuning之后的模型在CSC任务中的效果也会越好;
- 消融对比研究,证明该提出的模型每一部分都是不可或缺的.
关于以上内容:
完整代码以及更详细的注释(一行代码三行注释)已上传到github:wanglke/Soft-Masked-BERT
其中代码中用到的bert中文训练模型与config文件可以通过以下链接下载:
config文件下载:https://s3.amazonaws.com/models.huggingface.co/bert/bert-base-chinese-config.json
bert中文预训练模型:https://s3.amazonaws.com/models.huggingface.co/bert/bert-base-chinese-pytorch_model.bin
遗憾的是该论文的作者并没有对该论文中的算法进行开源,有对中文文本纠错感兴趣的小伙伴可以使用这个开源的中文纠错工具PYcorrector[3]:
pycorrectorgithub.com它不仅安装简单,同时支持加载自定义混淆集、英文拼写纠错,也支持加载kenlm、rnn_crf、seq2seq、BERT等各种模型。可以结合具体领域的fineturn,是一款可应用在工业级的中文纠错软件,可以满足大部分场景中的文本纠错需求.
问题探讨
那么中文纠错对下游NLP任务有没有影响?,在这里我就使用PYcorrector做了一个小实验,在一个文本分类任务中,我使用的数据集来自电商评论,其中有部分的错误
但在使用PYcorrector的时候,我发现PYcorrector确实能找出部分文本中的错误:
原句
但更多的是False Positive,比如以下:
原句
有这种结果是因为:
- 我使用默认的kenlm统计语言模型,要比深度学习模型要差;
- 更重要的是我使用的是单品类商品的评价文本,而且没有使用自己的数据做fine-tune,之后再使用通用型的 纠错模型纠错就会使模型"水土不服".
我把该部分数据在纠错前和纠错后以及分别放在相同的模型中(ALBERT+TextCNN[4])进行实验,得到如下的对比结果:
效果意料之中的变差了,虽然是次失败的尝试,但起码证明了效果差的纠错会对NLP下游任务造成负面影响。
后续我将会继续探讨纠错任务对下游NLP任务的影响,主要考虑使用深度学习模型在专门的语料上训练针对性模型
参考
- ^[1] https://arxiv.org/pdf/2005.07421.pdf
- ^http://ir.itc.ntnu.edu.tw/lre/sighan7csc.html
- ^https://github.com/shibing624/pycorrector
- ^https://zhuanlan.zhihu.com/p/164873441