import tensorflow as tf

        print('Conv layer {0} -> {1}'.format(bottom.get_shape().as_list(),conv_layer.get_shape().as_list()))
        return conv_layer

    def batch_norm_layer(self, name, input_tensor,training):
        with tf.variable_scope(name) as scope:
            return tf.contrib.layers.batch_norm(input_tensor,scope=scope,is_training=training,decay=0.99)

    def deconv_bn_relu(self, bottom, name, kernel_size, output_channels, initializer, stride = 1, bn=False, training=False, relu=True):
        input_shape = bottom.get_shape().as_list()
        input_channels = input_shape[-1]
        output_shape = [input_shape[0], input_shape[1]*stride, input_shape[2]*stride, output_channels]
        with tf.variable_scope(name) as scope:
            kernel = self.variable('weights', [kernel_size, kernel_size, output_channels, input_channels], initializer, regularizer=tf.contrib.layers.l2_regularizer(0.0005))
            deconv = tf.nn.conv2d_transpose(bottom, kernel, output_shape, [1, stride, stride, 1], padding='SAME')
            biases = self.variable('biases', [output_channels], tf.constant_initializer(0.0))
            deconv_layer = tf.nn.bias_add(deconv, biases)
            if bn:
                deconv_layer = self.batch_norm_layer('batch_norm_layer',deconv_layer,training)
            if relu:
                deconv_layer = tf.nn.relu(deconv_layer, name=scope.name)
        print('Deconv layer {0} -> {1}'.format(bottom.get_shape().as_list(),deconv_layer.get_shape().as_list()))
        return deconv_layer
