from https://blog.csdn.net/u013963380/article/details/108696552
本文翻译,原文地址:
https://createmomo.github.io/2017/10/08/CRF-Layer-on-the-Top-of-BiLSTM-3/
https://createmomo.github.io/2017/10/17/CRF-Layer-on-the-Top-of-BiLSTM-4/
https://createmomo.github.io/2017/11/11/CRF-Layer-on-the-Top-of-BiLSTM-5/
三、CRF损失函数
CRF损失函数由两部分组成,真实路径的分数 和 所有路径的总分数。真实路径的分数应该是所有路径中分数最高的。
例如,我们的数据集中有如下几种类别:
Label | Index |
B-Person | 0 |
I-Person | 1 |
B-Organization | 2 |
I-Organization | 3 |
O | 4 |
START | 5 |
END | 6 |
一个包含5个单词的句子,可能的类别序列如下:
- 1) START B-Person B-Person B-Person B-Person B-Person END
- 2) START B-Person I-Person B-Person B-Person B-Person END
- …
- 10) START B-Person I-Person O B-Organization O END
- …
- N) O O O O O O O
假设每种可能的路径的分数为,共有条路径,则路径的总分是:
,是一个数学常量。(下节会详细介绍如何计算,这里你可以把它当作这条路径的分数)。
如果第十条路径是真实路径,也就是说第十条是正确预测结果,那么应该是所有可能路径里分数最高的。根据如下损失函数,在训练过程中,BiLSTM-CRF模型的参数值将随着训练过程的迭代不断更新,使得真实路径所占的比值越来越大。
那么现在的问题就是:
- 如何定义路径的分数
- 怎么计算所有路径的分数
- 当计算所有的路径分时,是否需要穷举多有可能的路径?(答案是不需要)
四、真实路径分数
很明显,在所有的可能的路径中有一条是真实的路径。比如在上述的类别序列中,“START B-Person I-Person O B-Organization O END”是一条真实的路径。不正确的路径如“START B-Person B-Organization O I-Person I-Person B-Person”。是第条路径的分数。
在训练阶段,crf的损失函数只需要两种类别的分数,真实路径的分数 和 所有路径的总分数。在所有的可能路径的分数中,真实路径的分数应该是最高的。
当然计算是十分简单的,下面让我们聚焦如何来计算。
我们假设“START B-Person I-Person O B-Organization O END”是一条真实的路径:
- 一个句子中有5个单词,分别是
- 添加开始和结尾单词,分别是
- 包含两个部分,
tips:Emission Score 和 Transition Score在《BiLSTM中的CRF层(二)CRF层》一文中已经介绍。
(1)Emission Score(发射分数):
- 是第索引的单词被标注为的分数
- 这些分数来自前一层BiLstm的输出
- 可以设置为0
(2)Transition Score(转移分数):
- 是从label1转移到label2的分数
- 这些分数来自于CRF层。换句话说,这些分数其实是CRF层的参数
五、所有路径的分数
上面提到所有路径的分数。计算所有路径的总分最简单的方式是:穷举所有可能的路径,分别计算路径分,最后求和。但是这种方式是十分低效的,而且训练时间也是不可忍受的。
下面以一个简单的例子来说明如何高效的计算所有路径的分数。
Step1: recall the CRF loss function
CRF损失函数的定义是,我们把它变成log损失函数如下:
,由于我们训练的目标通常是最小化损失函数,所以我们加上负号:
(原文中在求真实路径的分数的时候,求和用的是N和N-1,但是从上面的求解发射分数和转移分数公式看,这里的N应该是句子的长度words,N-1应该是标签数num_tag,所有的路径总数N应该是N=(num_tag)^(words),否则对应不上。不知道是不是作者为了简化统一用N表示,还是本人理解错误。。。囧囧囧)
在上面,我们已经知道如何计算真实路径的分数,下面我们只需要找到一种高效的方式来计算。
Step2:recall the Emission and Transition Score
为了简化说明,这里我们假设我们训练模型的句子只有3的长度,标签只有2种:
我们从Bi-Lstm层获得的发射分数如下:
tips:表示单词被标签为的分数。
从CRF层获得的转移分数如下:
tips:表示从标签转移到标签的分数
Step3:START FIGHTING!
首先要记得我们的目标是
整个过程其实是分数累加的过程。它的思想和动态规划如出一辙。总而言之就是,首先单词的所有路径的总分被计算出来;然后,计算从 的所有路径的得分,最后计算的所有路径的得分,也就是我们最终要的结果。
接下来,你会看到两个变量:obs和 previous。previous存储了之前步骤的结果,obs代表当前单词的信息。
=======================================================================================================
:
如果我们的句子只有一个单词,前一个步骤没有任何的结果,因此previous=None。另外,我们只能获取到,和是上面提到的从BiLSTM层获得的发射分数。
因此,这里单词的所有路径分数为:
=======================================================================================================
:
(1) 将previous扩展为:
(2) 将obs扩展为:
将previos和obs扩展是为了计算总分更加高效。下面将会看到
(3) 对previou、obs和转移分数求和:
然后改变previos的值
到这里,第二次迭代实际上已经完成了。然后,我们使用新的previous值来计算的所有路径总分:
从上面公式可以看出,这就是我们的求解目标
在上述公式中:
=======================================================================================================
下面的手码太累了,直接贴原文的截图,截图出自(https://createmomo.github.io/2017/11/11/CRF-Layer-on-the-Top-of-BiLSTM-5/),原理是一样的。
=======================================================================================================
上述过程建议用手推一遍,对理解这个过程十分有用。。。
至此,我们完成了的求解过程。
六、如何利用CRF来推理
前面几节介绍了Bi-Lstm-CRF的模型结构以及CRF损失函数。我们可以使用开源的深度学习框架(Keras、tensorflow等)来实现一个Bi-Lstm-CRF模型。而且用这些框架最好的是不用自己来实现反向传播这个过程,更有的框架已经实现了CRF层,只需要添加一行代码就可以完全实现Bi-Lstm-CRF模型。
推理的过程和上述求解所有路径总分的过程有点相似,每次获取得分最高的路径,最终选择所有路径中得分最高的路径为最佳路径。
详细过程见原文:https://createmomo.github.io/2017/11/24/CRF-Layer-on-the-Top-of-BiLSTM-6/
这里不再讲述,因为整个过程十分简单,理解了第五节中的求解过程即可。