如何在 TensorFlow RNN 中检索中间状态
How to retrieve intermediary state in TensorFlow RNN
我是 运行 固定大小段信号上的 RNN。下面的代码允许我保留前一批的最终状态来初始化下一批的初始状态。
rnn_outputs, final_state = tf.contrib.rnn.static_rnn(cell, rnn_inputs, initial_state=init_state)
这在批次不重叠时有效。比如我的第一批处理样本0:124,final_state
就是这个处理后的状态。然后,下一批处理样本 124:256,将 init_state
设置为 final_state
。
我的问题是当批次重叠时如何检索中间状态。首先,我处理样本 0:124,然后处理 10:134,20:144,因此跳数为 10。我想检索的不是 final_state
,而是处理 10 个样本后的状态.
TF中是否可以保持中介状态? documentation 表明 return 值仅包含最终状态。
该图显示了我因状态不连续而面临的问题。在我的程序中,RNN段长为215,跳长为20。
更新:最简单的竟然是所描述的:
rnn_outputs_one, mid_state = tf.contrib.rnn.static_rnn(cell, rnn_inputs_one, initial_state=rnn_tuple_state)
rnn_outputs_two, final_state = tf.contrib.rnn.static_rnn(cell, rnn_inputs_two, initial_state=mid_state)
rnn_outputs = rnn_outputs_one + rnn_outputs_two
和
prev_state = sess.run(mid_state)
现在,经过几次迭代,结果看起来好多了。
在 tensorflow 中,从对 sess.run
的调用返回后唯一保留的是变量。您应该为状态创建一个变量,然后使用 tf.assign
将 RNN 单元格的结果分配给该变量。然后,您可以像使用任何其他张量一样使用该变量。
如果您需要将变量初始化为 0
以外的值,您可以使用占位符调用 sess.run
一次,然后 tf.assign
专门用于设置变量。
添加的详细信息:
如果您需要一个中间状态,假设您 运行 的时间步 0:124 并且您想要第 10 步,您应该将其分成 2 个 RNN 单元,一个处理前 10 个时间步第二个继续处理接下来的 114 个时间步。只要您在两个 static_rnn
函数中使用相同的单元格(LSTM 或其他单元格),这就不会影响训练和反向传播。单元格是定义权重的地方,并且必须保持不变。您的渐变将反向流过第二个单元格,然后最后适当地流过第一个单元格。
所以,我早些时候来这里寻找答案,但我最终创造了一个。
类似于上面关于使其可分配的海报...
构建图形时,列出序列占位符,例如...
my_states = [None] * int(sequence_length + 1)
my_states[0] = cell.zero_state()
for step in steps:
cell_out, my_states[step+1] = cell( )
然后在 sess.run() 之后你的图表之外你说
new_states = my_states[1:]
model.my_states = new_states
这种情况是一次步进 1 个时间步,但可以很容易地步进 10 个时间步。只需在 sess.run() 之后切分状态列表并将它们作为初始状态。
祝你好运!
我是 运行 固定大小段信号上的 RNN。下面的代码允许我保留前一批的最终状态来初始化下一批的初始状态。
rnn_outputs, final_state = tf.contrib.rnn.static_rnn(cell, rnn_inputs, initial_state=init_state)
这在批次不重叠时有效。比如我的第一批处理样本0:124,final_state
就是这个处理后的状态。然后,下一批处理样本 124:256,将 init_state
设置为 final_state
。
我的问题是当批次重叠时如何检索中间状态。首先,我处理样本 0:124,然后处理 10:134,20:144,因此跳数为 10。我想检索的不是 final_state
,而是处理 10 个样本后的状态.
TF中是否可以保持中介状态? documentation 表明 return 值仅包含最终状态。
该图显示了我因状态不连续而面临的问题。在我的程序中,RNN段长为215,跳长为20。
更新:最简单的竟然是
rnn_outputs_one, mid_state = tf.contrib.rnn.static_rnn(cell, rnn_inputs_one, initial_state=rnn_tuple_state)
rnn_outputs_two, final_state = tf.contrib.rnn.static_rnn(cell, rnn_inputs_two, initial_state=mid_state)
rnn_outputs = rnn_outputs_one + rnn_outputs_two
和
prev_state = sess.run(mid_state)
现在,经过几次迭代,结果看起来好多了。
在 tensorflow 中,从对 sess.run
的调用返回后唯一保留的是变量。您应该为状态创建一个变量,然后使用 tf.assign
将 RNN 单元格的结果分配给该变量。然后,您可以像使用任何其他张量一样使用该变量。
如果您需要将变量初始化为 0
以外的值,您可以使用占位符调用 sess.run
一次,然后 tf.assign
专门用于设置变量。
添加的详细信息:
如果您需要一个中间状态,假设您 运行 的时间步 0:124 并且您想要第 10 步,您应该将其分成 2 个 RNN 单元,一个处理前 10 个时间步第二个继续处理接下来的 114 个时间步。只要您在两个 static_rnn
函数中使用相同的单元格(LSTM 或其他单元格),这就不会影响训练和反向传播。单元格是定义权重的地方,并且必须保持不变。您的渐变将反向流过第二个单元格,然后最后适当地流过第一个单元格。
所以,我早些时候来这里寻找答案,但我最终创造了一个。
类似于上面关于使其可分配的海报...
构建图形时,列出序列占位符,例如...
my_states = [None] * int(sequence_length + 1)
my_states[0] = cell.zero_state()
for step in steps:
cell_out, my_states[step+1] = cell( )
然后在 sess.run() 之后你的图表之外你说
new_states = my_states[1:]
model.my_states = new_states
这种情况是一次步进 1 个时间步,但可以很容易地步进 10 个时间步。只需在 sess.run() 之后切分状态列表并将它们作为初始状态。
祝你好运!