r"""Applies Synchronized Batch Normalization for distributed training. Args: num_features: usually :math:`C` from an input of shape :math:`(N, C, H, W)` or the highest ranked dimension of an input less than 4D. eps: a value added to the denominator for nu
| 115 | |
| 116 | |
| 117 | class SyncBatchNorm(_BatchNorm): |
| 118 | r"""Applies Synchronized Batch Normalization for distributed training. |
| 119 | |
| 120 | Args: |
| 121 | num_features: usually :math:`C` from an input of shape |
| 122 | :math:`(N, C, H, W)` or the highest ranked dimension of an input |
| 123 | less than 4D. |
| 124 | eps: a value added to the denominator for numerical stability. |
| 125 | Default: 1e-5 |
| 126 | momentum: the value used for the ``running_mean`` and ``running_var`` computation. |
| 127 | Default: 0.9 |
| 128 | affine: a boolean value that when set to True, this module has |
| 129 | learnable affine parameters. Default: True |
| 130 | track_running_stats: when set to True, this module tracks the |
| 131 | running mean and variance. When set to False, this module does not |
| 132 | track such statistics and always uses batch statistics in both training |
| 133 | and eval modes. Default: True |
| 134 | freeze: when set to True, this module does not update the |
| 135 | running mean and variance, and uses the running mean and variance instead of |
| 136 | the batch mean and batch variance to normalize the input. The parameter takes effect |
| 137 | only when the module is initilized with track_running_stats as True. |
| 138 | Default: False |
| 139 | group: communication group, caculate mean and variance between this group. |
| 140 | Default: :obj:`~.distributed.WORLD` |
| 141 | """ |
| 142 | |
| 143 | def __init__( |
| 144 | self, |
| 145 | num_features, |
| 146 | eps=1e-5, |
| 147 | momentum=0.9, |
| 148 | affine=True, |
| 149 | track_running_stats=True, |
| 150 | freeze=False, |
| 151 | group: Optional[Group] = WORLD, |
| 152 | **kwargs |
| 153 | ) -> None: |
| 154 | super().__init__( |
| 155 | num_features, eps, momentum, affine, track_running_stats, freeze, **kwargs |
| 156 | ) |
| 157 | self.group = group |
| 158 | |
| 159 | def _check_input_ndim(self, inp): |
| 160 | if len(inp.shape) not in {2, 3, 4}: |
| 161 | raise ValueError( |
| 162 | "expected 2D, 3D or 4D input (got {}D input)".format(len(inp.shape)) |
| 163 | ) |
| 164 | |
| 165 | def forward(self, inp): |
| 166 | self._check_input_ndim(inp) |
| 167 | |
| 168 | inp_shape = inp.shape |
| 169 | _ndims = len(inp_shape) |
| 170 | if _ndims != 4: |
| 171 | new_shape = Tensor([1, 1, 1, 1], device=inp.device) |
| 172 | origin_shape = inp_shape |
| 173 | if _ndims == 2: |
| 174 | new_shape[:2] = origin_shape[:2] |
no outgoing calls