Variable Sequence Lengths in TensorFlow

2024-08-27 09:08

本文主要是介绍Variable Sequence Lengths in TensorFlow,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

翻译这篇文章:https://danijar.com/variable-sequence-lengths-in-tensorflow/
大意是因为在用rnn做nlp任务的时候,不同的句子长度不一样,如果我们使用static_rnn我们需要固定最大句子长度,这其实是不合适的。因为在句子实际长度m小于最大长度n的时候,我们实际上希望得到m时刻的输出,而不是n时刻的输出(因为m时刻句子已经结束),但是因为static_rnn我们不得不继续计算。这样不仅会增加很多的计算量,并且也会对我们的输出结果造成影响。所以我们使用dynamic_rnn.这样有一个好处就是在超过句子实际长度的时间的输出直接返回0,不在计算。
我们只需要添加sequence_length这个参数。这个参数是一个1-D,大小为batchsize的vector。
对于每个输入的shape是:batch size x max length x features。

def length(sequence):#sign大于0的等于1,小于0的等于-1,等于0的输出0#因为句子最大长度是max_lenth,不足的补0,所以通过reduce_max得到对于每个时间点的最大值#(因为补充值都为0,原有句子词向量的绝对值大于0)这样经过sign句子实际长度step值都为1,补充的都为0used = tf.sign(tf.reduce_max(tf.abs(sequence), 2))#这样对于每一个batch的step那一维求和就能得到句子长度length = tf.reduce_sum(used, 1)length = tf.cast(length, tf.int32)return length

这样我们就可以用下面的代码构建rnn网络:

max_length = 100
frame_size = 64
num_hidden = 200sequence = tf.placeholder(tf.float32, [None, max_length, frame_size])
output, state = tf.nn.dynamic_rnn(tf.contrib.rnn.GRUCell(num_hidden),sequence,dtype=tf.float32,sequence_length=length(sequence),
)

Masking the Cost Function:
对于加了sequence_lenth的output的shape依旧为batch_size x max_length x out_size。只不过大于句子实际长度的step输出为0。再计算损失的时候我们reduce_mean就不合适了,因为它除以的是句子的max_lenth,而不是实际长度。
所以我们可以使用下面的代码计算损失:

def cost(output, target):# Compute cross entropy for each frame.cross_entropy = target * tf.log(output)#求出每一个step的损失cross_entropy = -tf.reduce_sum(cross_entropy, 2)#对于每一个step,赋值为1或者0mask = tf.sign(tf.reduce_max(tf.abs(target), 2))#这一步我的理解如果前面求出的已经是变长的输出,那么补充的step值本身就是0,就不用这一步了#如果假设求出的是定长的,那么补充部分乘以0就变为0了cross_entropy *= mask# Average over actual sequence lengths.cross_entropy = tf.reduce_sum(cross_entropy, 1)cross_entropy /= tf.reduce_sum(mask, 1)return tf.reduce_mean(cross_entropy)

选择句子的最后输出:
因为在句子实际长度之后的step都赋值为0了,不能像以前一样直接去output[:,-1.:],但是tensorflow又不像numpy支持切片索引,直接output[:, length - 1]就可以了。所以要使用下面这段代码:

def last_relevant(output, length):batch_size = tf.shape(output)[0]max_length = tf.shape(output)[1]out_size = int(output.get_shape()[2])index = tf.range(0, batch_size) * max_length + (length - 1)#把output变成2-D的,在后面直接使用gather函数和索引就取到所有的结果了,类似embedding_lookup。flat = tf.reshape(output, [-1, out_size])relevant = tf.gather(flat, index)return relevant

预测:

num_classes = 10last = last_relevant(output)
weight = tf.Variable(tf.truncated_normal([num_hidden, num_classes], stddev=0.1))
bias = tf.Variable(tf.constant(0.1, shape=[num_classes]))
prediction = tf.nn.softmax(tf.matmul(last, weight) + bias)

这篇关于Variable Sequence Lengths in TensorFlow的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1111239

相关文章

win10不用anaconda安装tensorflow-cpu并导入pycharm

记录一下防止忘了 一、前提:已经安装了python3.6.4,想用tensorflow的包 二、在pycharm中File-Settings-Project Interpreter点“+”号导入很慢,所以直接在cmd中使用 pip install -i https://mirrors.aliyun.com/pypi/simple tensorflow-cpu下载好,默认下载的tensorflow

