def decoder(self, inputs, nout, skips=None, has_batchnorm=True):
    """VGG based image decoder.

    Args:
      inputs: image tensor with size BSxX
      nout: number of output channels
      skips: optional skip connections from encoder
      has_batchnorm: variable to use or not use batch normalization
    Returns:
      net: decoded image with size BSx64x64xNout
      skips: skip connection after each layer
    """
    vgg_layer = common_video.vgg_layer
    net = inputs
    # d1
    net = tfl.conv2d_transpose(net, 512, kernel_size=4, padding="VALID",
                               name="d1_deconv", activation=tf.nn.relu)
    if has_batchnorm:
      net = tfl.batch_normalization(
          net, training=self.is_training, name="d1_bn")
    net = tf.nn.relu(net)
    net = common_layers.upscale(net, 2)
    # d2
    if skips is not None:
      net = tf.concat([net, skips[-1]], axis=3)
    net = tfcl.repeat(net, 2, vgg_layer, 512, scope="d2a",
                      is_training=self.is_training,
                      activation=tf.nn.relu, has_batchnorm=has_batchnorm)
    net = tfcl.repeat(net, 1, vgg_layer, 256, scope="d2b",
                      is_training=self.is_training,
                      activation=tf.nn.relu, has_batchnorm=has_batchnorm)
    net = common_layers.upscale(net, 2)
    # d3
    if skips is not None:
      net = tf.concat([net, skips[-2]], axis=3)
    net = tfcl.repeat(net, 2, vgg_layer, 256, scope="d3a",
                      is_training=self.is_training,
                      activation=tf.nn.relu, has_batchnorm=has_batchnorm)
    net = tfcl.repeat(net, 1, vgg_layer, 128, scope="d3b",
                      is_training=self.is_training,
                      activation=tf.nn.relu, has_batchnorm=has_batchnorm)
    net = common_layers.upscale(net, 2)
    # d4
    if skips is not None:
      net = tf.concat([net, skips[-3]], axis=3)
    net = tfcl.repeat(net, 1, vgg_layer, 128, scope="d4a",
                      is_training=self.is_training,
                      activation=tf.nn.relu, has_batchnorm=has_batchnorm)
    net = tfcl.repeat(net, 1, vgg_layer, 64, scope="d4b",
                      is_training=self.is_training,
                      activation=tf.nn.relu, has_batchnorm=has_batchnorm)
    net = common_layers.upscale(net, 2)
    # d5
    if skips is not None:
      net = tf.concat([net, skips[-4]], axis=3)
    net = tfcl.repeat(net, 1, vgg_layer, 64, scope="d5",
                      is_training=self.is_training,
                      activation=tf.nn.relu, has_batchnorm=has_batchnorm)

    # if there are still skip connections left, we have more upscaling to do
    if skips is not None:
      for i, s in enumerate(skips[-5::-1]):
        net = common_layers.upscale(net, 2)
        net = tf.concat([net, s], axis=3)
        net = tfcl.repeat(net, 1, vgg_layer, 64, scope="upscale%d" % i,
                          is_training=self.is_training,
                          activation=tf.nn.relu, has_batchnorm=has_batchnorm)

    net = tfl.conv2d_transpose(net, nout, kernel_size=3, padding="SAME",
                               name="d6_deconv", activation=None)
    return net
VGG based image decoder.

    Args:
      inputs: image tensor with size BSxX
      nout: number of output channels
      skips: optional skip connections from encoder
      has_batchnorm: variable to use or not use batch normalization
    Returns:
      net: decoded image with size BSx64x64xNout
      skips: skip connection after each layer
    
tensor2tensor/models/video/emily.py