我正在使用Python中的Tensorflow培训LSTM网络,并希望切换到tf.contrib.cudnn_rnn.CudnnLSTM以加快培训速度.我做了什么被替换了
cells = tf.nn.rnn_cell.LSTMCell(self.num_hidden)
initial_state = cells.zero_state(self.batch_size, tf.float32)
rnn_outputs, _ = tf.nn.dynamic_rnn(cells, my_inputs, initial_state = initial_state)
Run Code Online (Sandbox Code Playgroud)
同
lstm = tf.contrib.cudnn_rnn.CudnnLSTM(1, self.num_hidden)
rnn_outputs, _ = lstm(my_inputs)
Run Code Online (Sandbox Code Playgroud)
我正在经历显着的训练加速(超过10倍),但同时我的性能指标也下降了.使用LSTMCell时二元分类的AUC为0.741,使用CudnnLSTM时为0.705.我想知道我是做错了什么,或者这两者之间的实现有何不同,这就是如何在继续使用CudnnLSTM的同时恢复性能的情况.
训练数据集具有15,337个不同长度的序列(最多几百个元素),在每个批次中用零填充为相同的长度.所有代码都相同,包括TF数据集API管道和所有评估指标.我运行了几次每个版本,并且在所有情况下都会收敛这些值.
此外,我有几个数据集可以插入完全相同的模型,并且问题仍然存在于所有这些数据集中.
在cudnn_rnn的tensorflow代码中,我发现了一句话:
Cudnn LSTM和GRU在数学上与它们的tf对应物不同.
但是没有解释这些差异究竟是什么......
我将以下代码用于标准GRU实施:
def BiRNN_deep_dynamic_FAST_FULL_autolength(x,batch_size,dropout,hidden_dim):
seq_len=length_rnn(x)
with tf.variable_scope('forward'):
lstm_cell_fwd =tf.contrib.rnn.GRUCell(hidden_dim,kernel_initializer=tf.contrib.layers.xavier_initializer(),bias_initializer=tf.contrib.layers.xavier_initializer())
lstm_cell_fwd = tf.contrib.rnn.DropoutWrapper(lstm_cell_fwd, output_keep_prob=dropout)
with tf.variable_scope('backward'):
lstm_cell_back =tf.contrib.rnn.GRUCell(hidden_dim,kernel_initializer=tf.contrib.layers.xavier_initializer(),bias_initializer=tf.contrib.layers.xavier_initializer())
lstm_cell_back = tf.contrib.rnn.DropoutWrapper(lstm_cell_back, output_keep_prob=dropout)
outputs,_= tf.nn.bidirectional_dynamic_rnn(cell_fw=lstm_cell_fwd,cell_bw= lstm_cell_back,inputs=x,sequence_length=seq_len,dtype=tf.float32,time_major=False)
outputs_fwd,outputs_bck=outputs
### fwd matrix is the matrix that keeps all the last [-1] vectors
fwd_matrix=tf.gather_nd(outputs_fwd, tf.stack([tf.range(batch_size), seq_len-1], axis=1)) ### 99,64
outputs_fwd=tf.transpose(outputs_fwd,[1,0,2])
outputs_bck=tf.transpose(outputs_bck,[1,0,2])
return outputs_fwd,outputs_bck,fwd_matrix
Run Code Online (Sandbox Code Playgroud)
谁能提供一个简单的示例来说明如何以类似方式使用tf.contrib.cudnn_rnn.CudnnGRU Cell?只是换出单元格是行不通的。
第一个问题是CuDnnGRU单元没有任何丢弃包装,这很好。其次,它似乎不适用于tf.nn.bidirectional_dynamic_rnn。任何帮助表示赞赏。