与Tensorflow中的常规LSTMCell相比,使用CudnnLSTM进行训练时的结果不同

Mik*_*laj 8 python tensorflow

我正在使用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对应物不同.

但是没有解释这些差异究竟是什么......

Szy*_*zke 3

它似乎tf.contrib.cudnn_rnn.CudnnLSTM是时间主要的,所以那些应该提供形状序列(seq_len, batch_size, embedding_size)而不是(batch_size, seq_len, embedding_size),所以你必须转置它(我认为,当涉及到混乱的 Tensorflow 文档时不能确定,但​​你可能想测试一下.如果您想检查,请参阅下面的链接)。

有关该主题的更多信息请参见此处(其中有另一个链接指向数学差异),但有一件事似乎是错误的:不仅 GRU 是时间主要的,LSTM 也是(如本期所指出的)。

我建议不要使用tf.contrib,因为它更混乱(最终将被排除在 Tensorflow 2.0 版本之外),并尽可能坚持使用(因为它将成为即将推出的Tensorflow 2.0keras的主要前端)或,因为它会成为 API 的一部分(尽管在我看来它的可读性要差得多)。tf.nntf.Estimator

...或者考虑使用 PyTorch 来省去麻烦,至少在文档中提供了输入形状(及其含义)。