'Run a step of the model feeding the given inputs.
Args:
session: tensorflow session to use.
encoder_inputs: list of numpy int vectors to feed as encoder inputs.
decoder_inputs: list of numpy int vectors to feed as decoder inputs.
target_weights: list of numpy float vectors to feed as target weights.
bucket_id: which bucket of the model to use.
forward_only: whether to do the backward step or only forward.
Returns:
A triple consisting of gradient norm (or None if we did not do backward),
average perplexity, and the outputs.
Raises:
ValueError: if length of encoder_inputs, decoder_inputs, or
target_weights disagrees with bucket size for the specified bucket_id.'

def step(self, session, encoder_inputs, decoder_inputs, target_weights, bucket_id, forward_only):

    (encoder_size, decoder_size) = self.buckets[bucket_id]
    if (len(encoder_inputs) != encoder_size):
        raise ValueError(('Encoder    length    must    be    equal    to    the    one    in    bucket,    %d    !=    %d.' % (len(encoder_inputs), encoder_size)))
    if (len(decoder_inputs) != decoder_size):
        raise ValueError(('Decoder    length    must    be    equal    to    the    one    in    bucket,    %d    !=    %d.' % (len(decoder_inputs), decoder_size)))
    if (len(target_weights) != decoder_size):
        raise ValueError(('Weights    length    must    be    equal    to    the    one    in    bucket,    %d    !=    %d.' % (len(target_weights), decoder_size)))
    input_feed = {}
    for l in xrange(encoder_size):
        input_feed[self.encoder_inputs[l].name] = encoder_inputs[l]
    for l in xrange(decoder_size):
        input_feed[self.decoder_inputs[l].name] = decoder_inputs[l]
        input_feed[self.target_weights[l].name] = target_weights[l]
    last_target = self.decoder_inputs[decoder_size].name
    input_feed[last_target] = np.zeros([self.batch_size], dtype=np.int32)
    if (not forward_only):
        output_feed = [self.updates[bucket_id], self.gradient_norms[bucket_id], self.losses[bucket_id]]
    else:
        output_feed = [self.losses[bucket_id]]
        for l in xrange(decoder_size):
            output_feed.append(self.outputs[bucket_id][l])
    outputs = session.run(output_feed, input_feed)
    if (not forward_only):
        return (outputs[1], outputs[2], None)
    else:
        return (None, outputs[0], outputs[1:])
