久闻LSTM + CRF的效果强大,最近在看Pytorch官网文档的时候,看到了这段代码,前前后后查了很多资料,终于把代码弄懂了。我希望在后来人看这段代码的时候,直接就看我的博客就能完全弄懂这段代码。
看这个博客之前,我首先建议看看
Pytorch 关于Bi-LSTM + CRF的解释
看完再看看这位的博客
Bi-LSTM-CRF for Sequence Labeling PENG
这两部分内容都看完了之后,我就接着上面这位的博客继续讲,他讲的很好了,只是没有讲的更细致。

首先我们来看看Score的定义:

这部分博主的解释很详细了,这里我想多提醒一下的是,我们的每一个Score都是对应于一个完整的路径,举例说
【我 爱 中国人民】对应标签【N V N】那这个标签就是一个完整的路径,也就对应一个Score值。

接下来我想讲的是这个公式

这个公式成立是很显然的,动笔算一算就知道了,代码里其实就是用了这个公式的原理,但是这位博主并没有详细解释代码是怎么实现这个公式的,所以我就写下这篇博客来完成这位博主没有做完的工作。
先上代码

def _forward_alg(self, feats):
# Do the forward algorithm to compute the partition function
init_alphas = torch.Tensor(1, self.tagset_size).fill_(-10000.)
# START_TAG has all of the score.
init_alphas[0][self.tag_to_ix[START_TAG]] = 0.

# Wrap in a variable so that we will get automatic backprop
forward_var = autograd.Variable(init_alphas)

# Iterate through the sentence
for feat in feats:
alphas_t = [] # The forward variables at this timestep
for next_tag in range(self.tagset_size):
# broadcast the emission score: it is the same regardless of
# the previous tag
emit_score = feat[next_tag].view(
1, -1).expand(1, self.tagset_size)
# the ith entry of trans_score is the score of transitioning to
# next_tag from i
trans_score = self.transitions[next_tag].view(1, -1)
# The ith entry of next_tag_var is the value for the
# edge (i -> next_tag) before we do log-sum-exp
next_tag_var = forward_var + trans_score + emit_score
# The forward variable for this tag is log-sum-exp of all the
# scores.
alphas_t.append(log_sum_exp(next_tag_var))
forward_var = torch.cat(alphas_t).view(1, -1)
terminal_var = forward_var + self.transitions[self.tag_to_ix[STOP_TAG]]
alpha = log_sum_exp(terminal_var)
return alpha
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
我们看到有这么一段代码
next_tag_var = forward_var + trans_score + emit_score
我们主要就是来讲讲他。
首先这个算法的思想是:假设我们要做一个词性标注的任务,对句子【我 爱 中华人民】,我们要对这个句子做
意思就是 对这个句子所有可能的标注,都算出来他们的Score,然后按照指数次幂加起来,再取对数。一般来说取所有可能的标注情况比较复杂,我们这里举例是长度为三,但是实际过程中,可能比这个要大得多,所以我们需要有一个简单高效得算法。也就是我们程序中得用得算法, 他是这么算得。
先算出【我, 爱】可能标注得所有情况,取 log_sum_exp 然后加上 转换到【中国人民】得特征值 再加上【中国人民】对应得某个标签得特征值。其等价于【我,爱,中国人民】所有可能特征值指数次幂相加,然后取对数

接下来我们来验证一下是不是这样

首先我们假设词性一共只有两种 名词N 和 动词 V
那么【我,爱】得词性组合一共有四种 N + N,N + V, V + N, V + V
那么【爱】标注为N时得log_sum_exp 为
log(escore(N,N)+score(V,N))
log(escore(N,N)+score(V,N))

【爱】 标注为 V时的 log_sum_exp为
log(escore(N,V)+score(V,V))
log(escore(N,V)+score(V,V))

