在RNN教程ptd_word_lm.py中。使用run_epoch训练RNN时,为什么需要评估self._initial_state?
$(document).foundation
初始状态定义如下,在训练期间永远不会改变。
def run_epoch(session, m, data, eval_op, verbose=False):
"""Runs the model on the given data."""
epoch_size = ((len(data) // m.batch_size) - 1) // m.num_steps
start_time = time.time()
costs = 0.0
iters = 0
state = m.initial_state.eval()
for step, (x, y) in enumerate(reader.ptb_iterator(data, m.batch_size,
m.num_steps)):
cost, state, _ = session.run([m.cost, m.final_state, eval_op],
{m.input_data: x,
m.targets: y,
m.initial_state: state})
costs += cost
iters += m.num_steps
if verbose and step % (epoch_size // 10) == 10:
print("%.3f perplexity: %.3f speed: %.0f wps" %
(step * 1.0 / epoch_size, np.exp(costs / iters),
iters * m.batch_size / (time.time() - start_time)))
return np.exp(costs / iters)
答案 0 :(得分:2)
在PTB示例中,句子被连接并分成批次(大小为batch_size x num_steps)。在每批之后,RNN的最后状态作为下一批的初始状态传递。这有效地允许您训练RNN,好像它是整个PTB语料库中的一个非常长的链(这解释了为什么评估model.final_state以及为什么状态被传递到feed_dict中的m.initial_state)。所以你看到initial_state实际的确实在每一步都发生了变化。
在一个纪元的最开始,我们没有先前的状态作为initial_state传递,因此使用全部为零,由state = m.initial_state.eval()表示。如果有另一个名为m.zero_state的属性被评估为获得此初始状态,那么可能会更容易混淆。例如,您可以使用适当大小的numpy数组,这也可以正常工作。 eval只是获得适当大小的张量或零的简便方法。
希望这是有道理的!