简单的NER模型实现——CRF+LSTM

记录从零到实现CRF+LSTM的整个过程

  1. 查找概述,了解实现的过程【1h30min】
  2. 建立模型【3h30min】
  3. 阅读代码,对于实现细节有进一步的了解【4h】
  4. 自己手动实现【】

背景知识

NER

神经网络成为可以有效处理许多NLP任务的模型。这类方法对于序列标注任务(如CWS、POS、NER)的处理方式是类似的,将token从离散one-hot表示映射到低维空间中成为稠密的embedding,随后将句子的embedding序列输入到RNN中,用神经网络自动提取特征Softmax来预测每个token的标签

缺点在于对于token打标签的时候是独立的分类,不能够直接利用上文已经预测的标签。

为了解决这个问题,提出LSTM+CRF模型做序列标注,在LSTM层后接入CRF层来做句子级别的标签预测,使得标注过程不再是对各个token独立分类。

LSTM

信息来源:《Neural Network Methods for NLP》

LSTM,即为Long Short-Term Memory,是目前最成功的RNN架构类型之一。

从名字可以看出,其设计的主要目的是解决RNN的梯度消失问题和梯度爆炸问题。门机制能够使得与记忆部分相关的梯度保留很长时间。因此,RNN能够在更长的序列中有更好的表现。

主要手段是首次引入门机制。所谓的门机制,简单来说,就是利用一个0-1列向量,通过hadamard乘积来控制对于历史/记忆的获取。
具体来说,LSTM架构将状态向量 s i s_i si分成两部分,一部分称之为memory cell c i c_i ci,被设计用来保存记忆,每次计算的时候通过忘记门向量f控制记忆的获取、通过输入门向量i控制更新的获取;另一部分称之为working memory h i h_i hi,隐藏状态组件。

信息来源:人人都能看懂的LSTM

图一:LSTM和普通RNN结构对比图
LSTM和普通RNN结构对比图
左边为普通的RNN结构,只有一个传递状态。
右边为LSTM结构,有两个传递状态c和h。前者改变的较慢,主要由历史经验决定;后者改变的较快,在不同节点下往往差别较大。

图二:LSTM内部结构解析
LSTM内部结构解析
LSTM内部有三个阶段:
阶段一:忘记阶段。
简言之,从历史数据中选择最重要的。
用数学公式表示即为用 z f z^f zf作为忘记门控,来控制上一个状态哪一部分需要保留。
z f . ∗ c t − 1 z^f.*c^{t-1} zf.ct1
阶段二:选择记忆阶段。
简言之,从输入数据中选择最重要的。
用数学公式表示即为用 z i z^i zi作为输入门控,来控制输入哪一部分需要重点保留。
z i . ∗ z z^i.*z zi.z
c t = z f . ∗ c t − 1 + z i . ∗ z c^t=z^f.*c^{t-1}+z^i.*z ct=zf.ct1+zi.z
阶段三:输出阶段。
简言之,控制输出。
用数学公式表示即为用 z o z^o zo作为输出门控,来控制输出。
h t = z o . ∗ t a n h ( c t ) h^t=z^o.*tanh(c^t) ht=zo.tanh(ct)

其中,门控向量的计算方法:
z g a t e = s i g m o i d ( W g a t e [ x t ; h t − 1 ] ) z^{gate}=sigmoid(W^{gate}[x^t ;h^{t-1}]) zgate=sigmoid(Wgate[xt;ht1])
sigmoid函数的目的是将值映射为0-1之间,从而可以作为门向量。
z = t a n h ( W [ x t ; h t − 1 ] ) z=tanh(W[x^t;h^{t-1}]) z=tanh(W[xt;ht1])

模型建立

主要思路:

  1. 将token从离散one-hot表示映射到低维空间中成为稠密的embedding
  2. 将句子的embedding序列输入到LSTM中,用神经网络自动提取特征
  3. 用CRF做句子级别的标签预测

模型示意图:
在这里插入图片描述
大致可分为五层:

  1. Embedding层
    输入:字对应的id列表以及分词信息特征
    目标:将字转化为低维稠密向量
    操作:预先训练好n维词向量模型,通过查询得到每一个字的n维向量。n维向量与分词信息特征向量一起输出到dropout层。
    这里预训练的embedding可以捕捉全局上单词的相似度。
  2. dropout层
    输入:字对应的n维向量以及分词信息特征向量
    目标:缓解过拟合
    操作
  3. bi-lstm层
    输入:字对应的n维向量
    目标:自动提取句子特征
    操作:将每个字的char embedding序列作为bi-lstm的各个时间步的输入,再将正向LSTM输出的隐状态序列与反向LSTM的在各个位置输出的隐状态按照位置进行拼接,得到完整的隐状态序列。
    这里可以捕捉字内部的一些规律。与预训练的embedding结合,可以得到更好的词嵌入。
  4. project层
    线性层。
    输入:bi-lstm输出的隐状态序列
    目标:得到自动提取的句子特征
    操作:将隐状态序列映射到标签数的维数,从而可以将每一维视作字到标签的打分值。此时如果使用softmax可以直接得到分类结果,但是没办法应用上其他位置上已经标注过的信息,所以接下来再接入一个CRF层。
  5. loss层
    内嵌CRF层。
    输入:字对于标签序列的打分
    目标:句子级的序列标注
    操作:重新打分;打分分成两部分,LSTM输出的打分加上CRF的转移矩阵(即由一个标签转移到另一个标签的转移得分)。得到打分之后,进而利用Softmax得到归一化之后的概率。

参考链接:

  1. BiLSTM-CRF 模型实现中文命名实体识别(写的太好啦)
  2. 基于 bi-LSTM和CRF的中文命名实体识别

代码实现

整体

Bi-LSTM Conditional Random Field Discussion(官方文档居然有!整体的实现!)

Bi-LSTM层

以下链接展示了如何使用Pytorch写LSTM,这里就不再过多重复。

  1. PyTorch 中的 LSTM模型参数解释
  2. nn.LSTM 代码文档(代码文档是真的清楚!)
  3. PyTorch 实现序列模型和基于LSTM的循环神经网络(主要参考)

CRF层

运行结果

NER任务的评测指标

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值