稀疏自编码器tensorflow

自编码器是一种无监督机器学习算法,通过计算自编码的输出与原输入的误差,不断调节自编码器的参数,最终训练出模型。自编码器可以用于压缩输入信息,提取有用的输入特征。如,[1,0,0,0],[0,1,0,0],[0,0,1,0],[0,0,0,1]四比特信息可以压缩成两位,[0,0],[1,0],[1,1],[0,1]。此时,自编码器的中间层的神经元个数为2。但是,有时中间隐藏层的神经元

Tensorflow实现与门感知机

感知机是最简单的神经网络,通过输入,进行加权处理,经过刺激函数,得到输出。通过输出计算误差,调整权重,最终,得到合适的加权函数。 今天,我通过tensorflow实现简单的感知机。 首先,初始化变量:     num_nodes = 2     output_units = 1     w = tf.Variable(tf.truncated_normal([num_nodes,output

Tensorflow lstm实现的小说撰写预测

最近,在研究深度学习方面的知识,结合Tensorflow,完成了基于lstm的小说预测程序demo。 lstm是改进的RNN,具有长期记忆功能,相对于RNN,增加了多个门来控制输入与输出。原理方面的知识网上很多,在此,我只是将我短暂学习的tensorflow写一个预测小说的demo,如果有错误,还望大家指出。 1、将小说进行分词,去除空格,建立词汇表与id的字典,生成初始输入模型的x与y d

浙大数据结构:02-线性结构4 Pop Sequence

这道题我们采用数组来模拟堆栈和队列。 简单说一下大致思路,我们用栈来存1234.....,队列来存输入的一组数据,栈与队列进行匹配,相同就pop 机翻 1、条件准备 stk是栈,que是队列。 tt指向的是栈中下标,front指向队头,rear指向队尾。 初始化栈顶为0,队头为0,队尾为-1 #include<iostream>using namespace std;#defi

Deepin Linux安装TensorFlow

Deepin Linux安装TensorFlow 1.首先检查是否有Python,一般deepin系统都自带python的。   2.安装pip Sudo appt-get install pip来安装pip,如果失败就先更新一下sudo apt-get updata,然后再sudo apt-get install pip,如果定位失败,就sudo apt-get install pyth

【UVA】1626-Brackets sequence(动态规划)

一道算是比较难理解的动规。 状态转移分2个: (用d[i][j]表示在i~j内最少需要添加几个括号,保持平衡) 1.如果s[i]和s[j]是一对括号,那么d[i][j] = d[i + 1][j - 1] 2.否则的话 d[i][j] = min(d[i][k],[k + 1][j]); 边界是d[i + 1][i] = 0; d[i][i] = 1; 13993644 162

【UVA】10534 - Wavio Sequence(LIS最长上升子序列)

这题一看10000的数据量就知道必须用nlog(n)的时间复杂度。 所以特意去看了最长上升子序列的nlog(n)的算法。 如果有2个位置,该位置上的元素为A[i]和A[j],并且他们满足以下条件: 1.dp[i] = dp[j]    (dp[x]代表以x结尾的最长上升子序列长度) 2.A[i] < A[j] 3.i < j 那么毫无疑问,选择dp[i] 一定优于选择dp[j] 那么

2015年多校联合训练第一场OO’s Sequence(hdu5288)

题意:给定一个长度为n的序列,规定f(l,r)是对于l,r范围内的某个数字a[i],都不能找到一个对应的j使得a[i]%a[j]=0,那么l,r内有多少个i,f(l,r)就是几。问所有f(l,r)的总和是多少。 公式中给出的区间,也就是所有存在的区间。 思路:直接枚举每一个数字,对于这个数字,如果这个数字是合法的i,那么向左能扩展的最大长度是多少,向右能扩展的最大长度是多少,那么i为合法的情况

终止distributed tensorflow的ps进程

1.直接终止: $ ps -ef | grep python | grep 文件名 | awk {'print $2'} | xargs kill文件名为当前运行的程序,名称如:distribute.py 2.查找pid,后kill: $ ps -ef | grep python | grep 文件名 | awk {'print $2'}$ kill -9 <pid>