2.BiLSTM+CRF实现命名实体识别 2.3 CRF建模的损失函数 前边我们讲到,CRF能够帮助我们以一种全局的方式建模,在所有可能的路径中选择效果最优,分数最高的那条路径。那么我们应该怎么去建模这个策略呢,下面我们来具体谈谈。
图5 CRF解码过程图
图5 展示了CRF的工作图,现在我们有一串输入
x=[x_0, x_1, x_2, x_n] (这里的
x 是文本串对应的发射分数,每个字词
x_i 都对应着一个发射分数向量,也就是前边提到的标签向量,该向量的维度就是标签数量),期待解码出相应的标签序列
y=[y_0, y_1,y_2, ..., y_n] ,形式化为对应的条件概率公式如下:
(y|x) = P(y_0,y_1,...,y_n|x_0,x_1,...,x_n) 在第2节我们提到,CRF的解码策略在所有可能的路径中,找出得出概率最大,效果最优的一条路径,那这个标签序列就是模型的输出,假设标签数量是
k ,文本长度是
n ,显然会有
N=k^n 条路径,若用
S_i 代表第
i 条路径的分数,那我们可以这样去算一个标签序列出现的概率:
P(S_i)=\frac{e^{S_i}}{\sum_j^{N}{e^{S_j}}} 现在我们有一条真实的路径
real ,即我们期待CRF解码出来的序列就是这一条。那它的分数可以表示为
s_{real} ,它出现的概率就是:
P(S_{real})=\frac{e^{S_{real}}}{\sum_j^{N}{e^{S_j}}} 所以我们建模学习的目的就是为了不断的提高
P(S_{real}) 的概率值,这就是我们的目标函数,当目标函数越大时,它对应的损失就应该越小,所以我们可以这样去建模它的损失函数:
loss=-P(S_{real})=-\frac{e^{S_{real}}}{\sum_j^{N}{e^{S_j}}} 为方便求解,我们一般将这样的损失放到log空间去求解,因为log函数本身是单调递增的,所以它并不影响我们去迭代优化损失函数。
\begin{align} loss &= -log \frac{e^{S_{real}}}{\sum_j^{N}{e^{S_j}}} \\ &= -(log(e^{S_{real}}) - log(\sum_j^{N}{e^{S_j}})) \\ &= log(\sum_j^{N}{e^{S_j}}) - log(e^{S_{real}}) \\ &= log(e^{S_1}+e^{S_2}+...+e^{S_N}) - S_{real} \\ \end{align} 千呼万唤始出来,这就是我们CRF建模的损失函数了。我们整个BiLSTM+CRF建模的目的就是为了让这个函数越来越小。从这个损失函数可以看出,这个损失函数包含两部分:单条真实路径的分数
S_{real} ,归一化项
log(e^{S_1}+e^{S_2}+...+e^{S_N}) ,即将全部的路径分数进行
log\_sum\_exp 操作,即先将每条路径分数
S_i 进行
exp(S_i) ,然后再将所有的项加起来,最后取
log 值。
讲到这里,有的同学可能会有疑惑,这里的每条路径分数应该怎么算呢?接下来,我们就来解决这个问题。
2.4 单条路径的分数计算 在开始之前,我们再来做一些约定,前边我们提到了发射分数和转移分数,假设
E 代表发射分数矩阵,
T 代表转移分数矩阵,
n 代表文本序列长度,
tag\_size 代表标签的数量。另外为方便书写,我们为每个标签编个id号(参考图5 中涉及到的标签),如图6 所示。
图6 Tag和Tag Id 对应表
其中,
E 的shape为
[n, tag\_size] ,每行对应着一个文本字词的发射分数,每列代表一个标签,例如,
E_{01} 代表
x_0 取id为1的标签分数,
E_{23} 代表
x_2 取id为3的标签分数。
T 的shape为
[tag\_size, tag\_size] ,它代表了标签之间相互转移的分数,例如,
T_{03} 代表id为3的标签向id为0的标签转移分数。
每条路径的分数就是由对应的发射分数和转移分数组合而成的,对于图5 标记出来的黄色路径来说,
x_0 的标签是B-Person,对应的发射分数是
E_{00} ,
x_1 的标签是I-Person,对应的发射分数是
E_{11} ,由B-Person向I-Person转移的分数是
T_{10} ,因此到这一步的分数就是:
E_{00}+T_{10}+E_{11} 。
接下来
x_2 的标签是
O ,由
x_1 的标签向I-Person向
x_2 的标签O转移的概率是
T_{41} ,因此到这一步的分数是:
E_{00}+T_{10}+E_{11}+T_{41}+E_{24} ,依次类推,我们可以计算完整条路径的分数。假设第
i 个位置对应的标签为
y_i ,则整条路径的分数计算形式化公式为:
S_{real}=\sum_{i=0}^{n-1}{E_{i,y_i}} + \sum_{i=0}^{n-2}{T_{y_{i+1}, y_{i}}} 2.5 全部路径的分数计算 2.3节中的损失函数包括两项,单条真实路径分数的计算和归一化项(如上所述,全部路径分数的
log\_sum\_exp ,为方便描述,后续直接将个归一化项描述为全部路径之和)的计算。这里你或许会问,现在知道了单条路径分数的计算方式,遍历一下所有的路径算个分数,不就可以轻松算出全部路径之和吗?是的,这在理论上是可行的。
但是,前边我们提到这个路径的数量是个指数级别的量纲,假设我对串包含50个字的文本串进行实体识别,标签的数量是31,那么这个路径的数量将是
31^{50} 条,这是真的是难以接受的一件事情,它会远远拖慢模型的训练和预测效率。
因此,我们要换一种高效的思路,这里其实用到了一种被称为前向算法 的动态规划,它能帮助我们将图5 所有路径的和计算,拆解为每个位置的和计算,最终得出所有的路径之和。如果这是你第一次听到这个算法,那也没关系,我会通过示例的方式,为你展现这个算法的工作原理,但是在看这部分内容之前,我们再来回顾一下我们的计算目标,即损失函数中的第1项:
log(e^{S_1}+e^{S_2}+...+e^{S_N}) 另外,为方便描述这个原理,我们来简化下这个问题,假设我们现在在计算图7 所示的所有路径之和。
图7 简化版的CRF工作图
图7 中,共包含2个标签
Tag 0 和
Tag 1, 文本串有3个单词
x_0, x_1, x_2 。我们再来做些约定如下:
emission_i=[x_{i0},x_{i1}] , 代表
x_i 位置的发射分数。
其中,
x_{i0} 代表
x_i 位置输出
Tag 0 标签的分数,
x_{i1} 代表
x_i 位置输出
Tag 1 标签的分数。
trans = \left[ \begin{matrix} t_{00} & t_{01}\ t_{10} & t_{11} \end{matrix} \right]
其中,
t_{01} 代表从
Tag 1 转移到
Tag 0的分数,
t_{10} 代表从
Tag 0 转移到
Tag 1的分数,依次类推。
alpha_i=[s_{i0},s_{i1}] , 其中各个数值代表到当前位置
x_i 为止,以
x_i 位置相应标签结尾的路径分数之和。
以
x_2 步为例,
alpha_2=[s_{20},s_{21}] ,其中
s_{20} 代表截止到
x_2 步骤为止,以标签
Tag 0 结尾所有的路径分数之和,
s_{21} 代表截止到
x_2 步骤为止,以标签
Tag 1结尾的所有路径分数之和。
这里比较抽象,如图7 所示,参与
x_2 步的
s_{20} 分数计算的路径包括4条,即
s_{20} 是下边4条路径分数之和,依次如下
x_{00},x_{10},x_{20} x_{00},x_{11},x_{20} x_{01},x_{10},x_{20} x_{01},x_{11},x_{20} 恭喜,我们完成了一些枯燥的定义,下边我们来看看如何计算所有路径的分数和吧,这里我们分成3步走来解释,首先计算截止到
x_0 位置,到各个标签的分数(上边的
alpha 内容)是多少;截止到
x_1 位置,到各个标签的分数是多少;截止到
x_2 位置,到各个标签的分数是多少。
第1步,截止到
x_0 位置
当前位置
x_0 输入的发射分数为:
emission_0=[x_{00},x_{01}] ,因为这是序列的起始,显然截止到
x_0 位置有:
alpha_0=[x_{00},x_{01}] 。
截止到
x_0 这一步,将
x_0 位置的所有标签的分数累计作为所有路径的分数为:
total_0 = log(e^{x_{00}}+e^{x_{01}}) 第2步,截止到
x_1 位置
当前步骤涉及到
x_0 向
x_1 位置的转移,在这个过程中,
x_1 位置输入的发射分数为:
emission_1=[x_{10}, x_{11}] , 转移概率矩阵为: $ trans = \left[ \begin{matrix} t_{00} & t_{01}\ t_{10} & t_{11} \end{matrix} \right]
, 前一个位置 x_0
各标签的路径累计和 alpha_0=[x_{00},x_{01}]$。
接下来我们expand一下
emission_1 和
alpha_0 ,力求通过矩阵计算的方式一次完成当前位置
x_1 各个标签的路径累计
alpha_1 ,具体如下:
emission_1 = \left[ \begin{matrix} x_{10} & x_{10}\\ x_{11} & x_{11} \end{matrix} \right] alpha_0 = \left[ \begin{matrix} x_{00} & x_{01}\\ x_{00} & x_{01} \end{matrix} \right] 然后我们来计算截止到
x_1 位置,到不同标签的每条路径的分数:
\begin{align} scores &= alpha_0+trans+emission_1 \\ &= \left[ \begin{matrix} x_{00} & x_{01}\\ x_{00} & x_{01} \end{matrix} \right] + \left[ \begin{matrix} t_{00} & t_{01}\\ t_{10} & t_{11} \end{matrix} \right] + \left[ \begin{matrix} x_{10} & x_{10}\\ x_{11} & x_{11} \end{matrix} \right] \\ &= \left[ \begin{matrix} x_{00}+t_{00}+x_{10} & x_{01}+t_{01}+x_{10}\\ x_{00}+t_{10}+x_{11} & x_{01}+t_{11}+x_{11} \end{matrix} \right] \end{align} 我们来看一条路径分数的计算,例如$ x_{00}+t_{10}+x_{11}
, 它代表在 x_0
的位置标签为 Tag$ 0,在
x_1 的位置标签为
Tag 1,然后通过加上
t_{10} 完成了
x_0 位置
Tag 0标签 向
x_1 位置标签
Tag 1的转移。
从上边的结果可以看到,第1行代表向当前位置
x_1 标签
Tag 0的转移路径,第2行代表向当前位置
x_1 标签
Tag 1的转移路径。以第1行为例,将第1行的路径分数相加,就相当于到当前位置
x_1 并且以
Tag 0结尾的所有路径之和。
因此,这样我们可以容易地算出当前位置
x_1 的各个标签的路径累计分数
alpha_1 :
alpha_1 = [log(e^{x_{00}+t_{00}+x_{10}}+e^{x_{01}+t_{01}+x_{10}}), log(e^{x_{00}+t_{10}+x_{11}}+e^{x_{01}+t_{11}+x_{11}})] 最后,我们来算下截止到
x_1 位置,所有的路径和:
\begin{align} total_1 &= log(e^{alpha_1[0]} + e^{alpha_1[1]}) \\ &=log(e^{log(e^{x_{00}+t_{00}+x_{10}}+e^{x_{01}+t_{01}+x_{10}})}+e^{log(e^{x_{00}+t_{10}+x_{11}}+e^{x_{01}+t_{11}+x_{11}})}) \\ &=log(e^{x_{00}+t_{00}+x_{10}}+e^{x_{01}+t_{01}+x_{10}} + e^{x_{00}+t_{10}+x_{11}}+e^{x_{01}+t_{11}+x_{11}}) \end{align} 再回顾一下我们的计算目标:
log(e^{S_1}+e^{S_2}+...+e^{S_N}) ,你可以看到如果图7 最终只到
x_1 位置,那么上边的这个结果就是我们相求的全部路径之和,或者说是归一化项。
第3步,截止到
x_2 位置
我们再来看下
x_2 位置的一些输入信息,
x_2 位置输入的发射分数为:
emission_2=[x_{20}, x_{21}] , 转移概率矩阵为: $ trans = \left[ \begin{matrix} t_{00} & t_{01}\ t_{10} & t_{11} \end{matrix} \right]
, 前一个位置 x_1
各标签的路径累计和 alpha_1=[log(e{x_{00}+t_{00}+x_{10}}+e{x_{01}+t_{01}+x_{10}}), log(e{x_{00}+t_{10}+x_{11}}+e{x_{01}+t_{11}+x_{11}})]$。
接下来继续expand一下
emission_2 和
alpha_1 ,力求通过矩阵计算的方式一次完成当前位置
x_2 各个标签的路径累计
alpha_2 ,具体如下:
emission_2 = \left[ \begin{matrix} x_{20} & x_{20}\\ x_{21} & x_{21} \end{matrix} \right] alpha_1 = \left[ \begin{matrix} log(e^{x_{00}+t_{00}+x_{10}}+e^{x_{01}+t_{01}+x_{10}}) & log(e^{x_{00}+t_{10}+x_{11}}+e^{x_{01}+t_{11}+x_{11}}) \\ log(e^{x_{00}+t_{00}+x_{10}}+e^{x_{01}+t_{01}+x_{10}}) & log(e^{x_{00}+t_{10}+x_{11}}+e^{x_{01}+t_{11}+x_{11}}) \end{matrix} \right] 然后我们来计算截止到
x_2 位置,到不同标签的每条路径的分数:
继续按行累加,算出到当前位置
x_2 的各个标签的路径累计分数
alpha_2 :
最后,我们来算下截止到
x_2 位置,所有的路径和:
显然,这个式子的结果就是最终我们想要的计算目标,损失函数中的第1项,共计包含8条路径的分数。
2.6 CRF的Viterbi解码 在前边几节,我们讲过了CRF的损失函数、单条路径分数的计算、全部路径分数的计算,根据这些内容完全可以进行BiLSTM+CRF的训练。但是,我们如何使用CRF从全部的路径中解码出得分最高的那条路径呢?
同2.5节所述,计算全部路径分数后,选择得分最大的那条路径肯定是不行的。其实这里是使用了一种被称为Viterbi 的算法,它的思想和2.5节介绍的前向算法 有些类似,将从全部路径中查找最优路径的过程,拆解为选择每个位置累计的最大路径。如果这是你第一次接触Viterbi 算法,也不用担心,本节依然会通过示例的方式展现这个算法原理。
我们依然以图7 为例,解码这全部路径中分数最大的这条(图中橙色显示的这条路径)。在正式介绍之前,我们依然做些约定如下:
emission_i=[x_{i0},x_{i1}] , 代表
x_i 位置的发射分数。
其中,
x_{i0} 代表
x_i 位置输出
Tag 0 标签的分数,
x_{i1} 代表
x_i 位置输出
Tag 1 标签的分数。
trans = \left[ \begin{matrix} t_{00} & t_{01}\ t_{10} & t_{11} \end{matrix} \right]
其中,
t_{01} 代表从
Tag 1 转移到
Tag 0的分数,
t_{10} 代表从
Tag 0 转移到
Tag 1的分数,依次类推。
alpha_i=[s_{i0},s_{i1}] , 其中各个数值代表到当前位置
x_i 为止,以当前位置
x_i 相应标签结尾的路径中,取得最大分数的路径得分。
以
x_2 位置为例,
alpha_2=[s_{20},s_{21}] ,其中
s_{20} 代表截止到
x_2 步骤为止,以标签
Tag 0 结尾所有的路径中得分最大的路径分数,
s_{21} 代表截止到
x_2 步骤为止,以标签
Tag 1结尾的所有路径中得分最大的路径分数。
这里比较抽象,如图7 所示,参与
x_2 步的
s_{20} 分数计算的路径包括4条,
s_{20} 是这4条路径中得分最大这一条对应的分数,即下边这一条路径:
x_{00},x_{11},x_{20} 。
beta_i = [p_{i0},p_{i1}] ,其中各个数值代表到当前位置
x_i 为止,以当前位置
x_i 相应标签结尾的路径中,分数最大的那一条路径在前一个位置
x_{i-1} 的标签索引(每个标签对应的id号)。
以
x_2 位置为例,
beta_2 = [p_{20},p_{21}] ,其中
p_{20} 代表代表截止到
x_2 步骤为止,以标签
Tag 0 结尾所有的路径中得分最大的那条路径在
x_{i-1} 位置的标签索引,同理
p_{21} 代表截止到
x_2 步骤为止,以标签
Tag 1结尾的最大路径在
x_{i-1} 位置的标签索引。
同样,如图7 所示,在
x_2 位置,到标签
Tag 0的所有路径中,分数最大的路径是:
x_{00},x_{11},x_{20} ,因为前一个位置
x_{i-1} 的标签是
Tag 1,因此
p_{20}=1 。
恭喜,我们又一次完成了这些枯燥的定义,下边我们来看看如何选择所有路径中得分最大的这一条吧,这里我们同样分成3步走来解释,首先计算截止到
x_0 位置,到各个标签的最大得分(上边的
alpha 内容)是多少;截止到
x_1 位置,到各个标签的最大得分是多少;截止到
x_2 位置,到各个标签的最大得分是多少。
第1步,截止到
x_0 位置
当前位置
x_0 输入的发射分数为:
emission_0=[x_{00},x_{01}] ,因为这是序列的起始,显然截止到
x_0 位置有:
alpha_0=[x_{00},x_{01}] 另外因为起始位置前边没有路径,这里我们使用-1来初始化:
beta_0=[-1,-1] 第2步,截止到
x_1 位置
当前步骤涉及到
x_0 向
x_1 位置的转移,在这个过程中,
x_1 位置输入的发射分数为:
emission_1=[x_{10}, x_{11}] , 转移概率矩阵为: $ trans = \left[ \begin{matrix} t_{00} & t_{01}\ t_{10} & t_{11} \end{matrix} \right]
, 到前一个位置 x_0
各标签的最大路径得分为 alpha_0=[x_{00},x_{01}]$。
接下来按照2.5节同样的方式,我们expand一下
emission_1 和
alpha_0 ,力求通过矩阵计算的方式一次完成到当前位置
x_1 各个标签的所有路径中得分最大的路径分数
alpha_1 ,具体如下:
emission_1 = \left[ \begin{matrix} x_{10} & x_{10}\\ x_{11} & x_{11} \end{matrix} \right] alpha_0 = \left[ \begin{matrix} x_{00} & x_{01}\\ x_{00} & x_{01} \end{matrix} \right] 然后我们来计算截止到
x_1 位置,到不同标签的每条路径的分数:
\begin{align} scores &= alpha_0+trans+emission_1 \\ &= \left[ \begin{matrix} x_{00} & x_{01}\\ x_{00} & x_{01} \end{matrix} \right] + \left[ \begin{matrix} t_{00} & t_{01}\\ t_{10} & t_{11} \end{matrix} \right] + \left[ \begin{matrix} x_{10} & x_{10}\\ x_{11} & x_{11} \end{matrix} \right] \\ &= \left[ \begin{matrix} x_{00}+t_{00}+x_{10} & x_{01}+t_{01}+x_{10}\\ x_{00}+t_{10}+x_{11} & x_{01}+t_{11}+x_{11} \end{matrix} \right] \end{align} 同样地,以第1行为例,第1行代表到当前位置
x_1 标签
Tag 0结尾的所有路径的得分,那么第1行中分数最大这一条路径,就是到当前位置
x_1 并且以
Tag 0结尾的所有路径中得分最大的路径。
因此,这样我们可以容易地算出到当前位置
x_1 的各个标签的最大路径分数
alpha_1 :
\begin{align} alpha_1 &= [max(scores[0,0], scores[0,1]), max(scores[1,0], scores[1,1])] \\ &= [max(x_{00}+t_{00}+x_{10}, x_{01}+t_{01}+x_{10}), max(x_{00}+t_{10}+x_{11}, x_{01}+t_{11}+x_{11})] \end{align} 显然从上边结果中,我们能够分析出到 x 1 x_1 x1位置各个标签的最大路径,例如到Tag 0的路径有 x 00 + t 00 + x 10 x_{00}+t_{00}+x_{10} x00+t00+x10 和 x_{01}+t_{01}+x_{10} , 其中较大者就是我们想要的到 , 其中较大者就是我们想要的到 ,其中较大者就是我们想要的到x_1位置 Tag
这里不妨我们做个假设:
x_{00}+t_{00}+x_{10} < x_{01}+t_{01}+x_{10} x_{00}+t_{10}+x_{11} > x_{01}+t_{11}+x_{11} 因此,我们可以获得
x_1 位置的索引
beta_1=[1,0] ,这代表在
x_1 位置,到标签
Tag 0的最大路径的前一个位置
x_{i-1} 的标签是
Tag 1, 到标签
Tag 1的最大路径的前一个位置
x_{i-1} 的标签是
Tag 0。
第3步,截止到
x_2 位置
我们再来看下
x_2 位置的一些输入信息,
x_2 位置输入的发射分数为:
emission_2=[x_{20}, x_{21}] , 转移概率矩阵为: $ trans = \left[ \begin{matrix} t_{00} & t_{01}\ t_{10} & t_{11} \end{matrix} \right]
, 前一个位置 x_1
各标签的路径累计和: alpha_1=[max(x_{00}+t_{00}+x_{10}, x_{01}+t_{01}+x_{10}), max(x_{00}+t_{10}+x_{11}, x_{01}+t_{11}+x_{11})]$。
接下来继续expand一下
emission_2 和
alpha_1 ,力求通过矩阵计算的方式一次完成当前位置
x_2 各个标签的路径累计
alpha_2 ,具体如下:
emission_2 = \left[ \begin{matrix} x_{20} & x_{20}\\ x_{21} & x_{21} \end{matrix} \right] alpha_1 = \left[ \begin{matrix} max(x_{00}+t_{00}+x_{10}, x_{01}+t_{01}+x_{10}) & max(x_{00}+t_{10}+x_{11}, x_{01}+t_{11}+x_{11}) \\ max(x_{00}+t_{00}+x_{10}, x_{01}+t_{01}+x_{10}) & max(x_{00}+t_{10}+x_{11}, x_{01}+t_{11}+x_{11}) \end{matrix} \right] 然后我们来计算截止到
x_2 位置,到不同标签的每条路径的分数:
因此,这样我们可以容易地算出到当前位置
x_2 的各个标签的最大路径分数
alpha_2 :
\begin{align} alpha_1 &= [max(scores[0,0], scores[0,1]), max(scores[1,0], scores[1,1])] \\ &= [max(max(x_{00}+t_{00}+x_{10}, x_{01}+t_{01}+x_{10}) +t_{00}+x_{20}, max(x_{00}+t_{10}+x_{11}, x_{01}+t_{11}+x_{11})+t_{01}+x_{20}), max(max(x_{00}+t_{00}+x_{10}, x_{01}+t_{01}+x_{10})+t_{10}+x_{21}, max(x_{00}+t_{10}+x_{11}, x_{01}+t_{11}+x_{11}) +t_{11}+x_{21} )] \end{align} 这里我不妨再假设:
max(x_{00}+t_{00}+x_{10}, x_{01}+t_{01}+x_{10}) +t_{00}+x_{20} > max(x_{00}+t_{10}+x_{11}, x_{01}+t_{11}+x_{11})+t_{01}+x_{20}) max(x_{00}+t_{00}+x_{10}, x_{01}+t_{01}+x_{10})+t_{10}+x_{21} < max(x_{00}+t_{10}+x_{11}, x_{01}+t_{11}+x_{11}) +t_{11}+x_{21} ) 上一步我们曾假设:
x_{00}+t_{00}+x_{10} < x_{01}+t_{01}+x_{10} x_{00}+t_{10}+x_{11} > x_{01}+t_{11}+x_{11} 因此有:
x_{01}+t_{01}+x_{10}+t_{01}+x_{10} < x_{00}+t_{10}+x_{11}+t_{01}+x_{20} x_{01}+t_{01}+x_{10}+t_{10}+x_{21} > x_{00}+t_{10}+x_{11}+t_{11}+x_{21} 所以
x_2 位置的索引:
beta_2 = [1,0] 此时:
alpha_1=[x_{00}+t_{10}+x_{11}+t_{01}+x_{20}, x_{01}+t_{01}+x_{10}+t_{10}+x_{21} ] 在图7 中橘色路径分数最高,其对应的是
x_{00}+t_{10}+x_{11}+t_{01}+x_{20} ,因此再假设:
x_{00}+t_{10}+x_{11}+t_{01}+x_{20} > x_{01}+t_{01}+x_{10}+t_{10}+x_{21} 这其实代表在
x_2 位置的所有标签对应的最大路径中,
Tag 0 对应的那条路径是最大的,这条路径也是全局所有路径中分数最大的那一条,是我们要解析出的期望路径。
第4步,开始解码标签序列
到现在位置,我们通过
beta_0 记录下了最大路径上的节点,接下来我们可以通过回溯来找出全局所有路径中的最大路径。
首先,在
x_2 位置所有标签对应的最大路径中,
Tag 0 对应的路径分数最大。因此
x_2 位置对应的标签就是
Tag 0。
然后,
beta_2 = [1,0] ,因此
x_2 位置解析出的标签
Tag 0,对应的上一位置
x_1 的标签是
Tag 1。
接下来,
beta_1=[1,0] ,因此
x_1 位置解析出的标签
Tag 1,对应的上一位置
x_0 的标签是
Tag 0。
最后,
beta_0=[-1,-1] ,当解析到这一步的时候,反回的标签肯定是-1,因此这个回溯过程也就结束了。
当回溯完成之后,将解析出的结果倒序排序,就是我们期望的最大路径。以图7 为例,该路径就是
Tag 0 -->
Tag 1 -->
Tag 0。
恭喜 ,看到这里,相信你已经懂得了CRF的核心原理。江湖虽路远,但总会再见,如对笔者的文章满意,还请多多支持 。
3. PLM Fine-tuning预训练的模型 3.1 目前前沿方法 Transformer-CRF模型:基于Transformers的神经网络结构和条件随机场模型的联合训练,通过提取输入的上下文信息、全局概率建模,结合现有的BERT和RoBERTa预训练模型,在多语种的命名实体识别任务中有很好的表现。
Pre-trained Language Model Fine-tuning (PLM Fine-tuning):该方法是基于预训练模型和微调技术的思想,利用预训练的模型(如BERT、RoBERTa等)作为初始参数,通过在命名实体识别的数据集上进行微调,来提升NER的性能。它可以在少量标注数据上快速训练,并在各种语言和领域中展现出优良的泛化能力。
Neural Architecture Search (NAS):利用神经网络搜索算法和强化学习,生成NN结构,并进行自动化架构搜索。NAS可以使模型具有更好的鲁棒性和泛化性能,并在不使用任何人工特征编码的情况下提高命名实体识别的准确性。
这些算法常用于实际应用中,并取得了良好的效果。当然,还有很多其他的NER算法,如模板匹配、CRF、SVM等,每种算法都有自己的优缺点,需要根据具体场景进行选择和组合。
3.2 小样本下NER 针对小样本问题,可以使用迁移学习或元学习等技术来解决。迁移学习是指将预先训练好的模型应用于新任务中,从而将新任务的训练时间缩短,但前提是预训练模型和待解决的任务有一定的相关性。元学习则是一种针对小样本学习问题的方法,它能够通过学习如何学习来提高模型在少量样本的情况下的泛化能力。
针对小样本NER问题,下面介绍两种常用的小样本模型:
Few-shot learning模型:该模型是一种基于元学习的模型,它可以用较少的数据进行训练,同时在新领域中进行良好的泛化,具有很强的适应性。Few-shot learning的主要思想是利用少量标注数据来训练一个编码器,通过训练来学习具有较好泛化性能的模型。在NER任务中,通过将少量文本做为一个任务,来进行训练,该模型可以在稀缺标注数据的情况下,识别新类别的命名实体。
Adaptive Span模型:该模型可以自适应地在输入序列中发现实体边界,从而进一步提高命名实体识别的性能。它可以利用现有的NER模型和表示学习方法,在少量数据情况下快速训练,并在大规模未标记的数据上表现优秀。Adaptive Span模型实现了端到端的自适应边界预测,它通过动态地选择每个输入序列中的子区间,来预测给定实体类别的标签。