RNN中不用写循环,快速实现时间步的方法及理解
本博文参考以下文章,重点记录下自己的一些想法和理解:
下面是一段定义标准RNN cell的代码:
@requires_authorization
import tensorflow as tf
import numpy as np
cell = tf.nn.rnn_cell.BasicRNNCell(num_units=128) # state_size = 128
print(cell.state_size) # 128
inputs = tf.placeholder(np.float32, shape=(32, 100)) # 32 是 batch_size
h0 = cell.zero_state(32, np.float32) # 通过zero_state得到一个全0的初始状态,形状为(batch_size, state_size)
output, h1 = cell.call(inputs, h0) #调用call函数
print(h1.shape) # (32, 128)
当我们要写一个多时间步的RNN时,若采用上面的cell,则需要自己写循环,先创建一个静态的RNN cell,再在循环中按照时间步调用,会比较低效。
于是,我们可以用下面的代码块来实现多个时间步的RNN模型:
@requires_authorization
# inputs: shape = (batch_size, time_steps, input_size)
# cell: RNNCell
# initial_state: shape = (batch_size, cell.state_size)。初始状态。一般可以取零矩阵
outputs, state = tf.nn.dynamic_rnn(cell, inputs, initial_state=initial_state)
上面的dynamic方法是动态的来创建RNN模型,相比前面口述的场景要来的高效许多。
一点想法
注意到第二段code里面在初始化参数的时候,参数初始化的size是batchsize乘以隐变量维度,
@requires_authorization
# initial_state: shape = (batch_size, cell.state_size)。初始状态。一般可以取零矩阵
我们知道初始化一次过后,每次会将新的参数更新值看作上一次初始化的结果。可能有人会问,为什么要对同一个隐状态初始化batchsize这么多次呢?不能第二次用前一次的更新值吗?
一开始,我也会这样疑问自己,可是仔细看,batchsize是在一次迭代中用到的样本数,而对于各个样本,我们可以将RNN模型看作是并行的关系,即在一次迭代,各个样本共用同一个model,但是各个model的初始化可以不一样。这就是和为什么要初始化batchsize个隐状态的原因啦!