Bi-LSTM-CRF for Sequence Labeling
做了一段时间的Sequence Labeling的工作,发现在NER任务上面,很多论文都采用LSTM-CRFs的结构。CRF在最后一层应用进来可以考虑到概率最大的最优label路径,可以提高指标。
一般的深度学习框架是没有CRF layer的,需要手动实现。最近在学习PyTorch,里面有一个Bi-LSTM-CRF的tutorial实现。不得不说PyTorch的tutorial真是太良心了,基本涵盖了NLP领域各个流行的model实现。在这里从头梳理一遍,也记录下学习过程中的一些问题。
Bi-LSTM-CRF的结构一般如上,最后一层利用CRF来学习一个最优路径。Bi-LSTM layer的输出维度是tag size,这就相当于是每个词映射到tag的发射概率值,设Bi-LSTM的输出矩阵为,其中代表词映射到的非归一化概率。对于CRF来说,我们假定存在一个转移矩阵,则代表转移到的转移概率。
对于输入序列对应的输出tag序列,定义分数为
利用Softmax函数,我们为每一个正确的tag序列定义一个概率值(代表所有的tag序列,包括不可能出现的)
因而在训练中,我们只需要最大化似然概率即可,这里我们利用对数似然
所以我们将损失函数定义为,就可以利用梯度下降法来进行网络的学习了。
在对损失函数进行计算的时候,的计算很简单,而(下面记作logsumexp)的计算稍微复杂一些,因为需要计算每一条可能路径的分数。这里用一种简便的方法,对于到词的路径,可以先把到词的logsumexp计算出来,因为
因此先计算每一步的路径分数和直接计算全局分数相同,但这样可以大大减少计算的时间。下面是PyTorch中的代码
def _forward_alg(self, feats):# Do the forward algorithm to compute the partition functioninit_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 backpropforward_var = autograd.Variable(init_alphas)# Iterate through the sentencefor feat in feats:alphas_t = [] # The forward variables at this timestepfor next_tag in range(self.tagset_size):# broadcast the emission score: it is the same regardless of# the previous tagemit_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 itrans_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-expnext_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
在解码时,采用Viterbi算法
def _viterbi_decode(self, feats):backpointers = []# Initialize the viterbi variables in log spaceinit_vvars = torch.Tensor(1, self.tagset_size).fill_(-10000.)init_vvars[0][self.tag_to_ix[START_TAG]] = 0# forward_var at step i holds the viterbi variables for step i-1forward_var = autograd.Variable(init_vvars)for feat in feats:bptrs_t = [] # holds the backpointers for this stepviterbivars_t = [] # holds the viterbi variables for this stepfor next_tag in range(self.tagset_size):# next_tag_var[i] holds the viterbi variable for tag i at the# previous step, plus the score of transitioning# from tag i to next_tag.# We don't include the emission scores here because the max# does not depend on them (we add them in below)next_tag_var = forward_var + self.transitions[next_tag]best_tag_id = argmax(next_tag_var)bptrs_t.append(best_tag_id)viterbivars_t.append(next_tag_var[0][best_tag_id])# Now add in the emission scores, and assign forward_var to the set# of viterbi variables we just computedforward_var = (torch.cat(viterbivars_t) + feat).view(1, -1)backpointers.append(bptrs_t)# Transition to STOP_TAGterminal_var = forward_var + self.transitions[self.tag_to_ix[STOP_TAG]]best_tag_id = argmax(terminal_var)path_score = terminal_var[0][best_tag_id]# Follow the back pointers to decode the best path.best_path = [best_tag_id]for bptrs_t in reversed(backpointers):best_tag_id = bptrs_t[best_tag_id]best_path.append(best_tag_id)# Pop off the start tag (we dont want to return that to the caller)start = best_path.pop()assert start == self.tag_to_ix[START_TAG] # Sanity checkbest_path.reverse()return path_score, best_path
全部代码实现可以移步Bi-LSTM-CRF。
参考
Bidirectional LSTM-CRF Models for Sequence Tagging
Neural Architectures for Named Entity Recognition
Advanced: Making Dynamic Decisions and the Bi-LSTM CRF
Bi-LSTM-CRF for Sequence Labeling相关推荐
- TensorFlow (RNN)深度学习 双向LSTM(BiLSTM)+CRF 实现 sequence labeling 序列标注问题 源码下载...
http://blog.csdn.net/scotfield_msn/article/details/60339415 在TensorFlow (RNN)深度学习下 双向LSTM(BiLSTM)+CR ...
- [论文速览] Dataset and Neural Recurrent Sequence Labeling Model for Open-Domain Factoid Question Answeri
开放域QA的数据集和神经递归序列标记模型,2016 ,https://arxiv.org/abs/1607.06275 abstract 近年来,基于神经网络的问答系统(QA)取得了令人瞩目的成果,但 ...
- End to End Sequence Labeling via Bi-directional LSTM CNNs CRF
来看看今日头条首席科学家的论文: End-to-end Sequence Labeling via Bi-directional LSTM-CNNs-CRF 使用LSTM方法进行序列标注,完成大规模标 ...
- 论文学习20-End-to-end Sequence Labeling via Bi-directional LSTM-CNNs-CRF(序列标注,2016ACL
文章目录 abstract 1.introduction 2.Architecture 2.1 CNN for Character-level Representation 2.2 BiLSTM 2. ...
- 论文学习19-Structured prediction models for RNN based sequence labeling in clinical text(LSTM_CRF,2016)
文章目录 abstract 1. Introduction 2.相关工作 3.方法 3.1 Bi-LSTM (baseline) 3.2BiLSTM+CRF 3.3 BiLSTM_CRF with p ...
- 复旦大学桂韬:Uncertainty—Aware Sequence Labeling
不到现场,照样看最干货的学术报告! 嗨,大家好.这里是学术报告专栏,读芯术小编不定期挑选并亲自跑会,为大家奉献科技领域最优秀的学术报告,为同学们记录报告干货,并想方设法搞到一手的PPT和现场视频--足 ...
- pytorch lstm crf 代码理解 重点
好久没有写博客了,这一次就将最近看的pytorch 教程中的lstm+crf的一些心得与困惑记录下来. 原文 PyTorch Tutorials 参考了很多其他大神的博客,https://blog.c ...
- pytorch lstm crf 代码理解
好久没有写博客了,这一次就将最近看的pytorch 教程中的lstm+crf的一些心得与困惑记录下来. 原文 PyTorch Tutorials 参考了很多其他大神的博客,https://blog.c ...
- 知识图谱-LSTM+CRF人物关系抽取实战
文章目录 一.引言 二.实践简介 1.数据来源 2.预测类别(7个) 3.框架 4.模型结构 5.项目流程 三.数据标注 四.实战 1.数据预处理 1.1 词典映射 1.2 从训练文件中获取句子和标签 ...
最新文章
- 青源 LIVE 预告 | 华为诺亚韩凯:视觉 Transformer 综述
- Python-S13-day2-之购物车
- 关于MySql中自增长id设置初始值
- Python | 7招教你识别一个网站是否是Django后台
- IDEA: .java文件和.class不一致
- Postgresql 填充所有的时间点
- BZOJ 2301 Problem b
- jenkins教程菜鸟_Jenkins教程:在Windows平台安装Jenkins
- 【Linux】rm -rf 删除命令
- 树莓派4使用CSI摄像头
- 在x86笔记本电脑上运行树莓派操作系统
- 适合学生用的蓝牙耳机哪款好?学生党无线蓝牙耳机推荐
- “三无”大学生,就业真难
- 正则密码验证,包含数字、字母、特殊符号
- wuc-tab标签点击不了_不干胶标签专属定制
- vue美团电影模拟实现
- Python中的np.array理解
- 【QMT之xtquant】活用xtdata,激活download_history_data2批量高效获取行情数据
- 10个最好用的在线配色网站推荐
- VR成为下一代计算平台的关键技术:面部追踪