Bert源码修改完成多分类任务

(作者:陈玓玏 data-master)

一直以来,我自己处理文本分类都是用的正则,但正则需要经常去维护,短信模板如果更新了,就需要考虑把新模板加到正则表达式中。这样其实挺费神的,虽然我们可以使用pyltp对文本做一些机构名/人名的替换,然后将文本去重,清洗出相对好提取正则的模板,但分类和消息来源多了之后,需要处理,测试的模板量还是很大的,所以就想,能不能把已经用正则进行分类的文本,以及正则判别出的分类做label,然后用bert进行文本分类,这样就不需要自己手动去更新正则表达式啦。

但是关于bert,网上有好多种使用方式,有苏剑林大神开发的bert4keras,网上找的代码也跑成功了,但是你始终还是不知道比较细节的部分。因此,就想找一个能够使用源码进行建模的脚本。官方文档附在这里:https://github.com/google-research/bert

官方文档其实写得很清楚了,做分类任务,只需要看Sentence (and sentence-pair) classification tasks这个小节,我们看重点部分:

export BERT_BASE_DIR=/path/to/bert/uncased_L-12_H-768_A-12
export GLUE_DIR=/path/to/glue

python run_classifier.py \
  --task_name=MRPC \
  --do_train=true \
  --do_eval=true \
  --data_dir=$GLUE_DIR/MRPC \
  --vocab_file=$BERT_BASE_DIR/vocab.txt \
  --bert_config_file=$BERT_BASE_DIR/bert_config.json \
  --init_checkpoint=$BERT_BASE_DIR/bert_model.ckpt \
  --max_seq_length=128 \
  --train_batch_size=32 \
  --learning_rate=2e-5 \
  --num_train_epochs=3.0 \
  --output_dir=/tmp/mrpc_output/

定义bert预训练好的模型路径为BERT_BASE_DIR(预训练好的模型官方文档里也有给出链接,可以自己找一下,我用的是哈工大的,https://github.com/ymcui/Chinese-BERT-wwm#中文模型下载,这个地址是在苏剑林的bert4keras的git上找到的),下载好的模型文件,解压后结构如下:
Bert源码修改完成多分类任务_第1张图片
bert_model.ckpt是checkpoint文件,记录模型的权重参数,包含三个文件(我之前下载过一个其他来源的预训练模型,还碰到过一个bug,ckpt三个文件读取的时候会统一读取,我之前一直读取不成功,因为我的.ckpt.data这个文件,名字是.ckpt(1).data,后来改成.ckpt也不行,显示tensorflow.python.framework.errors_impl.datalosserror: unable to open table file,这是因为ckpt文件没加载全,没把meta,index加载进来。解决方案参考:https://blog.csdn.net/Zhang_xi_xi_94/article/details/81293048。其实,ckpt就是三个文件的,只要保证中间没有多余的字符,三个文件二级后缀都一样。)

bert_model.json是网络结构,vocab.txt是模型的词典。

GLUE_DIR是输入样本的路径,bert源码里,能处理的输入数据类型是固定几种,如果你的输入数据类型不在其中,你需要自己写一个数据处理的processer,这就需要改源码了。自带的processer可以处理XNLI/MultiNLI/MRPC/CoLA数据集。

其余的参数就比较常规了。

具体到分类,可以直接像官网写的,新增一个自己的processer后,向脚本传参数直接调用脚本进行文本分类,也可以直接把run_classifier.py这个脚本copy一份,把各参数直接写在脚本中,(就是把参数写死),直接运行脚本,不传参。

运行要注意的一件事情是,bert中默认使用的是tpu,虽然有定义一个是否使用tpu进行模型训练的参数,但即使参数设置为False,代码中使用的Estimator是tf.contrib.tpu.TPUEstimatorSpec,当你只有cpu或gpu的时候,需要把这个部分改成tf.estimator.EstimatorSpec。

使用其实就这么些内容,至于微调是做什么,其实就是在预训练好的bert模型上,新加一层模型,用于实现你的任务,比如你做分类,就是在bert上新加一层softmax或sigmoid。

具体的代码实现,看https://github.com/javaidnabi31/Multi-Label-Text-classification-Using-BERT/blob/master/multi-label-classification-bert.ipynb这一篇,还有官网就好了,这个git可以直接用,没bug,只需要修改一下读数据的部分,官网是用来理解代码的。

代码改好之后,拿来训练,一开始我抽了不到3W条文本消息,标注好的,batch size是32,learning rate是4e-5,NUM_TRAIN_EPOCHS = 1.0,max_seq_length是128,并且我有11个分类,而我的train数据集上有11个不同分类的文本,但test上只有1个类别的,因为我并不是随机抽取的训练集和测试集。结果发现分类的效果不如正则。所以我调整了参数,把训练+测试样本增大到6W条,并且随机抽取训练和测试,保证两个数据集里样本都丰富,batch size改为256,learning rate增大到2e-5,NUM_TRAIN_EPOCHS = 2.0,max_seq_length改为50(因为我的都是短文本,大部分到不了128个字,如果转换成长度为128的向量,后面都是0,可能影响判断),效果就比正则划分的要好了,可以完全代替正则了。

参考资料:

  1. https://github.com/google-research/bert bert官方文档
  2. https://blog.csdn.net/HGlyh/article/details/106744286(用的苏剑林开发的bert4keras,实现相对简单,可以先尝试这一个)
  3. https://github.com/javaidnabi31/Multi-Label-Text-classification-Using-BERT/blob/master/multi-label-classification-bert.ipynb 根据官方的run_classifier.py改的做多分类的脚本,跟原始脚本还有点不一样,可能因为官方做了些修改,或者博主自己做了些修改吧
  4. https://blog.csdn.net/weixin_37947156/article/details/84877254 官方run_classifier.py的源码使用解析,有的内容和官方github上讲的重叠了
  5. https://github.com/ymcui/Chinese-BERT-wwm#%E4%B8%AD%E6%96%87%E6%A8%A1%E5%9E%8B%E4%B8%8B%E8%BD%BD(哈工大各种bert中文模型的下载,苏剑林的bert4keras桑下载的)

你可能感兴趣的:(深度学习,自然语言处理)