专栏名称: 天池大数据科研平台
天池,基于阿里云的开放数据处理服务ODPS,面向学术界开放海量数据和分布式计算资源,旨在打造“数据众智、众创”第一平台。在这里,人人都可以玩转大数据,共同探索数据众创新模式。
目录
相关文章推荐
大数据分析和人工智能  ·  人到中年才懂:能上班是福气 ·  昨天  
软件定义世界(SDX)  ·  与孙正义对话,Sam ... ·  2 天前  
数据派THU  ·  【ICLR2025】无噪声自我运动与噪声视频 ... ·  13 小时前  
大数据分析和人工智能  ·  35岁被优化,经济压力大,看DeepSeek ... ·  3 天前  
大数据分析和人工智能  ·  用DeepSeek帮我接财神 ·  4 天前  
51好读  ›  专栏  ›  天池大数据科研平台

我的BERT!改改字典,让BERT安全提速不掉分(已开源)

天池大数据科研平台  · 公众号  · 大数据  · 2020-10-14 18:44

正文

↑↑↑关注后" 星标 "天池大数据科研平台

人人都可以玩转大数据

阿里云天池严选

来源:夕小瑶的卖萌屋  文:苏剑林 编:小


背景

当前,大部分中文预训练模型都是 以字为基本单位 的,也就是说中文语句会被拆分为一个个字。中文也有一些多粒度的语言模型,比如创新工场的ZEN和字节跳动的AMBERT,但这类模型的基本单位还是字,只不过想办法融合了词信息。目前以词为单位的中文预训练模型很少,据笔者所了解到就只有腾讯UER开源了一个以词为颗粒度的BERT模型,但实测效果并不好。

那么,纯粹以词为单位的中文预训练模型效果究竟如何呢?有没有它的存在价值呢?最近,我们预训练并开源了 以词为单位的中文BERT模型 ,称之为 WoBERT (Word-based BERT,我的BERT!)。实验显示,基于词的WoBERT在不少任务上有它独特的优势,比如速度明显的提升,同时效果基本不降甚至也有提升。在此对我们的工作做一个总结。

开源地址
https://github.com/ZhuiyiTechnology/WoBERT

字还是词?

究竟是“字”好还是“词”好?这是中文NLP一个很让人抓狂的问题,也有一些工作去系统地研究这个问题。比较新的是香侬科技在ACL2019上发表的《Is Word Segmentation Necessary for Deep Learning of Chinese Representations?》,里边得到了字几乎总是优于词的结论。前面也说了,现在中文预训练模型确实也基本上都是以字为单位的。所以,看上去这个问题已经解决了?就是字更好?

事情远没有这么简单。就拿香侬科技的这篇论文来说,它的实验结果是没有错,但却是没有代表性的。为什么这样说呢?因为在该文的实验设置下,模型的embedding层皆从随机初始化状态开始训练。这样一来,对于同样的任务, 以词为单位的模型Embedding层参数更多 ,自然就更 容易过拟合 ,效果容易变差,这不用做实验都能猜个大概。问题是,我们用基于词的模型的时候,通常并不是随机初始化的,往往都是用预训练好的词向量的(下游任务看情况选择是否微调词向量),这才是分词的NLP模型的典型场景,但论文里边却没有比较这个场景,所以论文的结果并没有什么说服力。

事实上, “过拟合”现象具有两面性 ,我们要防止过拟合,但过拟合也正好说明了模型拥有比较强的拟合能力,而如果我们想办法抑制过拟合,那么就 能够在同样复杂度下得到更强的模型 ,或者在同样效果下得到更低复杂度的模型。而缓解过拟合问题的一个重要手段就是 更充分的预训练 ,所以不引入预训练的比较对以词为单位的模型来说是不公平的,而我们的 WoBERT正是证实了以词为单位的预训练模型的可取性

词的好处

一般认为,以字为单位的好处是:

  1. 参数更少, 不容易过拟合
  2. 不依赖于分词算法, 避免边界切分错误
  3. 没那么严重的稀疏性, 基本上不会出现未登录词

至于以词为单位的理由是:

  1. 序列变短, 处理速度更快
  2. 在文本生成任务上,能 缓解Exposure Bias 问题;
  3. 词义的不确定性更低, 降低建模复杂度

对于词的好处,大家可能会有些疑惑。比如第2点,词能缓解Exposure Bias,这是因为理论上来说,序列越短Exposure Bias问题就越不明显(词模型单步预测出一个n字词,相当于字的模型预测了n步,这n步都递归依赖,所以字的模型Exposure Bias问题更严重)。至于第3点,虽然有多义词的存在,但是多数词的含义还是比较确定的,至少比字义更加明确,这样一来可能只需要一个Embedding层就能把词义建模好,而不是像字模型那样,要通用多层模型才能把字组合成词。

看起来不相伯仲,但事实上以字为单位的好处,并非就是以词为单位的缺点了。只要多一些技巧, 以词为单位也能一定程度上避免这几个问题 。比如:

  1. 以词为单位的参数确实增多了,但是可以 通过预训练来缓解过拟合 ,所以这个问题不会很严重;
  2. 依赖分词算法是个问题,如果我们 只保留最常见的一部分词 ,那么不管哪个分词工具分出来的结果都是差不多的,差异性不大;
  3. 至于边界切分错误,这个难以避免,但是 需要准确的边界的,只是序列标注类任务而已 ,文本分类、文本生成其实都不需要准确的边界,因此不能就此否定词模型;
  4. 如果我们 把大部分字也加入到词表中 ,也不会出现未登录词。

所以,其实用词的好处是相当多的,除了需要非常精确边界的序列标注类型的任务外,多数NLP任务以词为单位都不会有什么问题。因此,我们就去做了以词为单位的BERT模型了。

Tokenizer

往BERT里边加入中文词,首先得让Tokenizer能分出词来。只需要把词加入到字典vocab.txt里边就行了吗?并不是。BERT自带的Tokenizer会强行把中文字符用空格隔开,因此就算你把词加入到字典中,也不会分出中文词来。此外,BERT做英文word piece的分词的时候,使用的是最大匹配法,这对中文分词来说精度也不够。

为了分出词来,我们修改了一下BERT的Tokenizer, 加入了一个“前分词(pre_tokenize)”操作 。这样我们就可以分出中文词来,具体操作如下:

  1. 把中文词加入到vocab.txt;
  2. 输入一个句子s,用pre_tokenize先分一次词,得到
  3. 遍历各个 ,如果 在词表中则保留,否则将 用BERT自带的tokenize函数再分一次;
  4. 将每个 的tokenize结果有序拼接起来,作为最后的tokenize结果。

在bert4keras>=0.8.8版本中, 实现上述改动只需要在构建Tokenizer的时候传入一行参数 ,例如:







请到「今天看啥」查看全文