TensorFlow框架下的RNN實踐小結

weixin_34321977發表於2017-11-21

截至目前,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 in tf.split(1, input_dim[1], inputs)]

rnn.rnn()的輸出也是對應每一個timestep的,如果只關心最後一步的輸出,取outputs[-1]即可。

注意一下子返回值的dimension和對應關係,損失函式和其它情況沒有大的區別。

目前飽受詬病的是TF本身還不支援Theano中scan()那樣可以輕鬆實現的不定長輸入的RNN,不過有人反饋說Theano中不定長訓練起來還不如提前給inputs加個padding改成定長的訓練快。

相關文章