我一直在使用" 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"基于输入批量大小而不是硬代码。我尝试了许多不同的方法,但没有一种方法有效。我宁愿不通过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吗?
答案 0 :(得分:3)
该问题的解决方案是如何获取“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]”,这将返回张量的“形状”并将batch_size值取为[0]。文档似乎不那么清楚,但这似乎是一个常量值,所以当你将图形加载到推理中时,这个值仍然是硬编码的(可能只在图形创建时评估?)。
使用“tf.shape()”函数,似乎可以解决问题。这不会返回形状,而是张量。所以这似乎在运行时更新。使用此代码片段解决了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)
以下是TensorFlow常见问题解答的一个很好的链接,它描述了这种方法'如何构建适用于可变批量大小的图表?': https://www.tensorflow.org/resources/faq