BILSTM+CRF中的条件随机场

tensorflow中crf关键的两个函数是训练函数tf.contrib.crf.crf_log_likelihood和解码函数tf.contrib.crf.viterbi_decode

crf_log_likelihood(inputs, tag_indices, sequence_lengths, transition_params=None)
Computes the log-likelihood of tag sequences in a CRF. Args:
inputs: A [batch_size, max_seq_len, num_tags] tensor of unary potentials
to use as input to the CRF layer.
tag_indices: A [batch_size, max_seq_len] matrix of tag indices for which we
compute the log-likelihood.
sequence_lengths: A [batch_size] vector of true sequence lengths.
transition_params: A [num_tags, num_tags] transition matrix, if available.
Returns:
log_likelihood: A scalar containing the log-likelihood of the given sequence
of tag indices.
transition_params: A [num_tags, num_tags] transition matrix. This is either
provided by the caller or created in this function.
viterbi_decode(score, transition_params)
Decode the highest scoring sequence of tags outside of TensorFlow. This should only be used at test time. Args:
score: A [seq_len, num_tags] matrix of unary potentials.
transition_params: A [num_tags, num_tags] matrix of binary potentials. Returns:
viterbi: A [seq_len] list of integers containing the highest scoring tag
indicies.
viterbi_score: A float containing the score for the Viterbi sequence.

看着这两个函数定义,我懵逼了。在看完了李航的《统计学习方法》后,我以为我可以轻松搞定bilstm+crf中的crf。然而对着这两个函数发呆了半天,发现怎么跟书上的理论对不上号?特征函数呢?转移函数呢?怎么训练完之后就只有个transition_params,维度还是num_tags x num_tags。这是什么东西。

郁闷的在网上找资料,终于看到了参考资料里面的讲解,总算是醍醐灌顶看懂了。这里记录一下。

bilstm和crf的作用

在bilstm+crf结构中,bilstm的输出已经是各个标签取值的概率了,crf的作用仅仅是根据标签间的关系做结果调整。借用参考资料里的图片

那么,bilstm已经输出标签取值概率了,为什么还需要crf层呢。因为直接用bilstm输出的标签有些并不合理,比如B-Person,I-Organization就是一个不合理的序列。crf做的就是在bilstm输出的基础上,调整输出标签,使得标签结果顺序更为合理。

crf细节

与之前介绍的标准形式相似,在条件\(x\)的情况下,序列\(y\)出现的概率\(P(y|x)\)可以表达为:

\[P(y|x)=\frac{e^s}{e^{s_1}+e^{s_2}+e^{s_3}+...+e^{s_n}}
\]

\(e^s\)是当前序列的分数,分母是所有序列分数的和。

可以对比一下之前介绍crf那篇的公式,到这里跟传统的crf都是一样的,只是表达上现在的公式化简了一些。

下面就是和前一篇不同的地方了,区别就在于\(s\)。在之前的介绍中,\(s\)由状态特征函数和转移特征函数组成,并有各自的权重。而bilstm+crf中的crf其\(s\)的组成要简单很多。

先介绍两个重要变量:

\(EmissionScore\): bilstm输出的每个位置是各个标签的概率。是一个\(seq\_len\times num\_tags\)的矩阵。如上图黄色矩形部分。

\(TransitionScore\): 标签间的转移概率。是一个\(num\_tags\times num\_tags\)的矩阵

上面矩阵的含义是,如果前一个标签是START,而后一个标签为B-Person的概率为0.8,而START后接I-Organization的概率只有0.0008。这是符合人们的认知的。

这样,就可以介绍\(s_i\)的组成了。

\[s_i=EmissionScore+TransitionScore
\]

对于序列来说,比如有一个序列是“START B-Person I-Person O B-Organization O END”,则

\[EmissionScore=x_{0,START}+x_{1,B-Person}+x_{2,I-Person}+x_{3,O}+x_{4,B-Organization}+x_{5,O}+x_{6,END}
\]

\[TransitionScore=t_{START->B-Person} + t_{B-Person->I-Person} + t_{I-Person->O} + t_{0->B-Organization} + t_{B-Organization->O} + t_{O->END}
\]

\[e^s=e^{EmissionScore+TransitionScore}
\]

看到这里就知道bilstm之上的crf与普通crf的区别了。普通crf的样本概率受特征函数和相关权值的影响。而bilstm上的crf则没有特征函数,也没有权值,结果受bilstm层输出的各个位置标签概率,以及标签间的状态转移矩阵影响。对于bilstm+crf的crf层来说,要学习的就只有标签间状态转移矩阵而已。

看到这,再对应tensorflow的函数定义,就很明白了。

crf_log_likelihood函数输出的transition_params,就是要求解的状态转移矩阵。

viterbi_decode(score, transition_params),就是通过bilstm的输出score和求解的状态转移矩阵transition_params来解码最终结果。

参考资料

  1. https://createmomo.github.io/2017/09/12/CRF_Layer_on_the_Top_of_BiLSTM_1/
  2. https://createmomo.github.io/2017/09/23/CRF_Layer_on_the_Top_of_BiLSTM_2/
  3. https://createmomo.github.io/2017/10/08/CRF-Layer-on-the-Top-of-BiLSTM-3/
  4. https://createmomo.github.io/2017/10/17/CRF-Layer-on-the-Top-of-BiLSTM-4/
  5. https://createmomo.github.io/2017/11/11/CRF-Layer-on-the-Top-of-BiLSTM-5/
  6. https://createmomo.github.io/2017/11/24/CRF-Layer-on-the-Top-of-BiLSTM-6/

