前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >深度学习算法(第17期)----RNN如何处理变化长度的输入和输出?

深度学习算法(第17期)----RNN如何处理变化长度的输入和输出?

作者头像
智能算法
发布2019-05-22 00:11:15
3.8K0
发布2019-05-22 00:11:15
举报
文章被收录于专栏:智能算法智能算法

上期我们一起学习了静态RNN和动态RNN的区别, 深度学习算法(第16期)----静态RNN和动态RNN 我们知道之前学过的CNN的输入输出都是固定长度,今天我们一起学习下RNN是怎么处理变化长度的输入输出的?

1. 处理变化长度的输入

到目前为止,我们已经知道在RNN中怎么使用固定长度的输入,准确的说是两个时刻长度的输入,但是如果输入的序列是变化长度的呢?比如一个句子。这种情况下,当我们调用dynamic_rnn()或者static_rnn()的时候,需要设置参数sequence_length。该参数应该是一个表示每个样本输入序列大小的一维tensor。走个例子看看:

代码语言:javascript
复制
seq_length = tf.placeholder(tf.int32, [None])
[...]
outputs, states = tf.nn.dynamic_rnn(basic_cell, X, dtype=tf.float32,
                sequence_length=seq_length)

就上期的例子,假如说,第二个样本的输入长度为1的话,那么为了匹配输入tensor的大小,必须将第二个样本的第二个输入设为0,如下:

代码语言:javascript
复制
X_batch = np.array([
# step 0 step 1
[[0, 1, 2], [9, 8, 7]], # instance 0
[[3, 4, 5], [0, 0, 0]], # instance 1 (padded with a zero vector)
[[6, 7, 8], [6, 5, 4]], # instance 2
[[9, 0, 1], [3, 2, 1]], # instance 3
])
seq_length_batch = np.array([2, 1, 2, 2])

当然,在我们运行RNN的时候,需要将输入X和样本长度seq_length都传输进去,如下:

代码语言:javascript
复制
with tf.Session() as sess:
    init.run()
    outputs_val, states_val = sess.run(
        [outputs, states], feed_dict={X: X_batch, seq_length: seq_length_batch})

这样的话呢,RNN就会根据输入序列的情况输出相应的结果,比方上面例子中第二个样本的第二个时刻为0,那么第二个样本在第二个时刻的输出情况就是0,如下:

代码语言:javascript
复制
>> print(outputs_val)
[[[-0.2964572 0.82874775 -0.34216955 -0.75720584 0.19011548]
[ 0.51955646 1. 0.99999022 -0.99984968 -0.24616946]] # final state
[[-0.12842922 0.99981797 0.84704727 -0.99570125 0.38665548] # final state
[ 0. 0. 0. 0. 0. ]] # zero vector
[[ 0.04731077 0.99999976 0.99330056 -0.999933 0.55339795]
[-0.32477224 0.99996376 0.99933046 -0.99711186 0.10981458]] # final state
[[ 0.70323634 0.99309105 0.99909431 -0.85363263 0.7472108 ]
[-0.43738723 0.91517633 0.97817528 -0.91763324 0.11047263]]]

还有,输出的states tensor包括了每一个记忆单元的最后一个状态(不包括0输入的),如下:

代码语言:javascript
复制
>>> print(states_val)
[[ 0.51955646 1. 0.99999022 -0.99984968 -0.24616946] # t = 1
[-0.12842922 0.99981797 0.84704727 -0.99570125 0.38665548] # t = 0 !!!
[-0.32477224 0.99996376 0.99933046 -0.99711186 0.10981458] # t = 1
[-0.43738723 0.91517633 0.97817528 -0.91763324 0.11047263]] # t = 1

好了,我们知道了RNN是怎么处理变长度的输入,那么输出序列的长度如果也是变化的,该怎么办呢?

2. 处理变化长度的输出

假如我们已经提前知道每个样本的输出的长度的话,比方说,我们知道每个样本输出的长度和输入的一样长,那么我们就可以像上面一样通过设置sequence_length参数来处理。 但是不幸的是,一般情况下,我们都不知道输出的长度,比方说翻译一个句子,输出的长度往往和输入的长度是不一致的。这种情况下最常用的解决办法是去定义一个特殊的输出,称为end-of-sequence token(EOS token)。这个我们后面再讨论。

学习了这么多的关于RNN的知识,下一期我们将学习如何训练RNN网络?

今天我们主要从输入和输出序列的变化长度方面,来理解了下RNN的怎么处理的方面的知识,希望有些收获,欢迎留言或进社区共同交流,喜欢的话,就点个在看吧,您也可以置顶公众号,第一时间接收最新内容。


智能算法,与您携手,沉淀自己,引领AI!

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-04-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 智能算法 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 处理变化长度的输入
  • 2. 处理变化长度的输出
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档