我正在使用Tensorflow用Python训练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)
使用
lstm = tf.contrib.cudnn_rnn.CudnnLSTM(1, self.num_hidden)
rnn_outputs, _ = lstm(my_inputs)
我正在经历显着的训练速度提升(超过10倍),但与此同时,我的绩效指标却下降了。使用LSTMCell时,二进制分类的AUC为0.741,使用CudnnLSTM时的AUC为0.705。我想知道我是在做错什么,还是这两者之间在实现上的区别,就是在继续使用CudnnLSTM的情况下如何恢复性能的情况。
训练数据集包含15337个长度可变的序列(最多几百个元素),并在每个批次中填充零以使其长度相同。所有代码都相同,包括TF Dataset API管道和所有评估指标。我对每个版本运行了几次,在所有情况下,它们都围绕这些值收敛。
此外,我几乎没有可以插入完全相同的模型的数据集,问题仍然存在。
在tensorflow code for cudnn_rnn中,我发现了一个句子:
Cudnn LSTM和GRU在数学上不同于它们的tf 同行。
但是没有解释这些差异到底是什么...
答案 0 :(得分:1)
tf.contrib.cudnn_rnn.CudnnLSTM
似乎比较耗时,因此应该为它们提供形状为(seq_len, batch_size, embedding_size)
的序列,而不是(batch_size, seq_len, embedding_size)
,因此您必须对其进行转置(我认为,可以不确定涉及到混乱的Tensorflow文档时,但您可能需要对其进行测试。如果要检查,请参见下面的链接。
有关主题here的更多信息(还有另一个指向数学差异的链接),但有一件事情似乎是错误的:不仅GRU是主要时间,LSTM是(this issue指出)。
我建议使用tf.contrib
反对,因为它更加混乱(最终将在Tensorflow 2.0版本中被排除在外),并尽可能坚持使用keras
(因为它将成为即将发布的Tensorflow 2.0或tf.nn
的主要前端,因为它将成为tf.Estimator
API的一部分(尽管它的IMO可读性要差得多)。
...或考虑使用PyTorch来避免麻烦,在文档中至少会提供输入形状(及其含义)。