【问题标题】:Tensorflow RNN sequence trainingTensorFlow RNN 序列训练
【发布时间】:2016-10-08 15:18:34
【问题描述】:

我正在迈出学习 TF 的第一步,但在训练 RNN 时遇到了一些麻烦。

我的玩具问题是这样的:两层 LSTM + 密集层网络被输入原始音频数据,并且应该测试声音中是否存在特定频率。

所以网络应该 1 对 1 映射浮点数(音频数据序列)到浮点数(预先选择的频率音量)

我已经在 Keras 上完成了这项工作,并看到了一个类似的 TFLearn 解决方案,但我希望以一种相对有效的方式在裸 Tensorflow 上实现它。

我做了什么:

lstm = rnn_cell.BasicLSTMCell(LSTM_SIZE,state_is_tuple=True,forget_bias=1.0)
lstm = rnn_cell.DropoutWrapper(lstm)
stacked_lstm = rnn_cell.MultiRNNCell([lstm] * 2,state_is_tuple=True)
outputs, states = rnn.dynamic_rnn(stacked_lstm, in, dtype=tf.float32)
outputs = tf.transpose(outputs, [1, 0, 2])
last = tf.gather(outputs, int(outputs.get_shape()[0]) - 1)
network= tf.matmul(last, W) + b

# cost function, optimizer etc...

在训练期间,我用 (BATCH_SIZE, SEQUENCE_LEN,1) 批次喂它,看起来损失收敛正确,但我不知道如何用训练过的网络进行预测。

我的(很多)问题: 我如何让这个网络直接从 Tensorflow 返回一个序列,而无需为每个样本返回 python(输入一个序列并预测一个相同大小的序列)?

如果我确实想一次预测一个样本并在 python 中进行迭代,那么正确的方法是什么?

在测试期间需要 dynamic_rnn 还是仅用于在训练期间展开 BPTT?为什么 dynamic_rnn 返回所有反向传播步骤张量?这些是展开网络的每一层的输出,对吧?

【问题讨论】:

    标签: tensorflow


    【解决方案1】:

    经过一番研究:

    我如何让这个网络直接从 Tensorflow 返回一个序列 无需为每个样本返回 python(提供一个序列和 预测一个相同大小的序列)?

    你可以使用 state_saving_rnn

    class Saver():
    def __init__(self):
        self.d = {}
    def state(self, name):
        if not name in self.d:
            return tf.zeros([1,LSTM_SIZE],tf.float32)
        return self.d[name]
    def save_state(self, name, val):
        self.d[name] = val
        return tf.identity('save_state_name') #<-important for control_dependencies
    
    outputs, states = rnn.state_saving_rnn(stacked_lstm, inx, Saver(),
                                           ('lstmstate', 'lstmstate2', 'lstmstate3', 'lstmstate4'),sequence_length=[EVAL_SEQ_LEN])
    #4 states are for two layers of lstm each has hidden and CEC variables to restore
    network = [tf.matmul(outputs[-1], W) for i in xrange(EVAL_SEQ_LEN)]
    

    一个问题是 state_saving_rnn 使用的是 rnn() 而不是 dynamic_rnn() 因此在编译时展开 EVAL_SEQ_LEN 步骤,如果你想输入长序列,你可能想用 dynamic_rnn 重新实现 state_saving_rnn

    如果我确实想一次预测一个样本并在 python 中进行迭代,那么正确的方法是什么?

    您可以使用 dynamic_rnn 并提供 initial_state。这可能与 state_saving_rnn 一样有效。查看 state_saving_rnn 实现以供参考

    在测试期间需要 dynamic_rnn 还是仅用于在训练期间展开 BPTT?为什么 dynamic_rnn 返回所有反向传播步骤张量?这些是展开网络的每一层的输出,对吧?

    dynamic_rnn 确实在运行时进行展开,类似于编译时 rnn()。我想它会返回所有步骤,让您在其他一些地方分支图表 - 在更少的时间步骤之后。在使用 [one time step input * current state -> one output, new state] 的网络中,就像上面描述的那样,它在测试中不需要,但可以用于训练截断时间反向传播

    【讨论】: