2016-07-19 8 views
1

In der RNN-Tutorial ptd_word_lm.py. Warum ist es beim Training der RNN mit run_epoch notwendig, self._initial_state auszuwerten?Warum evaluieren Sie self._initial_state beim Training von RNN in Tensorflow

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) 

Der Anfangszustand ist wie folgt definiert und wird während des Trainings nicht geändert.

self._initial_state = cell.zero_state(batch_size, tf.float32) 

Antwort

2

In der PTB Beispiel sind die Sätze verketteten und spaltete sich in Chargen (von batch_size x num_steps Größe). Nach jedem Batch wird der letzte Zustand des RNN als Anfangszustand des nächsten Stapels übergeben. Dies ermöglicht es Ihnen effektiv, die RNN so zu trainieren, als wäre sie eine sehr lange Kette über den gesamten PTB-Korpus (und dies erklärt, warum model.final_state ausgewertet wird und warum der Zustand in m.initial_state im feed_dict übergeben wird). So sehen Sie, dass der initial_state tatsächliche bei jedem Schritt ändert.

Am Anfang einer Epoche haben wir keinen vorherigen Zustand, der als initial_state übergeben werden kann, und verwenden daher nur Nullen, dargestellt durch state = m.initial_state.eval(). Vielleicht wäre es weniger verwirrend, wenn es eine andere Eigenschaft namens m.zero_state gäbe, die Sie ausgewertet haben, um diesen Anfangszustand zu erhalten. Sie könnten zum Beispiel auch ein numpliges Array von Nullen der entsprechenden Größe verwenden, und das würde auch gut funktionieren. Das Eval ist nur ein bequemer Weg, um einen Tensor oder Nullen der passenden Größe zu erhalten.

Hoffe das macht Sinn!

Verwandte Themen