上海电视剧频道,城市文化的荧屏窗口
4
2024 / 12 / 24
比赛链接: 互联网金融新实体发现.
本博客主要参考他的文章和代码: 阿力阿哩哩.感兴趣的话可以关注他的知乎、公众号以及B站账号。
(1)硬件环境:
操作系统:windows 10或者 linux(Ubuntu 16~18) (本人使用的windows 10)
硬件配置:主要是显卡要求:1660Ti 6G(最起码要保证有一个显卡)
(2)软件环境:
这里最好自己创建一个虚拟环境,然后在里面配置一下各种库的版本。
(1)实验流程
(2)代码结构
preprocess/preprocess.py: 对原始数据进行预处理,包含数据清洗、数据切割、数据格式转换
model.py:单模构建代码,包含BERT+BILISTM-CRF、BERT+IDCNN-CRF
utils.py:DataIterator数据迭代器, 用于生成batch数据喂入模型
train_fine_tune.py:模型的训练(即模型参数微调)
predict.py:模型预测(微调好的模型用于测试集的预测)
ensemble/ensemble.py:对predict.py模型生成的文件进行复原,生成单模的文字预测结果
bert/tokenization.py:BERT源码分词工具
tf_utils文件夹:BERT源码的修改以及CRF等的开源代码
config.py:超参数设置和预训练模型等的路径设置
optimization.py:参数优化器
post_process文件夹:
[1] get_ensemble_final_result.py: 对ensemble.py生成的单模文字结果进行拼接,因为在预处理的时候将测试集切成了多份。
[2] post_ensemble_final_result.py: 对get_ensemble_final_result.py 生成的文件进行后处理,得到最终的单模文字结果
(1)首先查看一下原始数据:
样本数据包含文本标识号(ID)、题目(title)、正文(text)、识别出的未知实体(unknownEntity)四列,这个阶段需要做的事情就是要将数据样本处理成BIEO或BIO等格式。预处理之后的数据格式如下:
(2)代码解析
-将数据中标题和文本合并,数据中的实体主要在title和text上
在机器学习中数据的质量直接决定了任务的天花板,而模型和算法只是无限的去接近这个天花板,本文对前期的数据处理进行了详细的介绍。最终在pycharm中运行结果如下图所示:
在本地data/process_data中生成了我们需要的文件:
在将数据处理成标准的BIO标注格式后,需要使用数据迭代器将数据喂给模型中,虽然所一般情况下可以将很多数据直接读入内存中,但是对于一些较大的神经网络或晕训练模型时,数据量往往较大,我们需要分批次将数据送入后去的神经网络中。
NER一直是NLP领域中的研究热点,从早期基于词典和规则的方法,到传统机器学习的方法,到近年来基于深度学习的方法,NER研究进展的大概趋势大致如下图所示:
当时的源代码作者尝试了BERT+BILSTM+CRF、BERT+IDCNN+CRF、动态权重融合BERT+IDCNN/BILSTM+CRF。
(1)BERT+BILSTM+CRF
在预训练模型BERT未出现之前,BILSTM-CRF就是一种比较流行的命名实体识别框架,这里将BERT的token向量(即含有上下文信息的词向量)喂到BILSTM中,BILSTM可以进一步提取特征,CRF可以更好的学习到标签之间的约束关系。网络模型一般输出的是一个句子的每个字的分类,不能够较好的考虑该字左右两边的结果,比如小明,小(B-PER)明(I-PER),可能会预测成小(B-PER)明(B-PER),而CRF可以避免这种情况,比如B-PER后面只能是I-PER或者O类标签。感兴趣的话可以参考这篇文章 博客.
BERT+BILSTM+CRF的结构如下图所示:
(2)BERT+IDCNN+CRF
IDCNN(Iterated Dilated Convolutional Neural Networks)迭代空洞卷积神经网络,和传统的CNN相比,IDCNN可以较好的捕捉更长的上下文信息,和时序模型LSTM相比,IDCNN可以实行并行化运算,大大提高了模型的运算速度,这里不再对 IDCNN模型进行赘述,感兴趣的话可以参考以下几篇文章:
【1】IDCNN for NER论文阅读笔记: 链接.
【2】如何理解空洞卷积(dilated convolution): 链接1.
【3】如何理解空洞卷积(dilated convolution): 链接2.
BERT+IDCNN+CRF的结果如下图所示:
本文采用的是当时IDCNN作者默认的模型参数,各层的dilation为[1,1,2],卷积核参数为3x3
(3)动态融合的BERT+IDCNN+CRF
BERT的每一层编码对文本都有着不同的理解,本文将BERT的12层编码赋予了不同的权重,初始化公式按照如下公式进行初始化:
然后通过训练来确定权重,并将每一层的表示进行加权平均,在后接一层全连接层降维至512维(BERT可以接收的最大序列长度),公式如下:
式中represent i 为BERT每一层输出的表示,ai 为权重BERT每一层表示的权重值。
动态融合的BERT结构图如下图所示:
后续将512维的向量输入BILSTM/IDCNN-CRF模型即可。
(4)代码实现
-动态融合BERT和原生BERT代码:
【注意】这里的BERT代码直接调用bert_modeling库(该库来源于官方库)
模型的训练模型参数微调和模型保存。
训练过程的结果如下图所示:
本次实验使用的是6G的显卡,batch_size设置为2,训练完一个epoch大概花费了两个小时左右,最终会在model/runs_0路径下生成训练好的模型:
先通过运行check_F1.py查看最优的预测模型,而后读取模型,再通过之前在model.py给每一个变量设置的变量名得到我们需要的变量,这样做的好处是无需重新构建模型图,只要抽取我们预测所需要的变量即可完成任务,一定程度上对我们的模型代码进行了加密。最后我们对测试集进行预测,并保存所需的预测概率。预测的代码结构和训练的代码相差不大
预测的结果如下图所示,后续需要对该文件进行后处理:
会在该路径下生成测试文件:
对多个异构单模的文字结果投票进行多模融合。具体的融合思路如下图所示。我们通过模型构建部分获得了多个异构模型,我们选择高召回率的模型进行单模预测,并将得到的单模结果进行文字投票融合得到最终结果
(1)自建库或者别人写的非官方库(这里的官方库指的是可以pip/conda install的那种)在pycharm环境中一定要设置成Resource root这样在调用该库时不会报错。
设置成功后,该文件夹为蓝色,设置过程如下:
(2)注意初始化文件config.py中一些模型的路径问题:
这里建议最好使用“/”而不是windows 文件路径的“”,因为“”容易被理解成转义字符
(3)原作者没有给出BERT官方的预训练模型,官方给出了多种不同的BERT模型,这里可以选择合适的模型,放在相应路径即可。下载速度慢的可以参考:https://gitee.com/cheng_jinpei/bert
(4)由于笔者水平和经验有限,该解析文件肯定存在一些漏洞,欢迎大家进行批评与指正