BERT代码重构、分类实战及问题思考

久仰bert大名,终于痛下杀手对bert做一个从肉体到精神上的深入探究和了解

在参观了 https://github.com/google-research/berthttps://github.com/CyberZHG/keras-bert后,我也决定重写一份keras版本的keras-bert(https://github.com/yfyvan/keras-bert),毕竟,是吧,作为程序猿,最嗨皮的事就是欣赏别人的代码,最头疼的是就是迁移调用别人的代码,第二嗨皮的事就是别人迁移调用你的代码,第二头疼的是就是别人不会迁移也不会调用的你的代码。所以,我就安安静静的重构了一下楼上两位(主要以第二位为主)的代码,并去除了很多冗杂的操作,因为你要是想用bert模型和参数,大多数情况下你只能乖乖的使用人家训练好的参数。

重构完,我把本真模型参数和一些task数据传到oss上,让你一键下载、一键加载、一键建模- - 

bert的大致模型如下(为什么说大致,因为中间很多dropout、LN等操作就不细写了,详细模型大家可以去mode.png瞅一瞅,我给你们画出来了- -)

BERT代码重构、分类实战及问题思考

从黄色方框圈起来的以下的地方,其实我们都可以不用,以下都可以作为下游任务的分支

黄色方框输出了个[N, max_len, emb_dim]的矩阵,N表示批次、句子个数,max_len表示每个句子最大长度,最大不超过512,emb_dim就是嵌入的维度。

我们直接上代码玩吧https://github.com/yfyvan/keras-bert-projects

1、demo_predict_is_next_sentence.py

说明:用来预测两个句子是不是因果句子,比如:A:肚子饿了  B:咱们一起去吃饭吧。预测出来就是True(官方给的False,因为他们预测是“是不是随机的句子”,也就是是不是不匹配,所以返回False,我做了not操作)

这有什么用呢?最直接的一个产品,百度大会上,李彦宏一遍跟小度聊天,一遍跟我们聊天,跟我们聊天时小度不会有反应,让小度切歌时,小度能自动识别是在呼唤他- -,这种识别技术,跟bert的预测技术是异曲同工

2、demo_predict_mask_words.py

说明:预测挡住的词是什么。比如:今天**了,但是我没带伞。机器一般会预测出“下雨”两个字(我同事说,今天无语了,今天懵逼了,今天难受了。。。),这有什么用,语音纠错!

比如:siri听你讲话,你说“我要去湖南吃米粉”,然后由于你浓厚的口音,被识别成“我要去福南呲米粉”,后台在做实体识别或者字典查找时,发现“福南”的“福”(也有可能是“南”,反正挑一个进行纠错)字有可能是错的,于是置为“*”,同理“呲”也置为“*”,这时候就可以用如上方法进行纠错了

3、demo_extract_word_vector.py

说明:抽取字向量。输入一个字,抽取bert训练出来的字向量,方便我们后期进行其他任务的训练,就避免了embedding的训练过程

4、demo_extract_sentence_vector.py

说明:抽取句向量。这里抽取向量我用的是均值,https://github.com/CyberZHG/keras-bert这里用的是max,我个人感觉其实都可以,我只是在平时做向量时用均值比较多

 

5、task_emotion_recognition.py

情感识别、文本分类。说实话,我取了Extratc层,-1的attention,-2的attention层,-1的dense层,再加上自己的分类层,效果都不理想,最高也就80不到准确率,经常过拟合,也不乏欠拟合,非常难受,做了两天的测试,跟https://blog.csdn.net/rensihui/article/details/90648291这位博主的实验效果和结论异曲同工,直接比不上自己设计的分类网络。在此一边严重怀疑bert中文权重的稳定性,一方面也可能是我对bert的理解存在误区。在此广发英雄帖,望广大猿友给出一些解决方案。

 

最后:关于对keras-bert的一些代码优化。

1、scale层去掉,变成常规计算层。scale层只是做了相关数据变换,没有任何的权重参数更新,一次换成普通类

2、gelu函数使用官方的写法

3、Attention层使用tf函数做简化