Source code for cvnets.layers.global_pool

#
# For licensing see accompanying LICENSE file.
# Copyright (C) 2023 Apple Inc. All Rights Reserved.
#

import argparse
from typing import List, Optional

import torch
from torch import Tensor

from cvnets.layers.base_layer import BaseLayer
from utils import logger


[docs]class GlobalPool(BaseLayer): """ This layers applies global pooling over a 4D or 5D input tensor Args: pool_type (Optional[str]): Pooling type. It can be mean, rms, or abs. Default: `mean` keep_dim (Optional[bool]): Do not squeeze the dimensions of a tensor. Default: `False` Shape: - Input: :math:`(N, C, H, W)` or :math:`(N, C, D, H, W)` - Output: :math:`(N, C, 1, 1)` or :math:`(N, C, 1, 1, 1)` if keep_dim else :math:`(N, C)` """ pool_types = ["mean", "rms", "abs"]
[docs] def __init__( self, pool_type: Optional[str] = "mean", keep_dim: Optional[bool] = False, *args, **kwargs ) -> None: super().__init__() if pool_type not in self.pool_types: logger.error( "Supported pool types are: {}. Got {}".format( self.pool_types, pool_type ) ) self.pool_type = pool_type self.keep_dim = keep_dim
[docs] @classmethod def add_arguments(cls, parser: argparse.ArgumentParser): cls_name = "{} arguments".format(cls.__name__) group = parser.add_argument_group(title=cls_name, description=cls_name) group.add_argument( "--model.layer.global-pool", type=str, default="mean", help="Which global pooling?", ) return parser
def _global_pool(self, x: Tensor, dims: List): if self.pool_type == "rms": # root mean square x = x**2 x = torch.mean(x, dim=dims, keepdim=self.keep_dim) x = x**-0.5 elif self.pool_type == "abs": # absolute x = torch.mean(torch.abs(x), dim=dims, keepdim=self.keep_dim) else: # default is mean # same as AdaptiveAvgPool x = torch.mean(x, dim=dims, keepdim=self.keep_dim) return x
[docs] def forward(self, x: Tensor) -> Tensor: if x.dim() == 4: dims = [-2, -1] elif x.dim() == 5: dims = [-3, -2, -1] else: raise NotImplementedError("Currently 2D and 3D global pooling supported") return self._global_pool(x, dims=dims)
def __repr__(self): return "{}(type={})".format(self.__class__.__name__, self.pool_type)