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)