TensorFlow教程——Bi-LSTM+CRF进行序列标注(代码浅析)
https://blog.csdn.net/guolindonggld/article/details/79044574
Bi-LSTM
使用TensorFlow构建Bi-LSTM时经常是下面的代码:
cell_fw = tf.contrib.rnn.LSTMCell(num_units=100)
cell_bw = tf.contrib.rnn.LSTMCell(num_units=100)
(outputs, output_states) = tf.nn.bidirectional_dynamic_rnn(cell_fw, cell_bw, inputs,
sequence_length=300)
- 1
- 2
- 3
- 4
- 5
首先下面是我画的Bi-LSTM示意图:
其实LSTM使用起来很简单,就是输入一排的向量,然后输出一排的向量。构建时只要设定两个超参数:num_units和sequence_length。
LSTMCell
tf.contrib.rnn.LSTMCell(
num_units,
use_peepholes=False,
cell_clip=None,
initializer=None,
num_proj=None,
proj_clip=None,
num_unit_shards=None,
num_proj_shards=None,
forget_bias=1.0,
state_is_tuple=True,
activation=None,
reuse=None
)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
上面的LSTM Cell只有一个超参数需要设定,num_units,即输出向量的维度。
bidirectional_dynamic_rnn()
(outputs, output_states) = tf.nn.bidirectional_dynamic_rnn(
cell_fw,
cell_bw,
inputs,
sequence_length=None,
initial_state_fw=None,
initial_state_bw=None,
dtype=None,
parallel_iterations=None,
swap_memory=False,
time_major=False,
scope=None
)
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
这个函数唯一需要设定的超参数就是序列长度sequence_length。
输入:
inputs的shape通常是[batch_size, sequence_length, dim_embedding]。
输出:
outputs是一个(output_fw, output_bw)元组,output_fw和output_bw的shape都是[batch_size, sequence_length, num_units]
output_states是一个(output_state_fw, output_state_bw) 元组,分别是前向和后向最后一个Cell的Output,output_state_fw和output_state_bw的类型都是LSTMStateTuple,这个类有两个属性c和h,分别表示Memory Cell和Hidden State,如下图:
CRF
对于序列标注问题,通常会在LSTM的输出后接一个CRF层:将LSTM的输出通过线性变换得到维度为[batch_size, max_seq_len, num_tags]的张量,这个张量再作为一元势函数(Unary Potentials)输入到CRF层。
# 将两个LSTM的输出合并
output_fw, output_bw = outputs
output = tf.concat([output_fw, output_bw], axis=-1)
# 变换矩阵,可训练参数
W = tf.get_variable("W", [2 * num_units, num_tags])
# 线性变换
matricized_output = tf.reshape(output, [-1, 2 * num_units])
matricized_unary_scores = tf.matmul(matricized_output , W)
unary_scores = tf.reshape(matricized_unary_scores, [batch_size, max_seq_len, num_tags])
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
损失函数
# Loss函数
log_likelihood, transition_params = tf.contrib.crf.crf_log_likelihood(unary_scores, tags, sequence_lengths)
loss = tf.reduce_mean(-log_likelihood)
- 1
- 2
- 3
其中
tags:维度为[batch_size, max_seq_len]的矩阵,也就是Golden标签,注意这里的标签都是以索引方式表示的。
sequence_lengths:维度为[batch_size]的向量,记录了每个序列的长度。
log_likelihood:维度为[batch_size]的向量,每个元素代表每个给定序列的Log-Likelihood。
transition_params :维度为[num_tags, num_tags]的转移矩阵。注意这里的转移矩阵不像传统的HMM概率转移矩阵那样要求每个元素非负且每一行的和为1,这里的每个元素取值范围是实数(正负都可以)。
解码
decode_tags, best_score = tf.contrib.crf.crf_decode(unary_scores, transition_params, sequence_lengths)
- 1
其中
decode_tags:维度为[batch_size, max_seq_len]的矩阵,包含最高分的标签序列。
best_score :维度为[batch_size]的向量,包含最高分数。
TensorFlow教程——Bi-LSTM+CRF进行序列标注(代码浅析)的更多相关文章
- LSTM+CRF进行序列标注
为什么使用LSTM+CRF进行序列标注 直接使用LSTM进行序列标注时只考虑了输入序列的信息,即单词信息,没有考虑输出信息,即标签信息,这样无法对标签信息进行建模,所以在LSTM的基础上引入一个标签转 ...
- ALBERT+BiLSTM+CRF实现序列标注
一.模型框架图 二.分层介绍 1)ALBERT层 albert是以单个汉字作为输入的(本次配置最大为128个,短句做padding),两边分别加上开始标识CLS和结束标识SEP,输出的是每个输入wor ...
- TensorFlow (RNN)深度学习 双向LSTM(BiLSTM)+CRF 实现 sequence labeling 序列标注问题 源码下载
http://blog.csdn.net/scotfield_msn/article/details/60339415 在TensorFlow (RNN)深度学习下 双向LSTM(BiLSTM)+CR ...
- 用CRF++开源工具做文本序列标注教程
本文只介绍如何快速的使用CRF++做序列标注,对其中的原理和训练测试参数不做介绍. 官网地址:CRF++: Yet Another CRF toolkit 主要完成如下功能: 输入 -> &qu ...
- CNN做序列标注问题(tensorflow)
一.搭建简单的CNN做序列标注代码 import tensorflow as tf import numpy as np import matplotlib.pyplot as plt TIME_ST ...
- 基于CRF序列标注的中文依存句法分析器的Java实现
这是一个基于CRF的中文依存句法分析器,内部CRF模型的特征函数采用 双数组Trie树(DoubleArrayTrie)储存,解码采用特化的维特比后向算法.相较于<最大熵依存句法分析器的实现&g ...
- BI-LSTM-CRF在序列标注中的应用
1. 前言 在NLP中有几个经典的序列标注问题,词性标注(POS),chunking和命名实体识别(NER).序列标注器的输出可用于另外的应用程序.例如,可以利用在用户搜索查询上训练的命名实体识别器来 ...
- 转:TensorFlow入门(六) 双端 LSTM 实现序列标注(分词)
http://blog.csdn.net/Jerr__y/article/details/70471066 欢迎转载,但请务必注明原文出处及作者信息. @author: huangyongye @cr ...
- Bi-LSTM+CRF在文本序列标注中的应用
传统 CRF 中的输入 X 向量一般是 word 的 one-hot 形式,前面提到这种形式的输入损失了很多词语的语义信息.有了词嵌入方法之后,词向量形式的词表征一般效果比 one-hot 表示的特征 ...
随机推荐
- mySql---剖析InnoDB索引原理
摘要: 本篇为参考别人的文章(http://blog.csdn.net/voidccc/article/details/40077329) 1 各种树形结构 本来不打算从二叉搜索树开始,因为网上已经有 ...
- java execute、executeQuery和executeUpdate之间的区别
在用纯JSP做一个页面报警功能的时候习惯性的用executeQuery来执行SQL语句,结果执行update时就遇到问题,语句能执行,但返回结果出现问题,另外还忽略了executeUpdate的返回值 ...
- ARM 非对齐的数据访问操作
I’m confused about unaligned memory accesses on ARM. My understanding was that they’re not allowed — ...
- 荣耀 6 安装 SD 卡,提示:SD卡已安全移除
先前买了个 荣耀6(购买链接),自带存储只有 16G,用来一段时间后,老是提示存储不足.后来发现是 微信 等软件占用了好多存储(缓存),, 好吧,在京东上买了个 64G 扩展卡(购买链接),安装过程如 ...
- 对一个前端使用AngularJS后端使用ASP.NET Web API项目的理解(4)
chsakell分享了一个前端使用AngularJS,后端使用ASP.NET Web API的项目. 源码: https://github.com/chsakell/spa-webapi-angula ...
- [erlang] mnesia
原文地址: http://www.cnblogs.com/bluefrog/archive/2012/05/16/2504625.html 本来是项目合作的,可是你却一而再再而三的使用这招,我处理愤怒 ...
- 利用MPMoviePlayerViewController 播放视频 iOS
方法一: @property (nonatomic, strong) MPMoviePlayerController *player; NSString *url = [[NSBundle mainB ...
- value stored to value2 during its initialization is never read
警告:value stored to value2 during its initialization is never read NSMutableArray *datesArray = [[NSM ...
- winform 给textbox 增加 或 减小字体大小 z
private void btnAddFont_Click(object sender, EventArgs e) { float fSize = this.txtResult.Font.Size; ...
- 自定义兼容多种Protobuf协议的编解码器
<从零开始搭建游戏服务器>自定义兼容多种Protobuf协议的编解码器 直接在protobuf序列化数据的前面,加上一个自定义的协议头,协议头里包含序列数据的长度和对应的数据类型,在数据解 ...