mirror of
https://github.com/zebrajr/pytorch.git
synced 2025-12-07 12:21:27 +01:00
175 lines
6.7 KiB
Python
175 lines
6.7 KiB
Python
import torch
|
|
from .module import Module
|
|
from torch.nn.parameter import Parameter
|
|
from .. import functional as F
|
|
|
|
|
|
# TODO: check contiguous in THNN
|
|
# TODO: use separate backend functions?
|
|
class _BatchNorm(Module):
|
|
|
|
def __init__(self, num_features, eps=1e-5, momentum=0.1, affine=True):
|
|
super(_BatchNorm, self).__init__()
|
|
self.num_features = num_features
|
|
self.affine = affine
|
|
self.eps = eps
|
|
self.momentum = momentum
|
|
if self.affine:
|
|
self.weight = Parameter(torch.Tensor(num_features))
|
|
self.bias = Parameter(torch.Tensor(num_features))
|
|
else:
|
|
self.register_parameter('weight', None)
|
|
self.register_parameter('bias', None)
|
|
self.register_buffer('running_mean', torch.zeros(num_features))
|
|
self.register_buffer('running_var', torch.ones(num_features))
|
|
self.reset_parameters()
|
|
|
|
def reset_parameters(self):
|
|
self.running_mean.zero_()
|
|
self.running_var.fill_(1)
|
|
if self.affine:
|
|
self.weight.data.uniform_()
|
|
self.bias.data.zero_()
|
|
|
|
def _check_input_dim(self, input):
|
|
if input.size(1) != self.running_mean.nelement():
|
|
raise ValueError('got {}-feature tensor, expected {}'
|
|
.format(input.size(1), self.num_features))
|
|
|
|
def forward(self, input):
|
|
self._check_input_dim(input)
|
|
return F.batch_norm(
|
|
input, self.running_mean, self.running_var, self.weight, self.bias,
|
|
self.training, self.momentum, self.eps)
|
|
|
|
def __repr__(self):
|
|
return ('{name}({num_features}, eps={eps}, momentum={momentum},'
|
|
' affine={affine})'
|
|
.format(name=self.__class__.__name__, **self.__dict__))
|
|
|
|
|
|
class BatchNorm1d(_BatchNorm):
|
|
r"""Applies Batch Normalization over a 2d or 3d input that is seen as a mini-batch.
|
|
|
|
.. math::
|
|
|
|
y = \frac{x - mean[x]}{ \sqrt{Var[x]} + \epsilon} * gamma + beta
|
|
|
|
The mean and standard-deviation are calculated per-dimension over
|
|
the mini-batches and gamma and beta are learnable parameter vectors
|
|
of size C (where C is the input size).
|
|
|
|
During training, this layer keeps a running estimate of its computed mean
|
|
and variance. The running sum is kept with a default momentum of 0.1.
|
|
|
|
During evaluation, this running mean/variance is used for normalization.
|
|
|
|
Args:
|
|
num_features: num_features from an expected input of size `batch_size x num_features [x width]`
|
|
eps: a value added to the denominator for numerical stability. Default: 1e-5
|
|
momentum: the value used for the running_mean and running_var computation. Default: 0.1
|
|
affine: a boolean value that when set to true, gives the layer learnable affine parameters.
|
|
|
|
Shape:
|
|
- Input: :math:`(N, C)` or :math:`(N, C, L)`
|
|
- Output: :math:`(N, C)` or :math:`(N, C, L)` (same shape as input)
|
|
|
|
Examples:
|
|
>>> # With Learnable Parameters
|
|
>>> m = nn.BatchNorm1d(100)
|
|
>>> # Without Learnable Parameters
|
|
>>> m = nn.BatchNorm1d(100, affine=False)
|
|
>>> input = autograd.Variable(torch.randn(20, 100))
|
|
>>> output = m(input)
|
|
"""
|
|
|
|
def _check_input_dim(self, input):
|
|
if input.dim() != 2 and input.dim() != 3:
|
|
raise ValueError('expected 2D or 3D input (got {}D input)'
|
|
.format(input.dim()))
|
|
super(BatchNorm1d, self)._check_input_dim(input)
|
|
|
|
|
|
class BatchNorm2d(_BatchNorm):
|
|
r"""Applies Batch Normalization over a 4d input that is seen as a mini-batch of 3d inputs
|
|
|
|
.. math::
|
|
|
|
y = \frac{x - mean[x]}{ \sqrt{Var[x]} + \epsilon} * gamma + beta
|
|
|
|
The mean and standard-deviation are calculated per-dimension over
|
|
the mini-batches and gamma and beta are learnable parameter vectors
|
|
of size C (where C is the input size).
|
|
|
|
During training, this layer keeps a running estimate of its computed mean
|
|
and variance. The running sum is kept with a default momentum of 0.1.
|
|
|
|
During evaluation, this running mean/variance is used for normalization.
|
|
|
|
Args:
|
|
num_features: num_features from an expected input of size batch_size x num_features x height x width
|
|
eps: a value added to the denominator for numerical stability. Default: 1e-5
|
|
momentum: the value used for the running_mean and running_var computation. Default: 0.1
|
|
affine: a boolean value that when set to true, gives the layer learnable affine parameters.
|
|
|
|
Shape:
|
|
- Input: :math:`(N, C, H, W)`
|
|
- Output: :math:`(N, C, H, W)` (same shape as input)
|
|
|
|
Examples:
|
|
>>> # With Learnable Parameters
|
|
>>> m = nn.BatchNorm2d(100)
|
|
>>> # Without Learnable Parameters
|
|
>>> m = nn.BatchNorm2d(100, affine=False)
|
|
>>> input = autograd.Variable(torch.randn(20, 100, 35, 45))
|
|
>>> output = m(input)
|
|
"""
|
|
|
|
def _check_input_dim(self, input):
|
|
if input.dim() != 4:
|
|
raise ValueError('expected 4D input (got {}D input)'
|
|
.format(input.dim()))
|
|
super(BatchNorm2d, self)._check_input_dim(input)
|
|
|
|
|
|
class BatchNorm3d(_BatchNorm):
|
|
r"""Applies Batch Normalization over a 5d input that is seen as a mini-batch of 4d inputs
|
|
|
|
.. math::
|
|
|
|
y = \frac{x - mean[x]}{ \sqrt{Var[x]} + \epsilon} * gamma + beta
|
|
|
|
The mean and standard-deviation are calculated per-dimension over
|
|
the mini-batches and gamma and beta are learnable parameter vectors
|
|
of size C (where C is the input size).
|
|
|
|
During training, this layer keeps a running estimate of its computed mean
|
|
and variance. The running sum is kept with a default momentum of 0.1.
|
|
|
|
During evaluation, this running mean/variance is used for normalization.
|
|
|
|
Args:
|
|
num_features: num_features from an expected input of size batch_size x num_features x depth x height x width
|
|
eps: a value added to the denominator for numerical stability. Default: 1e-5
|
|
momentum: the value used for the running_mean and running_var computation. Default: 0.1
|
|
affine: a boolean value that when set to true, gives the layer learnable affine parameters.
|
|
|
|
Shape:
|
|
- Input: :math:`(N, C, D, H, W)`
|
|
- Output: :math:`(N, C, D, H, W)` (same shape as input)
|
|
|
|
Examples:
|
|
>>> # With Learnable Parameters
|
|
>>> m = nn.BatchNorm3d(100)
|
|
>>> # Without Learnable Parameters
|
|
>>> m = nn.BatchNorm3d(100, affine=False)
|
|
>>> input = autograd.Variable(torch.randn(20, 100, 35, 45, 10))
|
|
>>> output = m(input)
|
|
"""
|
|
|
|
def _check_input_dim(self, input):
|
|
if input.dim() != 5:
|
|
raise ValueError('expected 5D input (got {}D input)'
|
|
.format(input.dim()))
|
|
super(BatchNorm3d, self)._check_input_dim(input)
|