如何使用动态 "zero_state" 创建 dynamic_rnn (推理失败)

How do you create a dynamic_rnn with dynamic "zero_state" (Fails with Inference)

我一直在与 "dynamic_rnn" 合作创建模型。

该模型基于 80 个时间周期的信号,我想在每个 运行 之前将 "initial_state" 归零,因此我设置了以下代码片段来完成此操作:

state = cell_L1.zero_state(self.BatchSize,Xinputs.dtype)
outputs, outState = rnn.dynamic_rnn(cell_L1,Xinputs,initial_state=state,  dtype=tf.float32)

这对训练过程很有用。问题是一旦我进行推理,我的 BatchSize = 1,我就会收到错误消息,因为 rnn "state" 与新的 Xinputs 形状不匹配。所以我想我需要根据输入的批量大小来制作 "self.BatchSize" 而不是硬编码。我尝试了很多不同的方法,其中 none 行得通。我宁愿不通过 feed_dict 传递一堆零,因为它是一个基于批量大小的常数。

以下是我的一些尝试。它们通常都会失败,因为在构建图形时输入大小未知:

state = cell_L1.zero_state(Xinputs.get_shape()[0],Xinputs.dtype)

.....

state = tf.zeros([Xinputs.get_shape()[0], self.state_size], Xinputs.dtype, name="RnnInitializer")

另一种方法,认为初始化程序可能要到 运行 时间才会被调用,但在图形构建时仍然失败:

init = lambda shape, dtype: np.zeros(*shape)
state = tf.get_variable("state", shape=[Xinputs.get_shape()[0], self.state_size],initializer=init)

有没有办法动态创建这个恒定的初始状态,或者我是否需要通过 feed_dict 使用张量服务代码重置它?有没有一种聪明的方法可以在图表中只执行一次 tf.Variable.assign?

问题的解决方案是如何获取 "batch_size" 这样变量就不会被硬编码。

这是给定示例中的正确方法:

Xinputs = tf.placeholder(tf.int32, (None, self.sequence_size, self.num_params), name="input")
state = cell_L1.zero_state(Xinputs.get_shape()[0],Xinputs.dtype)

问题是"get_shape()[0]"的使用,这个return是张量的"shape",取[0]处的batch_size值。文档似乎不是那么清楚,但这似乎是一个常量值,因此当您将图形加载到推理中时,该值仍然是硬编码的(可能只在图形创建时评估?)。

使用 "tf.shape()" 函数,似乎可以解决问题。这不是 return 形状,而是张量。所以这似乎在 run-time 更新了更多。使用此代码片段解决了训练批次为 128 的问题,然后将图形加载到 TensorFlow-Service 推理处理批次仅为 1.

Xinputs = tf.placeholder(tf.int32, (None, self.sequence_size, self.num_params), name="input")
batch_size = tf.shape(Xinputs)[0]
state = self.cell_L1.zero_state(batch_size,Xinputs.dtype)

这里有一个很好的 link TensorFlow 常见问题解答,其中描述了这种方法“如何构建适用于可变批量大小的图形?”: https://www.tensorflow.org/resources/faq