普通的RNN:
因为这个左边图中间循环的箭头难以理解,所以将其按照时间轴展开成多个单元。网络只有一个,网络只有一个,网络只有一个, 并不是想右边那样画的。右边的图只不过是不同时刻的输入。因为每个时刻RNN会产生两个输出,一个output和一个state,上一个时刻state和当前作为输入给当前网络,就如右图所示。上图很容易造成了误解。
全连接成的输入
图出自: https://zhuanlan.zhihu.com/p/36455374
![](https://i-blog.csdnimg.cn/blog_migrate/357f5cbe8a5d82060f4d77567db87b3f.gif)
图出自: https://zhuanlan.zhihu.com/p/36455374
![](https://i-blog.csdnimg.cn/blog_migrate/a99a9f6be3f957e7250679f8a43d4c44.gif)
上图RNN展开的正确理解方式是这样的:
![](https://i-blog.csdnimg.cn/blog_migrate/7093b1c5cfabae473bd532d2f658b615.gif)
再理解几个概念:sequence length,input size, hidden unit
序列长度(sequence length)也可以理解为时间步(time step)比较好理解。比如一个语音输入,语音的长度就是序列长度。
input size表示一次输入的特征向量的大小。比如上面的全连接层神经网络,当batch_size为1是,输入的shape就是1x3。
x = tf.placeholder(tf.float32, shape=[None, 3])
hidden unit 指的就是有多少个LSTM cell或者GRU。
全连接神经网络的输入与RNN的输入比较:
知乎 隔壁小王 的回答:链接:https://www.zhihu.com/question/41949741/answer/342218083
例如这样一个数据集合,总共100条句子,每个句子20个词,每个词都由一个80维的向量表示。在lstm中,单个样本即单条句子输入下(shape是 [1 , 20, 80]),假如设定每一个time step的输入是一个词(当然这不一定,你也可以调成两个词或者更多个数的词),则在t0时刻是第一个时间步,输入x0则为代表一条句子(一个样本)中第1个词的80维向量,t1是第二个时间步,x1表示该句子中第2个词的80维向量,依次类推t19输入是最后一个词即第20个词的向量表示。常见的tf或者keras中lstm的参数(samples, timestep, input_dim),samples是指批量训练样本的数量, timestep是时间步(这个时间步可自己设置)比如上面说的20,input-dim是每个time step的输入shape。
知乎 撸猫的大王 的回答: https://www.zhihu.com/question/41949741/answer/232424403
假如数据集是(5000,28,128),其中5000指的是样本个数,(28,128)便是具体每个样本的行列数,28就是lstm中的时间步数;假如定义一个lstm层为 LSTM(output_dim= 256,activation=,input_shape= (28,128)),那么每个时间步输出的是一个元素个数为256的一阶向量,所有时间步集合起来就是(28,256)的二阶向量。至于模型是用所有时间步的输出,还是只用最后一个,就看具体怎么设计了。
知乎 EDU GUO 的回答:
实际应用中,我们通常使用的是Tensorflow中定义好的单元搭建RNN,或者直接使用keras。那么这两个框架中的输入形式是怎样?
使用LSTM单元静态搭建一个RNN
tf.contrib.rnn.static_rnn(cell, inputs, initial_state=None, dtype=None, sequence_length=None, scope=None):
关注参数inputs
inputs:A length T list of inputs, each a Tensor
of shape [batch_size, input_size]
, or a nested tuple of such elements.输入数据形状为[batch_size,input_size]
使用LSTM单元动态搭建一个RNN
tf.nn.dynamic_rnn(cell, inputs, sequence_length=None,
initial_state=None, dtype=None, parallel_iterations=None,
swap_memory=False, time_major=False, scope=None):
inputs:If time_major == False
(default), this must be a Tensor
of shape:[batch_size, max_time, depth]
, or a nested tuple of such elements. If time_major == True
, this must be a Tensor
of shape: [max_time, batch_size, depth]
, or a nested tuple of such elements. 输入数据,是一个张量,默认是三维张量,[batch_size, max_time, depth],batch_size 表示一个批次数量,max_time:表示时间序步总数,后面是一个时序输入数据的维度。
在默认情况下,time_major默认值是False,网络输出结果是[batch_size,max_time,depth]形式的张量。
这是一个批次优先的矩阵,当我们需要取最后一个时序的输出,需要转置成时间优先的形式。
outputs = tf.transpose(outputs,[1,0,2]
keras使用recurrent layers实现RNN
Input shape:
3D tensor with shape (batch_size, timesteps, input_dim).
这个输入的形式和Tensorflow动态搭建一个RNN的输入形式是一样的。