NLP-Beginner 任务四:基于LSTM+CRF的序列标注+pytorch

传送门

NLP-Beginner 任务传送门

我的代码/数据集传送门

原数据集介绍传送门

特征提取预训练模型

主要参考论文:Neural Architectures for Named Entity Recognition

辅助参考论文:End-to-end Sequence Labeling via Bi-directional LSTM-CNNs-CRF

一. 介绍

1.1 任务简介

本次的NLP(Natural Language Processing)任务是对一个英文句子进行序列标注,例子如下

1.2 数据集

我的代码/数据集传送门

原数据集介绍传送门

例子

原数据
EU NNP B-NP B-ORG
rejects VBZ B-VP O
German JJ B-NP B-MISC
call NN I-NP O
to TO B-VP O
boycott VB I-VP O
British JJ B-NP B-MISC
lamb NN I-NP O
. . O O
输入文本: EU rejects German call to boycott British lamb.
输出序列: B-ORG O B-MISC O O O B-MISC O O

原数据
Peter NNP B-NP B-PER
Blackburn NNP I-NP I-PER
输入文本: Peter Blackburn
输出序列: B-PER I-PER

1.3 原数据解释

The first item on each line is a word, the second a part-of-speech (POS) tag, the third a syntactic chunk tag and the fourth the named entity tag.

每行第一项是单词,第二项是POS标签,第三项是语法块标签,第四项是命名实体标签,也就是我们本次的任务。

具体命名实体的每一个标签代表的意思,可以参考原数据集介绍

数据集共有三个文件:train.txt, test.txt 和 dev.txt。由于文件数据的组织方式比较松散,因此需要预处理,并且需要去掉文件中所有的:-DOCSTART- -X- -X- O(代表某一个文档开始)

二. 特征提取——Word embedding(词嵌入)

请参考NLP任务二

本次实战除了给定的各种序列类别之外,还要另外多加3个类别,分别是: < pad >,< start >,< end >,分别代表padding(即补位,使句子达到同一个长度),句子开头和句子结尾,总共C类标签。

三. 神经网络(LSTM+CRF)

本部分详细内容可以参考论文:Neural Architectures for Named Entity Recognition

3.1 LSTM层

在这里插入图片描述
在这里插入图片描述

3.2 CRF层(条件随机场Conditional Random Field)

在这里插入图片描述

3.2.1 转移矩阵 T r a n Tran Tran 初始化

注意:

  • 句子开头< start >不可能到达< start >
  • < end >代表句子结尾,不能再转移
  • -< pad > 表示padding(即补位,使句子达到同一个长度)也只能转移到< pad >。

3.2.2 CRF(最困难的部分)

首先我们先明确一下目标,在LSTM层过后我们得到了得分矩阵 S S S,我们还要从输入 X X X得到一个loss(损失),从而优化整个网络的参数,而从 X X X得到loss的中间部分则是CRF层。

对于每一个句子 X X X,需要计算的数值如下:

  • 真实得分:对真正序列 y y y的得分
  • 全部得分:对于所有序列 y ~ \tilde{y} y~的得分
  • softmax得分: e T r u e _ s c o r e ( X , y ) ∑ y ~ e s c o r e ( X , y ~ ) = e T r u e _ s c o r e ( X , y ) T o t a l _ s c o r e \frac{e^{True\_score(X,y)}}{\sum_{\tilde{y}} e^{score(X,\tilde{y})}}=\frac{e^{True\_score(X,y)}}{Total\_score} y~escore(X,y~)eTrue_score(X,y)=Total_scoreeTrue_score(X,y),这个得分越高,就证明真正序列y的得分占比越大,而其它所有序列的指数加和占比越小,也就是说我们的模型更加正确。
  • Loss:loss一般是越小越好,而softmax得分是越大越好,且比值方式可以利用 l o g log log性质变成减法,因此取 l o s s = − log ⁡ ( s o f t m a x ) = T r u e _ s c o r e ( X , y ) − log ⁡ ( T o t a l _ s c o r e ) loss=-\log (softmax)=True\_score(X,y)-\log{(Total\_score)} loss=log(softmax)=True_score(X,y)log(Total_score)得分
3.2.2.1 真实得分——对应CRF.true_prob

S S S T r a n Tran Tran 可以直接计算,非常简单,求和即可。
在这里插入图片描述

3.2.2.2 全部得分——对应CRF.total_prob(难点)

在这里插入图片描述

我们可以看到,我们需要计算所有序列 y ~ \tilde{y} y~的得分,如果一个句子的长度为 T T T,一共 C C C类标签,那么我们就有 C T C^T CT种情况需要遍历,这个复杂度是非常高的,代价非常大,因此参考了网上的方法,采用动态规划(DP)的思想进行计算(非常难以理解)

具体请参考代码。

3.2.2.3 Loss

直接计算 l o s s = T r u e _ s c o r e ( X , y ) − log ⁡ ( T o t a l _ s c o r e ) loss=True\_score(X,y)-\log{(Total\_score)} loss=True_score(X,y)log(Total_score)

3.2.2.4 预测序列——对应CRF.predict(难点)

除了训练网络参数,我们还需要进行预测,以在测试集上进行测试。

预测无非就是在所有序列得分中找到最大得分的序列,因此一开始的想法是遍历 C T C^T CT种情况,但显然复杂度非常高,因此采用非常常见且高效的动态规划算法——viterbi算法(建议先了解算法本身)。

具体请参考代码。

四. 代码及实现

4.1 实验设置

  • 样本个数:train.txt与test.txt
  • 训练集:测试集 : train.txt与test.txt
  • 特征提取:Random / GloVe Embedding
  • 学习率:10-3
  • l h ,   l f l_h,\ l_f lh, lf:50
  • Batch 大小:128
  • 训练轮数:50

4.2 结果展示

指标:单个句子的标注正确率的平均
比如:一个句子无论多少个词,只有标全对了,才记为1分,否则0分。

可以看到GloVe初始化比随机初始化明显地好,标注正确率随机最多只有55%,而GloVe最高能到76.23%,性能比较好。
在这里插入图片描述

五. 总结

自己编写CRF难度是非常大的,因此建议多去网上寻找相关的讲解,还有一种“逃课”的方法是,直接调包,好像pytorch是有现成的CRF包的,直接调用可以解决许多问题。

标注正确率不到80%其实不太高,模型有待改进,比如增大 l h 和 l f l_h和l_f lhlf,更精确的指标可以参考原本论文的指标 F 1 F_1 F1

以上就是本次NLP-Beginner的任务四,全文难点在于全部得分预测序列,需要多加琢磨。

谢谢各位的阅读,欢迎各位对本文章指正或者进行讨论,希望可以帮助到大家!

六. 自我推销

  • 8
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值