code: def create_visual_observation_encoder(self, image_input, h_size, activation, num_layers, scope,
                                            reuse):
          
          with tf.variable_scope(scope):
              conv1 = tf.layers.conv2d(image_input, 16, kernel_size=[8, 8], strides=[4, 4],
                                       activation=tf.nn.elu, reuse=reuse, name="conv_1")
              conv2 = tf.layers.conv2d(conv1, 32, kernel_size=[4, 4], strides=[2, 2],
                                       activation=tf.nn.elu, reuse=reuse, name="conv_2")
              hidden = c_layers.flatten(conv2)
  
          with tf.variable_scope(scope + '/' + 'flat_encoding'):
              hidden_flat = self.create_vector_observation_encoder(hidden, h_size, activation,
                                                                   num_layers, scope, reuse)
          return hidden_flat
docs: Builds a set of visual (CNN) encoders.
          :param reuse: Whether to re-use the weights within the same scope.
          :param scope: The scope of the graph within which to create the ops.
          :param image_input: The placeholder for the image input to use.
          :param h_size: Hidden layer size.
          :param activation: What type of activation function to use for layers.
          :param num_layers: number of hidden layers to create.
          :return: List of hidden layer tensors.