'Runs the model on the given data for one full pass.'

def run_epoch(self, session, data_size, batch_generator, is_training, verbose=0, freq=10, summary_writer=None, debug=False, divide_by_n=1):

    epoch_size = (data_size // (self.batch_size * self.num_unrollings))
    if ((data_size % (self.batch_size * self.num_unrollings)) != 0):
        epoch_size += 1
    if (verbose > 0):
        logging.info('epoch_size:    %d', epoch_size)
        logging.info('data_size:    %d', data_size)
        logging.info('num_unrollings:    %d', self.num_unrollings)
        logging.info('batch_size:    %d', self.batch_size)
    if is_training:
        extra_op = self.train_op
    else:
        extra_op = tf.no_op()
    state = session.run(self.zero_state)
    self.reset_loss_monitor.run()
    start_time = time.time()
    for step in range((epoch_size // divide_by_n)):
        data = batch_generator.next()
        inputs = np.array(data[:(-1)]).transpose()
        targets = np.array(data[1:]).transpose()
        ops = [self.average_loss, self.final_state, extra_op, self.summaries, self.global_step, self.learning_rate]
        feed_dict = {self.input_data: inputs, self.targets: targets, self.initial_state: state}
        results = session.run(ops, feed_dict)
        (average_loss, state, _, summary_str, global_step, lr) = results
        ppl = np.exp(average_loss)
        if ((verbose > 0) and (((step + 1) % freq) == 0)):
            logging.info('%.1f%%,    step:%d,    perplexity:    %.3f,    speed:    %.0f    words', ((((step + 1) * 1.0) / epoch_size) * 100), step, ppl, ((((step + 1) * self.batch_size) * self.num_unrollings) / (time.time() - start_time)))
    logging.info('Perplexity:    %.3f,    speed:    %.0f    words    per    sec', ppl, ((((step + 1) * self.batch_size) * self.num_unrollings) / (time.time() - start_time)))
    return (ppl, summary_str, global_step)
