平安科技举办2020中国大学生保险数字科技挑战赛的比赛在昨天落下帷幕,笔者在自然语言处理赛道的成绩是全榜第四,在这里做个比赛分享,记录一下历程。
1.1 数据
比赛数据是经过加密的对话数据,如下图。主办方需要我们设计一个算法去识别客户的对话意图,也就是一个多分类问题,客户意图的类别高达56类,存在极大的样本不均衡问题。
1.2 算法思路
主办方的数据既有字的id也有词的id,而当前自然语言处理最火的模型就是BERT,又因为有词id,我们不免想用(Whole Word Masking)这种策略去预训练一个bert_wwm模型,进而设计下游结构去完成意图识别的任务。
我们设计了6层的bert_wwm结构,然后对其预训练了120W + 步,得到了相应的bert_wwm模型。之后的下游任务和笔者在科技战疫·大数据公益挑战赛-情绪识别TOP3分享并没有什么不同,感兴趣的读者可以翻阅一下这篇分享,这里就不进行赘述了。
本次分享的重点并不在这,而是笔者预训练bert_wwm的过程中发现了wwm中文掩盖策略的硬伤。请注意,说的是wwm在中文掩盖策略的硬伤。
我们废话不多说,扣1直接开车。
1.3 WWM之殇
在这场比赛中,我们发现了Whole Word Masking在中文掩盖策略的问题。众所周知,wwm掩盖策略如下图所示,我们可以看到用wwm掩盖策略,我们掩盖了“模型”和“probability”。
对于英文“probability”:我们可以认为他被拆成了词根词缀的形式“pro”+ “##bab”+“##lity”,然后全部掩盖,这无可厚非。
不过,对于中文“模型二字”:源码中也是引用了英文一样的形式,将其拆分成“模”+“##型”,那么整个BERT字典vocab.txt就要多出一行来记录“##型”。
我们通过实验也可以看到,“型”和“##型”是对应字典里的两个id。
那么问题来了,我们预训练的时候,wwm掩盖的是“模”+“##型”,但是我们下游任务fine-tune的时候却是“模”+ “型”,也就是说,我们预训练学了这么久的“##型”竟然没用上!这就有点难顶了。
本着科学严谨的态度,笔者还对“模型”这个词进行了tokenize,得到的结果是“模”+“型”,而probability则是可以tokenize成“pro”+ “##ba” + “##bility”的形式。
到这里,我们就知道了即使使用官方自带的tokenize工具,中文词语切分出来的字也还是“模”+“型”。为此也证明了,我们在fine-tune过程中使用bert_wwm模型,其实并没有用对字。
那么有没有解决办法?有的!
我们在下游任务过程中,先对中文文本进行分词,然后将词语拆成“模”+ “##型”的形式,如此这般,convert_tokens_to_ids函数就能找到预训练常用的字了。
那为啥不能直接将“##型”代替“型”呢?当然不可以,有时候“型”字并不是单单出现在“模型”里面。就好比“南京”可以拆成“南”+ “##京”,但京东只能拆成“京”+ “##东”,虽然都是同一个字,但是embedding却是不一样的,当然也就不能相互替代。
1.4 总结
到这,比赛的总结也就写完了,其实每一场比赛都是对过去知识的巩固与加深,在这个过程中也会发现一些有意思的东西。
这几天笔者还会陆续更新笔者学到的一些NER类的算法,之前也更新了一篇命名实体识别的调研blog,后续的一篇是基于这个基础上又加了一些新的东西。本来是打算端午假期更新的,但是放假的时候,睡着的状态比醒着的时间还长(尴尬)。
关注我的微信公众号【阿力阿哩哩】~不定期更新相关专业知识~
喜欢就点个赞吧~