【问题标题】:Tensorflow: how to use RNN initial state in an estimator with different batch size for training and testing?Tensorflow:如何在具有不同批量大小的估计器中使用 RNN 初始状态进行训练和测试?
【发布时间】:2018-09-10 08:39:22
【问题描述】:

我正在使用 RNN (GRUCell) 开发 Tensorflow 估计器。 我使用 zero_state 来初始化第一个状态,它需要一个固定的大小。 我的问题是我希望能够使用估计器来预测单个样本(batchsize=1)。 当它加载序列化的估计器时,它抱怨我用于预测的批次大小与训练批次大小不匹配。

如果我用不同的批量大小重建估计器,我无法加载已序列化的内容。

有没有一种优雅的方式在估算器中使用 zero_state? 我看到一些解决方案使用变量来存储批量大小,但使用 feed_dict 方法。我不知道如何使它在估算器的上下文中工作。

这是我在估算器中简单测试 RNN 的核心:

cells = [  tf.nn.rnn_cell.GRUCell(self.getNSize()) for _ in range(self.getNLayers())]


multicell = tf.nn.rnn_cell.MultiRNNCell(cells, state_is_tuple=False)
H_init = tf.Variable( multicell.zero_state( batchsize, dtype=tf.float32 ), trainable=False)
H = tf.Variable( H_init )

Yr, state = tf.nn.dynamic_rnn(multicell, Xo, dtype=tf.float32, initial_state=H)

有人知道吗?

编辑:

好的,我在这个问题上尝试了各种方法。 我现在尝试过滤从检查点加载的变量以删除用作循环单元的内部状态的“H”。对于预测,我可以将其保留为所有 0 值。

到目前为止,我是这样做的: 首先我定义一个钩子:

class RestoreHook(tf.train.SessionRunHook):
    def __init__(self, init_fn):
        self.init_fn = init_fn

    def after_create_session(self, session, coord=None):
        print("--------------->After create session.")
        self.init_fn(session)

然后在我的model_fn中:

if mode == tf.estimator.ModeKeys.PREDICT:
        logits = tf.nn.softmax(logits)

        # Do not restore H as it's batch size might be different.
        vlist = tf.contrib.framework.get_variables_to_restore()
        vlist = [ x for x in vlist if x.name.split(':')[0] != 'architecture/H']
        init_fn = tf.contrib.framework.assign_from_checkpoint_fn(tf.train.latest_checkpoint(self.modelDir), vlist, ignore_missing_vars=True)
        spec = tf.estimator.EstimatorSpec(mode=mode,
                                          predictions = {
                                              'logits': logits,
                                          },
                                          export_outputs={
                                              'prediction': tf.estimator.export.PredictOutput( logits )
                                          },
                                          prediction_hooks=[RestoreHook(init_fn)])

我从https://github.com/tensorflow/tensorflow/issues/14713获取了这段代码

但它还没有工作。似乎它仍在尝试从文件中加载 H ...我检查它是否不在 vlist 中。 我仍在寻找解决方案。

【问题讨论】:

    标签: python tensorflow rnn


    【解决方案1】:

    您可以从其他张量example获取批量大小

    decoder_initial_state = cell.zero_state(array_ops.shape(attention_states)[0], dtypes.float32).clone(cell_state=encoder_state)

    【讨论】:

    • 感谢您的回答。它不能解决问题,因为在训练和预测时批次的大小会有所不同。因此,RNN 内部状态的大小将被序列化为给定大小,然后在重新加载时会发生大小不匹配。这就是为什么我在重新加载检查点时尝试过滤掉这个“H”变量的原因。它将根据输入批量大小使用 zero_state 进行初始化,并且不会被检查点加载覆盖。
    • 我使用不同的批量大小进行训练、评估和推断,在加载检查点时无需显式删除批量大小即可正常工作。顺便说一句,我使用 TensorFlow 1.11.0-rc0,您可以使用 tf-nightly 或 tf- nightly-gpu 获取该版本
    • 如何初始化initial_state参数?
    • 切换到 1.11 并没有改变任何东西。初始状态以给定的大小(取决于批量大小)保存,并在加载时期望相同​​的大小。我使整个网络依赖于批量大小。很烦人。有人找到解决方案了吗?
    • 看看这个:machinelearningmastery.com/…。就像你在使用 tensorflow 时需要有不同的图表用于训练、评估、测试,请看这里:github.com/tensorflow/…
    【解决方案2】:

    我找到了解决办法:

    • 我为 batchsize=64 和 batchsize=1 的初始状态创建变量。
    • 在训练时,我使用第一个初始化 RNN。
    • 在预测时,我使用第二个。

    因为这两个变量都将被估算器代码序列化和恢复,所以它不会抱怨。 缺点是查询批量大小(在我的例子中为 1)在训练时(当它创建两个变量时)是已知的。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-03-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-30
      • 1970-01-01
      • 2018-09-27
      • 1970-01-01
      相关资源
      最近更新 更多