【问题标题】:TensorFlow: initializing state for RNN between inferences in AndroidTensorFlow:在 Android 中的推理之间为 RNN 初始化状态
【发布时间】:2017-04-01 17:28:04
【问题描述】:

我们有一个在 Android 上运行的 TensorFlow 网络 (graphdef),我注意到随着时间的推移,推理结果往往是相关的。也就是说,如果返回标签 A,即使输入数据切换到应该生成 B 标签的数据,也会有一个 A 的流及时跟随。最终,结果将切换到 B,但似乎存在滞后,这表明 RNN 在推理调用之间是有状态的。我们的网络正在使用 RNN/LSTM。

cellLSTM    = tf.nn.rnn_cell.BasicLSTMCell(nHidden)
cellsLSTM   = tf.nn.rnn_cell.MultiRNNCell([cellLSTM] * 2)
RNNout, RNNstates = tf.nn.rnn(cellsLSTM, Xin)

我想知道是否需要在推理调用之间重新初始化 RNN 状态。我会注意到 TensorFlowInferenceInterface.java 接口中没有这样的方法可用。我想可以将一个 RNN 单元初始化节点插入到可以用节点值激活的图中(使用 FillNodeInt 或类似方法)。

所以我的问题是:在 Tensorflow 中使用 RNN/LSTM 的最佳实践是什么。是否需要在推论之间清除状态?如果是这样,如何做到这一点?

【问题讨论】:

    标签: java android tensorflow lstm


    【解决方案1】:

    是否需要在推理之间清除状态?

    我认为这取决于如何训练 RNN 以及您如何使用它。但是,我猜想无论是否重置状态,网络都会很好地工作。

    如何做到这一点?

    评估与初始状态相关的每个张量的初始化操作。

    【讨论】:

    • 相反,RNN 可以随着时间的推移将状态带向前进。如果未初始化并且使用训练会话中的随机帧序列进行训练,则它们在真实数据中的可预测性往往较低。因此,确保它以零状态开始每一帧非常重要。我在 TF 问题板上看到了一些评论,新的 dynamic_rnn 实现会在每一帧自动将其状态初始化为零。但是,就我而言,我看到了异常情况,并希望保证初始化作为图表的一部分。
    【解决方案2】:

    虽然我无法评论 RNN 状态初始化的一般做法,但这里是我们如何设法强制初始状态定义。问题是,虽然批量大小确实是训练集的常数参数,但它不是测试集。测试集始终是数据语料库的 20%,因此它的大小随着语料库的每次变化而不同。
    解决方案是为批量大小创建一个新变量:

    batch_size_T  = tf.shape(Xin)[0]
    

    其中Xin 是大小为 [b x m x n] 的输入张量,其中 b 是批量大小,m x n 是训练帧的大小。辛是从feed_dict送进来的。

    然后可以将初始状态定义为:

    initial_state = lstm_cells.zero_state(batch_size_T, tf.float32) 
    

    最后,RNN 是根据新的 Dynamic RNN 定义的:

    outputs, state = tf.nn.dynamic_rnn(cell=lstm_cells, inputs=Xin, dtype=tf.float32, initial_state=initial_state)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-12
      • 2019-05-05
      • 2018-03-05
      • 1970-01-01
      • 2019-05-08
      • 1970-01-01
      相关资源
      最近更新 更多