code: def _conv_linear(args, filter_size, num_features, bias, bias_start=0.0, scope=None):
      
      # Calculate the total size of arguments on dimension 1.
      total_arg_size_depth = 0
      shapes = [a.get_shape().as_list() for a in args]
      for shape in shapes:
          if len(shape) != 4:
              raise ValueError("Linear is expecting 4D arguments: %s" % str(shapes))
          if not shape[3]:
              raise ValueError("Linear expects shape[4] of arguments: %s" % str(shapes))
          else:
              total_arg_size_depth += shape[3]
  
      dtype = [a.dtype for a in args][0]
  
      # Now the computation.
      with tf.variable_scope(scope or "Conv"):
          matrix = tf.get_variable(
              "Matrix", [filter_size[0], filter_size[1], total_arg_size_depth, num_features], dtype=dtype
          )
          if len(args) == 1:
              res = tf.nn.conv2d(args[0], matrix, strides=[1, 1, 1, 1], padding='SAME')
          else:
              res = tf.nn.conv2d(tf.concat(args, 3), matrix, strides=[1, 1, 1, 1], padding='SAME')
          if not bias:
              return res
          bias_term = tf.get_variable(
              "Bias", [num_features], dtype=dtype, initializer=tf.constant_initializer(bias_start, dtype=dtype)
          )
      return res + bias_term
docs: convolution:
  
      Parameters
      ----------
      args : tensor
          4D Tensor or a list of 4D, batch x n, Tensors.
      filter_size : tuple of int
          Filter height and width.
      num_features : int
          Nnumber of features.
      bias_start : float
          Starting value to initialize the bias; 0 by default.
      scope : VariableScope
          For the created subgraph; defaults to "Linear".
  
      Returns
      --------
      - A 4D Tensor with shape [batch h w num_features]
  
      Raises
      -------
      - ValueError : if some of the arguments has unspecified or wrong shape.