- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我想保存我的 LSTM 的最终状态,以便在我恢复模型时包含它并可用于预测。如下所述,当我使用 tf.assign
时,Saver 只知道最终状态。但是,这会引发错误(也在下面解释)。
在训练期间,我总是将最终的 LSTM 状态反馈回网络,如 this post 中所述。 .以下是代码的重要部分:
构建图表时:
self.init_state = tf.placeholder(tf.float32, [
self.n_layers, 2, self.batch_size, self.n_hidden
])
state_per_layer_list = tf.unstack(self.init_state, axis=0)
rnn_tuple_state = tuple([
tf.contrib.rnn.LSTMStateTuple(state_per_layer_list[idx][0],
state_per_layer_list[idx][1])
for idx in range(self.n_layers)
])
outputs, self.final_state = tf.nn.dynamic_rnn(
cell, inputs=self.inputs, initial_state=rnn_tuple_state)
在训练期间:
_current_state = np.zeros((self.n_layers, 2, self.batch_size,
self.n_hidden))
_train_step, _current_state, _loss, _acc, summary = self.sess.run(
[
self.train_step, self.final_state,
self.merged
],
feed_dict={self.inputs: _inputs,
self.labels:_labels,
self.init_state: _current_state})
当我稍后从检查点恢复我的模型时,最终状态也没有恢复。如 this post 中所述问题是 Saver 不知道新状态。该帖子还提出了一个基于 tf.assign
的解决方案。遗憾的是,我不能使用建议的
assign_op = tf.assign(self.init_state, _current_state)
self.sess.run(assign_op)
因为 self.init state 不是一个变量而是一个占位符。我得到错误
AttributeError: 'Tensor' 对象没有属性 'assign'
我已经尝试解决这个问题几个小时了,但我无法让它工作。
感谢任何帮助!
编辑:
我已将 self.init_state 更改为
self.init_state = tf.get_variable('saved_state', shape=
[self.n_layers, 2, self.batch_size, self.n_hidden])
state_per_layer_list = tf.unstack(self.init_state, axis=0)
rnn_tuple_state = tuple([
tf.contrib.rnn.LSTMStateTuple(state_per_layer_list[idx][0],
state_per_layer_list[idx][1])
for idx in range(self.n_layers)
])
outputs, self.final_state = tf.nn.dynamic_rnn(
cell, inputs=self.inputs, initial_state=rnn_tuple_state)
并且在训练期间我没有为 self.init_state 提供值:
_train_step, _current_state, _loss, _acc, summary = self.sess.run(
[
self.train_step, self.final_state,
self.merged
],
feed_dict={self.inputs: _inputs,
self.labels:_labels})
但是,我仍然无法运行赋值操作。知道我得到
TypeError: 预期的 float32 传递给 op 'Assign' 的参数 'value',得到 (LSTMStateTuple(c=array([[ 0.07291573, -0.06366599, -0.23425588, ..., 0.05307654,
最佳答案
为了保存最终状态,您可以创建一个单独的 TF 变量,然后在保存图形之前,运行一个 assign
op 将您的最新状态分配给该变量,然后保存图形.您唯一需要记住的是在声明 Saver
之前声明该变量;否则它不会包含在图中。
此处对此进行了非常详细的讨论,包括工作代码: TF LSTM: Save State from training session for prediction session later
*** 更新:后续问题的答案:
看起来您正在使用 BasicLSTMCell
,state_is_tuple=True
。我向您推荐的先前讨论使用了 GRUCell
和 state_is_tuple=False
。两者之间的细节有些不同,但总体方法可能相似,因此希望这对您有用:
在训练期间,您首先将零作为 initial_state
馈送到 dynamic_rnn
中,然后继续将其自己的输出作为 initial_state
的输入重新馈送回来。因此,我们的 dynamic_rnn
调用的最后输出状态就是您要保存以备后用的内容。由于它是 sess.run()
调用的结果,因此本质上它是一个 numpy 数组(不是张量也不是占位符)。因此,问题相当于“如何将 numpy 数组与图中的其余变量一起保存为 Tensorflow 变量”。这就是为什么您将最终状态分配给一个变量,而该变量的唯一目的就是这个。
所以,代码是这样的:
# GRAPH DEFINITIONS:
state_in = tf.placeholder(tf.float32, [LAYERS, 2, None, CELL_SIZE], name='state_in')
l = tf.unstack(state_in, axis=0)
state_tup = tuple(
[tf.nn.rnn_cell.LSTMStateTuple(l[idx][0], l[idx][1])
for idx in range(NLAYERS)])
#multicell = your BasicLSTMCell / MultiRNN definitions
output, state_out = tf.nn.dynamic_rnn(multicell, X, dtype=tf.float32, initial_state=state_tup)
savedState = tf.get_variable('savedState', shape=[LAYERS, 2, BATCHSIZE, CELL_SIZE])
saver = tf.train.Saver(max_to_keep=1)
in_state = np.zeros((LAYERS, 2, BATCHSIZE, CELL_SIZE))
# TRAINING LOOP:
feed_dict = {X: x, Y_: y_, batchsize: BATCHSIZE, state_in:in_state}
_, out_state = sess.run([training_step, state_out], feed_dict=feed_dict)
in_state = out_state
# ONCE TRAINING IS OVER:
assignOp = tf.assign(savedState, out_state)
sess.run(assignOp)
saver.save(sess, pathModel + '/my_model.ckpt')
# RECOVERING IN A DIFFERENT PROGRAM:
gInit = tf.global_variables_initializer().run()
lInit = tf.local_variables_initializer().run()
new_saver = tf.train.import_meta_graph(pathModel + 'my_model.ckpt.meta')
new_saver.restore(sess, pathModel + 'my_model.ckpt')
# retrieve State and get its LAST batch (latest obervarions)
savedState = sess.run('savedState:0') # this is FULL state from training
state = savedState[:,:,-1,:] # -1 gets only the LAST batch of the state (latest seen observations)
state = np.reshape(state, [state.shape[0], 2, -1, state.shape[2]]) #[LAYERS, 2, 1 (BATCH), SELL_SIZE]
#x = .... (YOUR INPUTS)
feed_dict = {'X:0': x, 'state_in:0':state}
#PREDICTION LOOP:
preds, state = sess.run(['preds:0', 'state_out:0'], feed_dict = feed_dict)
# so now state will be re-fed into feed_dict with the next loop iteration
如前所述,这是一种修改后的方法,适用于 GRUCell
,其中 state_is_tuple = False
。我对其进行了调整,以尝试使用 state_is_tuple=True
的 BasicLSTMCell
。它有效,但不如原来的方法准确。我还不知道是因为对我来说 GRU 比 LSTM 更好还是出于其他原因。看看这是否适合您...
另外请记住,正如您在恢复和预测代码中看到的那样,您的预测可能基于与训练循环不同的批处理大小(我猜是 1 个批处理?)所以您必须仔细考虑如何处理你的恢复状态——只拿最后一批?或者是其他东西?此代码仅采用已保存状态的最后一层(即训练中的最新观察结果),因为这与我相关...
关于python - Tensorflow 将 LSTM 的最终状态保存在 dynamic_rnn 中用于预测,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45209227/
我是一名优秀的程序员,十分优秀!