'Creates a WaveNet network and returns the autoencoding loss.
The variables are all scoped to the given name.'

def loss(self, input_batch, global_condition_batch=None, l2_regularization_strength=None, name='wavenet'):

    with tf.name_scope(name):
        encoded_input = mu_law_encode(input_batch, self.quantization_channels)
        gc_embedding = self._embed_gc(global_condition_batch)
        encoded = self._one_hot(encoded_input)
        if self.scalar_input:
            network_input = tf.reshape(tf.cast(input_batch, tf.float32), [self.batch_size, (-1), 1])
        else:
            network_input = encoded
        network_input_width = (tf.shape(network_input)[1] - 1)
        network_input = tf.slice(network_input, [0, 0, 0], [(-1), network_input_width, (-1)])
        raw_output = self._create_network(network_input, gc_embedding)
        with tf.name_scope('loss'):
            target_output = tf.slice(tf.reshape(encoded, [self.batch_size, (-1), self.quantization_channels]), [0, self.receptive_field, 0], [(-1), (-1), (-1)])
            target_output = tf.reshape(target_output, [(-1), self.quantization_channels])
            prediction = tf.reshape(raw_output, [(-1), self.quantization_channels])
            loss = tf.nn.softmax_cross_entropy_with_logits(logits=prediction, labels=target_output)
            reduced_loss = tf.reduce_mean(loss)
            tf.summary.scalar('loss', reduced_loss)
            if (l2_regularization_strength is None):
                return reduced_loss
            else:
                l2_loss = tf.add_n([tf.nn.l2_loss(v) for v in tf.trainable_variables() if (not ('bias' in v.name))])
                total_loss = (reduced_loss + (l2_regularization_strength * l2_loss))
                tf.summary.scalar('l2_loss', l2_loss)
                tf.summary.scalar('total_loss', total_loss)
                return total_loss
