'Builds a sentence decoder.
Args:
name: Decoder name.
embeddings: Batch of sentences to decode; a float32 Tensor with shape
[batch_size, padded_length, emb_dim].
targets: Batch of target word ids; an int64 Tensor with shape
[batch_size, padded_length].
mask: A 0/1 Tensor with shape [batch_size, padded_length].
initial_state: Initial state of the GRU. A float32 Tensor with shape
[batch_size, num_gru_cells].
reuse_logits: Whether to reuse the logits weights.'

def _build_decoder(self, name, embeddings, targets, mask, initial_state, reuse_logits):

    cell = self._initialize_gru_cell(self.config.encoder_dim)
    with tf.variable_scope(name) as scope:
        decoder_input = tf.pad(embeddings[:, :(-1), :], [[0, 0], [1, 0], [0, 0]], name='input')
        length = tf.reduce_sum(mask, 1, name='length')
        (decoder_output, _) = tf.nn.dynamic_rnn(cell=cell, inputs=decoder_input, sequence_length=length, initial_state=initial_state, scope=scope)
    decoder_output = tf.reshape(decoder_output, [(-1), self.config.encoder_dim])
    targets = tf.reshape(targets, [(-1)])
    weights = tf.to_float(tf.reshape(mask, [(-1)]))
    with tf.variable_scope('logits', reuse=reuse_logits) as scope:
        logits = tf.contrib.layers.fully_connected(inputs=decoder_output, num_outputs=self.config.vocab_size, activation_fn=None, weights_initializer=self.uniform_initializer, scope=scope)
    losses = tf.nn.sparse_softmax_cross_entropy_with_logits(labels=targets, logits=logits)
    batch_loss = tf.reduce_sum((losses * weights))
    tf.losses.add_loss(batch_loss)
    tf.summary.scalar(('losses/' + name), batch_loss)
    self.target_cross_entropy_losses.append(losses)
    self.target_cross_entropy_loss_weights.append(weights)