我们的forward列表里就是存在着这两个值,即:
[
log(escore(N,N)+score(V,N))
log(escore(N,N)+score(V,N))

log(escore(N,N)+score(V,N))
log(escore(N,N)+score(V,N))
]
在这里我在提醒一下score(N,V)的定义,前面有写哈,可以翻前面取看看。
假设【中华人民】得词性为N,我们按照代码来写一下公式,在forward列表对应位置相加就是这样
[
log(escore(N+N)+score(V+N)+N+N−>N)
log(escore(N+N)+score(V+N)+N+N−>N)
,
log(escore(N,V)+score(V,V))+N+V−>N
log(escore(N,V)+score(V,V))+N+V−>N

]
我们的N+N->N可以写成 log(eN+N−>N)log(eN+N−>N),这样的话,我们的列表就变成
[
log(escore(N,N)+score(V,N)+N+N−>N)log(escore(N,N)+score(V,N)+N+N−>N),
log(escore(N,V)+score(V,V)+N+V−>N)log(escore(N,V)+score(V,V)+N+V−>N),
]
再次回想一下score的定义,我们就能知道这个式子其实也就是等于
[
log(escore(∗,N,N))log(escore(∗,N,N)),log(escore(∗,V,N)log(escore(∗,V,N)
]
我们对这个式子 long_sum_exp就变成了log∑(escore(∗,∗,N))log∑(escore(∗,∗,N))
他的直观意义就是【中华人民】的词性为N的时候,整个score值的long_sum_exp
以上是我们把【中华人民】作为N的举例,如果我们再举V的情况,计算过程同上,最后我们要把 中华人民两种情况的再做一次log_sum_exp,这样我们就完成了【我,爱,中华人民】所有情况的score值的log_sum_exp
以上就是对LSTM+crf 的所有讲解,有问题,请留言
---------------------
作者:Johnny_Cuii
来源:CSDN
原文:https://blog.csdn.net/cuihuijun1hao/article/details/79405740
版权声明:本文为博主原创文章,转载请附上博文链接!

Pytorch Bi-LSTM + CRF 代码详解的更多相关文章

  1. pytorch BiLSTM+CRF代码详解 重点

    一. BILSTM + CRF介绍 https://www.jianshu.com/p/97cb3b6db573 1.介绍 基于神经网络的方法,在命名实体识别任务中非常流行和普遍. 如果你不知道Bi- ...

  2. pytorch lstm crf 代码理解

    好久没有写博客了,这一次就将最近看的pytorch 教程中的lstm+crf的一些心得与困惑记录下来. 原文 PyTorch Tutorials 参考了很多其他大神的博客,https://blog.c ...

  3. Github-jcjohnson/torch-rnn代码详解

    Github-jcjohnson/torch-rnn代码详解 zoerywzhou@gmail.com http://www.cnblogs.com/swje/ 作者:Zhouwan  2016-3- ...

  4. Github-karpathy/char-rnn代码详解

    Github-karpathy/char-rnn代码详解 zoerywzhou@gmail.com http://www.cnblogs.com/swje/ 作者:Zhouwan  2016-1-10 ...

  5. Kaggle网站流量预测任务第一名解决方案:从模型到代码详解时序预测

    Kaggle网站流量预测任务第一名解决方案:从模型到代码详解时序预测 2017年12月13日 17:39:11 机器之心V 阅读数:5931   近日,Artur Suilin 等人发布了 Kaggl ...

  6. BM算法  Boyer-Moore高质量实现代码详解与算法详解

    Boyer-Moore高质量实现代码详解与算法详解 鉴于我见到对算法本身分析非常透彻的文章以及实现的非常精巧的文章,所以就转载了,本文的贡献在于将两者结合起来,方便大家了解代码实现! 算法详解转自:h ...

  7. ASP.NET MVC 5 学习教程:生成的代码详解

    原文 ASP.NET MVC 5 学习教程:生成的代码详解 起飞网 ASP.NET MVC 5 学习教程目录: 添加控制器 添加视图 修改视图和布局页 控制器传递数据给视图 添加模型 创建连接字符串 ...

  8. 代码详解:TensorFlow Core带你探索深度神经网络“黑匣子”

    来源商业新知网,原标题:代码详解:TensorFlow Core带你探索深度神经网络“黑匣子” 想学TensorFlow?先从低阶API开始吧~某种程度而言,它能够帮助我们更好地理解Tensorflo ...

  9. JAVA类与类之间的全部关系简述+代码详解

    本文转自: https://blog.csdn.net/wq6ylg08/article/details/81092056类和类之间关系包括了 is a,has a, use a三种关系(1)is a ...

随机推荐

  1. 【JZOJ3216】【SDOI2013】淘金

    ╰( ̄▽ ̄)╭ 小 Z在玩一个 叫做<淘金者>的游戏.游戏的世界是一个 二维坐标 .X轴.Y轴坐标范围均为1..N.初始的时候,所有的整数坐标点上均有一块金子,共 N*N 块. 一阵风吹过 ...

  2. hive行转列的高级用法later view explode

    先贴出一个示例: 参考链接

  3. DataIntputStream / DataOutputStream 类

    1. DataInputStream类(熟悉)   (1)基本概念 java.io.DataInputStream类用于读取java中的基本数据类型.   (2)常用的方法 DataInputStre ...

  4. JQuery--jQquery控制CSS样式

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  5. golang数据类型二

    字符类型 3.14基本数据类型的相互转换 3.15基本数据类型和string的转换 FormatInt // FormatUint 将 int 型整数 i 转换为字符串形式// base:进位制(2 ...

  6. pl/sql基础知识—函数快速入门

    n  函数 函数用于返回特定的数据,当建立函数式,在函数头部必须包含return子句,而在函数体内必须包含return语句返回的数据,我们可以使用create function来建立函数,实际案例: ...

  7. [idea]idea配置tomcat 标签: tomcatidea 2017-03-12 22:12 402人阅读 评论(19)

    我们在使用idea的时候,一定会遇到的一步,就是使用tomcat来发布我们的项目,那么,如何在idea中设置tomcat呢?下面就随小编来一起学习一下吧. 设置tomcat 打开设置界面 Run-&g ...

  8. 容器云平台使用体验:DaoCloud

    容器技术风起云涌,在国内也涌现出了很多容器技术创业公司,本文介绍容器厂商DaoCloud提供的容器云平台,通过使用容器云平台,可以让大家更加了解容器,并可以学习不同容器云平台的优势. 1.       ...

  9. AtCoder Regular Contest 094 D Worst Case【思维题】

    https://arc094.contest.atcoder.jp/tasks/arc094_b 题意: 在2次超多人的比赛中,你取得的成绩依次为第A名和第B名.一个人的成绩为a和b时,当且仅当ab& ...

  10. poj2391 最大流+拆点

    题意:F块草坪,上面有n头牛,可以容纳m个牛遮雨.将草坪一份为2,成为二部图. 对于此题,和poj2112很像,只是2112很明显的二部图.这道题就开始敲,但是建图遇到问题,草坪的2个值怎么处理,于是 ...