【算法】BILSTM+CRF中的条件随机场的更多相关文章

  1. 【机器学习】【条件随机场CRF-2】CRF的预测算法之维特比算法(viterbi alg) 详解 + 示例讲解 + Python实现

    1.CRF的预测算法条件随机场的预测算法是给定条件随机场P(Y|X)和输入序列(观测序列)x,求条件概率最大的输出序列(标记序列)y*,即对观测序列进行标注.条件随机场的预测算法是著名的维特比算法(V ...

  2. 标注-CRF条件随机场

    1 概率无向图模型1.1 模型定义1.2 因子分解2 条件随机场的定义2.2 条件随机场的参数化形式2.3 条件随机场的简化形式2.4 条件随机场的矩阵形式 3 条件随机场的概率计算问题 3.1 前向 ...

  3. 条件随机场CRF

    条件随机场(CRF)是给定一组输入随机变量X的条件下另一组输出随机变量Y的条件概率分布模型,其特点是假设输出随机变量构成马尔科夫随机场.实际上是定义在时序数据上的对数线性模型.条件随机场属于判别模型. ...

  4. 高级教程: 作出动态决策和 Bi-LSTM CRF 重点

    动态 VS 静态深度学习工具集 Pytorch 是一个 动态 神经网络工具包. 另一个动态工具包的例子是 Dynet (我之所以提这个是因为使用 Pytorch 和 Dynet 是十分类似的. 如果你 ...

  5. bi-Lstm +CRF 实现命名实体标注

    1. https://blog.csdn.net/buppt/article/details/82227030 (Bilstm+crf中的crf详解,包括是整体架构) 2. 邹博关于CRF的讲解视频 ...

  6. Viterbi(维特比)算法在CRF(条件随机场)中是如何起作用的?

    之前我们介绍过BERT+CRF来进行命名实体识别,并对其中的BERT和CRF的概念和作用做了相关的介绍,然对于CRF中的最优的标签序列的计算原理,我们只提到了维特比算法,并没有做进一步的解释,本文将对 ...

  7. 条件随机场CRF(三) 模型学习与维特比算法解码

    条件随机场CRF(一)从随机场到线性链条件随机场 条件随机场CRF(二) 前向后向算法评估标记序列概率 条件随机场CRF(三) 模型学习与维特比算法解码 在CRF系列的前两篇,我们总结了CRF的模型基 ...

  8. 条件随机场CRF(二) 前向后向算法评估标记序列概率

    条件随机场CRF(一)从随机场到线性链条件随机场 条件随机场CRF(二) 前向后向算法评估标记序列概率 条件随机场CRF(三) 模型学习与维特比算法解码 在条件随机场CRF(一)中我们总结了CRF的模 ...

  9. 【算法】CRF(条件随机场)

    CRF(条件随机场) 基本概念 场是什么 场就是一个联合概率分布.比如有3个变量,y1,y2,y3, 取值范围是{0,1}.联合概率分布就是{P(y2=0|y1=0,y3=0), P(y3=0|y1= ...

随机推荐

  1. 正则 re模块

    Python 正则表达式 re 模块 简介 正则表达式(regular expression)是可以匹配文本片段的模式.最简单的正则表达式就是普通字符串,可以匹配其自身.比如,正则表达式 ‘hello ...

  2. Mac打开Terminal报错-bash : : command not found

    问题描述: Mac系统在打开Terminal的时候,报错-bash : : command not found. 问题分析: 报错并不影响Terminal的使用,于是忽略不计.但是在修改.bash_p ...

  3. React多层级表单

    因项目需要封装的组件,组件库使用的是Ant Design 用到了 Form组件 , 布局组件,表单控件 ,如果没有使用Ant Design,可以用rc-form代替,需要对组件中使用的表单控件和布局进 ...

  4. Go语言中的make和new

    相同点: make和new都是用来创建分配类型内存的. 不同点: 先看下面的代码 package main import "fmt" func main(){ var i *int ...

  5. [HNOI/AHOI2018]游戏

    题目描述 https://lydsy.com/JudgeOnline/upload/201804/%E6%B9%96%E5%8D%97%E4%BA%8C%E8%AF%95%E8%AF%95%E9%A2 ...

  6. yii2 使用指定数据库执行createCommand

    Yii::$app->dbName->createCommand($sql)->queryAll(); 指定dbName数据库配置

  7. SpringMVC 文件上传下载

    目录 文件上传 MultipartFile对象 文件下载 上传下载示例 pom.xml增加 创建uploadForm.jsp 创建uploadForm2.jsp 创建userInfo.jsp spri ...

  8. [PKUWC2019]Day1 T2 你和虚树的故事

    选择k个颜色,使得颜色的虚树有交的方案数 肯定要考虑连通块的贡献. 法一 https://www.cnblogs.com/xzz_233/p/10292983.html 枚举连通块还是不可行的. 枚举 ...

  9. 【洛谷P1090 合并果子】

    题目描述 在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆.多多决定把所有的果子合成一堆. 每一次合并,多多可以把两堆果子合并到一起,消耗的体力等于两堆果子的重量之和.可 ...

  10. SpringBoot实现优雅的关机

    最近在公司使用了 Springboot 项目, 发现在   linux  上 通过 java -jar 命令可以十分安全的运行, 但是 当我们需要关闭它的时候呢? 难道  登陆服务器 kill 线程? ...