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

    Args:
      inputs: image tensor with size BSx64x64xC
      nout: number of output channels
      has_batchnorm: variable to use or not use batch normalization
    Returns:
      net: encoded image with size BSxNout
      skips: skip connection after each layer
    """
    vgg_layer = common_video.vgg_layer
    net01 = inputs

    skips = []

    # The original model only supports 64x64. We can support higher resolutions
    # as long as they are square and the side-length is a power of two
    # by inserting more downscaling layers. Corresponding upscaling can be found
    # in the decoder, as well.
    # (This procedure is ad-hoc, i.e., not from the SVP-FP paper)
    _, res_y, res_x, _ = inputs.shape.as_list()
    assert res_x == res_y, "Model only supports square inputs"
    is_power_of_two = lambda x: ((x & (x - 1)) == 0) and x != 0
    assert is_power_of_two(res_x), "Input resolution must be power of 2"
    assert res_x >= 64, "Input resolution must be >= 64"
    ds_idx = 0
    while res_x > 64:
      h = tfcl.repeat(net01, 2, vgg_layer, 64, scope="downscale%d" % ds_idx,
                      is_training=self.is_training, activation=tf.nn.relu,
                      has_batchnorm=has_batchnorm)
      net01 = tfl.max_pooling2d(h, [2, 2], strides=(2, 2),
                                name="downscale%d_pool" % ds_idx)
      skips.append(h)
      ds_idx += 1
      res_x /= 2

    # h1
    net11 = tfcl.repeat(net01, 2, vgg_layer, 64,
                        scope="h1", is_training=self.is_training,
                        activation=tf.nn.relu, has_batchnorm=has_batchnorm)
    net12 = tfl.max_pooling2d(net11, [2, 2], strides=(2, 2), name="h1_pool")
    # h2
    net21 = tfcl.repeat(net12, 2, vgg_layer, 128,
                        scope="h2", is_training=self.is_training,
                        activation=tf.nn.relu, has_batchnorm=has_batchnorm)
    net22 = tfl.max_pooling2d(net21, [2, 2], strides=(2, 2), name="h2_pool")
    # h3
    net31 = tfcl.repeat(net22, 3, vgg_layer, 256,
                        scope="h3", is_training=self.is_training,
                        activation=tf.nn.relu, has_batchnorm=has_batchnorm)
    net32 = tfl.max_pooling2d(net31, [2, 2], strides=(2, 2), name="h3_pool")
    # h4
    net41 = tfcl.repeat(net32, 3, vgg_layer, 512,
                        scope="h4", is_training=self.is_training,
                        activation=tf.nn.relu, has_batchnorm=has_batchnorm)
    net42 = tfl.max_pooling2d(net41, [2, 2], strides=(2, 2), name="h4_pool")
    # h5
    net51 = tfcl.repeat(net42, 1, vgg_layer, nout,
                        kernel_size=4, padding="VALID", activation=tf.nn.relu,
                        scope="h5", is_training=self.is_training,
                        has_batchnorm=has_batchnorm)

    skips += [net11, net21, net31, net41]
    return net51, skips
VGG based image encoder.

    Args:
      inputs: image tensor with size BSx64x64xC
      nout: number of output channels
      has_batchnorm: variable to use or not use batch normalization
    Returns:
      net: encoded image with size BSxNout
      skips: skip connection after each layer
    
tensor2tensor/models/video/emily.py