docs: def sg_pool(tensor, opt):
      r"""Performs the 2-D pooling on the `tensor`.
      Mostly used with sg_conv().
  
      Args:
        tensor: A 4-D `Tensor` (automatically given by chain).
        opt:
          size: A tuple or list of integers of length 2 representing `[kernel height, kernel width]`.
            Can be an int if both values are the same.
            If not specified, (2, 2) is set implicitly.
          stride: A tuple or list of integers of length 2 or 4 representing stride dimensions.
            If the length is 2, i.e., (a, b), the stride is `[1, a, b, 1]`.
            If the length is 4, i.e., (a, b, c, d), the stride is `[a, b, c, d]`.
            Can be an int. If the length is an int, i.e., a, the stride is `[1, a, a, 1]`.
            The default value is [1, 1, 1, 1].
          avg: Boolean. If True, average pooling is applied. Otherwise, max pooling.
          name: If provided, replace current tensor's name.
  
      Returns:
        A `Tensor`. The max pooled output tensor.
      """
  
      # default stride and pad
      opt += tf.sg_opt(stride=(1, 2, 2, 1), pad='VALID')
  
      # shape stride
      opt.stride = opt.stride if isinstance(opt.stride, (list, tuple)) else [1, opt.stride, opt.stride, 1]
      opt.stride = [1, opt.stride[0], opt.stride[1], 1] if len(opt.stride) == 2 else opt.stride
  
      # shape size
      opt += tf.sg_opt(size=opt.stride)
      opt.size = opt.size if isinstance(opt.size, (list, tuple)) else [1, opt.size, opt.size, 1]
      opt.size = [1, opt.size[0], opt.size[1], 1] if len(opt.size) == 2 else opt.size
  
      if opt.avg:
          out = tf.nn.avg_pool(tensor, opt.size, opt.stride, opt.pad)
      else:
          out = tf.nn.max_pool(tensor, opt.size, opt.stride, opt.pad)
  
      return tf.identity(out, name=opt.name)