如何创建具有动态“zero_state”的dynamic_rnn(推理失败)

2024-02-10

我一直在使用“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“状态”与新的 Xinputs 形状不匹配。所以我想我需要根据输入批量大小制作“self.BatchSize”,而不是对其进行硬编码。我尝试了很多不同的方法,但没有一个有效。我宁愿不通过 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]”,它返回张量的“形状”并采用[0]处的batch_size值。文档似乎不太清楚,但这似乎是一个常量值,因此当您将图加载到推理中时,该值仍然是硬编码的(可能仅在图创建时评估?)。

使用“tf.shape()”函数,似乎可以解决问题。这不会返回形状,而是返回张量。所以这似乎在运行时更新得更多。使用此代码片段解决了 128 个批次的训练问题,然后将图加载到仅处理 1 个批次的 TensorFlow-Service 推理中。

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)

这是 TensorFlow FAQ 的一个很好的链接,它描述了这种方法'如何构建适用于可变批量大小的图表?': https://www.tensorflow.org/resources/faq https://www.tensorflow.org/resources/faq

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何创建具有动态“zero_state”的dynamic_rnn(推理失败) 的相关文章

随机推荐