截至目前,TensorFlow的RNN APIs还处于Draft阶段。不过据官方解释,RNN的相关API已经出现在Tutorials里了,大幅度的改动应该是不大可能,现在入手TF的RNN APIs风险应该是不大的。
目前TF的RNN APIs主要集中在tensorflow.models.rnn中的rnn和rnn_cell两个模块。其中,后者定义了一些常用的RNN cells,包括RNN和优化的LSTM、GRU等等;前者则提供了一些helper方法。
创建一个基础的RNN很简单:
1 |
from tensorflow.models.rnn import rnn_cell |
2 |
cell = rnn_cell.BasicRNNCell(inputs, state) |
创建一个LSTM或者GRU的cell?
1 |
cell = rnn_cell.BasicLSTMCell(num_units) #最最基础的,不带peephole。 |
2 |
cell = rnn_cell.LSTMCell(num_units, input_size) #可以设置peephole等属性。 |
3 |
cell = rnn_cell.GRUCell(num_units) |
调用呢?
1 |
output, state = cell( input , state) |
这样自己按timestep调用需要设置variable_scope的reuse属性为True,懒人怎么做,TF也给想好了:
1 |
state = cell.zero_state(batch_size, dtype = tf.float32) |
2 |
outputs, states = rnn.rnn(cell, inputs, initial_state = state) |
再懒一点:
1 |
outputs, states = rnn.rnn(cell, inputs, dtype = tf.float32) |
怕overfit,加个Dropout如何?
1 |
cell = rnn_cell.DropoutWrapper(cell, input_keep_prob = 0.5 , output_keep_prob = 0.5 ) |
做个三层的带Dropout的网络?
1 |
cell = rnn_cell.DropoutWrapper(cell, output_keep_prob = 0.5 ) |
2 |
cell = rnn_cell.MultiRNNCell([cell] * 3 ) |
3 |
inputs = tf.nn.dropout(inputs, 0.5 ) #给第一层单独加个Dropout。 |
一个坑——用rnn.rnn要按照timestep来转换一下输入数据,比如像这样:
1 |
inputs = [tf.reshape(t, (input_dim[ 0 ], 1 )) for t in tf.split( 1 , input_dim[ 1 ], inputs)] |
rnn.rnn()的输出也是对应每一个timestep的,如果只关心最后一步的输出,取outputs[-1]即可。
注意一下子返回值的dimension和对应关系,损失函数和其它情况没有大的区别。
目前饱受诟病的是TF本身还不支持Theano中scan()那样可以轻松实现的不定长输入的RNN,不过有人反馈说Theano中不定长训练起来还不如提前给inputs加个padding改成定长的训练快。
本文转自博客园知识天地的博客,原文链接:TensorFlow框架下的RNN实践小结,如需转载请自行联系原博主。