1.为什么不直接使用LSTM?
关于标注任务,我们自然而然的可以想到,使用RNN序列模型,在每一时刻输出对应的隐状态Ht,然后进行每一时刻的逐帧softmax。为什么不行呢?主要原因在于,RNN模型(比如LSTM)没有考虑到输出类标之间的关联性,比如NER任务中,一些输出的类标之间是有顺序性的,而RNN虽然利用隐变量Ht学到了X之间的顺序关系,但是没有考虑到输出序列的顺序性。
于是,我们将二者结合起来,使用RNN序列模型提取X之间的转移关系,使用CRF层来处理输出序列的顺序。
2.CRF原理
在CRF的标注任务中,我们的目标是根据观测序列推断出最有可能的标注序列,设我们的序列长为n,标签数为K,其本质是一个K^n分类的问题,而逐帧softmax则计算的是一个n次的K分类问题。
即在CRF的序列标注问题中,我们的目标是最大化条件概率:
为了近似这个条件概率,我们有如下两个假设:
①假设这个分布是指数族分布
这个假设意味着存在函数 f(y1,…,yn;x),使得:
其实这里也可以从另一个角度解释,即CRF和LR同属于对数线性函数,这是对数线性函数的形式。其中Z为归一化因子,f为特征函数,也可以理解为打分函数。
②输出之间的关联仅发生在相邻位置,并且关联是指数加性的。
这个假设意味着 f(y1,…,yn;x) 可以更进一步简化为:
这里也可以看出,我们假设分数与每个标注结果和标注结果的转移分数构成。
这也就是说,现在我们只需要对每一个标签和每一个相邻标签对分别打分,然后将所有打分结果求和得到总分。
线性链CRF
尽管已经做了大量简化,但一般来说,(3) 式所表示的概率模型还是过于复杂,难以求解。于是考虑到当前深度学习模型中,RNN 或者层叠 CNN 等模型已经能够比较充分捕捉各个 y 与输出 x 的联系,因此,我们不妨考虑函数 g 跟 x 无关,那么:
这时候 g 实际上就是一个有限的、待训练的参数矩阵而已,而单标签的打分函数 h(yi;x) 我们可以通过 RNN 或者 CNN 来建模。因此,该模型是可以建立的,其中概率分布变为:
这就是线性链 CRF 的概念。(在实际的训练中,h由RNN给出,g则就是一个分数矩阵,由训练得出)
注意这里与HMM的不同,HMM中的发射概率由隐状态y向观测序列x发射,这里对y的打分函数实际上相当于由x向y发射。
为最大化条件概率,我们取log并加上负号作为我们的损失函数,任务变成最小化这个损失函数:
即
这个损失函数也可以这么理解:
这里面的LossFunction取负log后实际上和上式相同。
前面的一项非常好算,我们只需要将我们观测到的序列得到的分数相加,而这个分数是怎么得来的呢?
注意到BILSTM在每一时刻输出的softmax结果,即每一时刻的x对于标签y的打分。
正确路径非常好计算,但是归一化因子中的所有分数实际上是比较难以计算的,如果我们穷举所有可能,那这个时间复杂度实际上并不是我们能够接受的。
于是我们想到了动态规划,这里面实际的操作过程和HMM中概率计算问题的前向算法非常相似。
这里面采取的方法同样是列表格,我们举一个例子来说明:
我们利用之前文章中介绍的前向算法类似的计算方式
其中每个方块中第一项都是基于前一个状态转移过来的和,然后我们在加上当前标签得分和状态转移得分。
在最后一列按行求和,就可以得到最终的结果,其与计算所有路径和是等价的:
为什么动态规划的时间复杂度更好?因为每一时刻都利用到了上一时刻的计算结果,没有产生重复计算。
参考: