torch.nn.modules.upsampling
torch.nn.modules.upsampling 的源码.
Upsample 模块 class 类
from numbers import Integral
import warnings
from .module import Module
from .. import functional as F
class Upsample(Module):
r"""
Upsample 类的作用是,上采样给定的多通道数据(multi-channel),如 1D(时序temporal),2D(空间spatial) 和 3D(体积volumetric).
输入数据 input 的形式为:minibatch x channels x [optional depth] x [optional height] x width.
故,对于 2D spatial 输入,其是 4D Tensor;对于 3D volumetric 输入,其是 5D Tensor.
上采样的算法有:最近邻(nearest neighbor),线性(linear),双线性(bilinear) 和 三线性(trilinear),分别对应于 3D,3D,4D 和 5D Tensor.
可以给定参数 scale_factor 或目标尺寸 size 来计算输出尺寸.
(不能同时指定两个参数,会导致混淆.)
参数:
- size - tuple, ints 类型, 输出尺寸:([optional D_out], [optional H_out], W_out)`
- scale_factor - int 或 tuple,图像 height / width / depth 缩放比例因子,
- model - string 类型,指定上采样算法: nearest, linear, bilinear 和 trilinear. 默认是 nearest.
- align_corners - bool 类型,如果 align_corners=True,则对齐 input 和 output 的角点像素(corner pixels),保持在角点像素的值. 只会对 mode=linear, bilinear 和 trilinear 有作用. 默认是 False.
Shape:
- Input - (N, C, W_in),或 (N, C, H_in, W_in),或 (N, C, D_in, H_in, W_in).
- Output - (N, C, W_out),或 (N, C, H_out, W_out) 或 (N, C, D_out, H_out, W_out
其中,
D_out = [D_in x scale_factor] 或 size[-3]
H_out = [H_in x scale_factor] 或 size[-2]
W_out = [W_in x scale_factor] 或 size[-1]
Warning:
当 align_corners=True 时,线性插值方法(linear, bilinear 和 trilinear) 不能比例地对齐 output 和 input 像素,故,output 值取决于 input 尺寸. 因此默认 align_corners = False.
Note:
downsampling/general resizing,采用 nn.functional.interpolate 函数.
"""
def __init__(self, size=None, scale_factor=None, mode='nearest', align_corners=None):
super(Upsample, self).__init__()
self.size = size
self.scale_factor = scale_factor
self.mode = mode
self.align_corners = align_corners
def forward(self, input):
return F.interpolate(input, self.size, self.scale_factor, self.mode, self.align_corners)
def extra_repr(self):
if self.scale_factor is not None:
info = 'scale_factor=' + str(self.scale_factor)
else:
info = 'size=' + str(self.size)
info += ', mode=' + self.mode
return info
class UpsamplingNearest2d(Upsample):
r"""
对于由多个 input channels 组成的 input 数据,进行 2D 最近邻上采样.
通过 size 和 scale_factor 来指定尺度(scale).
当给定 size 时,其输出尺寸为:图片(h, w).
参数:
- size - tuple,ints 类型,输出尺寸:(H_out, W_out)
- scale_factor - int 类型值,图像 height 和 width 的缩放因子.
Warning:
该 class 类被废弃,由 nn.functional.interpolate 取代.
Shape:
- Input - (N, C, H_in, W_in)
- Output - (N, C, H_out, W_out)
其中,
H_out = [H_in x scale_factor]
W_out = [W_in x scale_factor]
Examples:
>>> input = torch.arange(1, 5).view(1, 1, 2, 2)
>>> input
tensor([[[[ 1., 2.],
[ 3., 4.]]]])
>>> m = nn.UpsamplingNearest2d(scale_factor=2)
>>> m(input)
tensor([[[[ 1., 1., 2., 2.],
[ 1., 1., 2., 2.],
[ 3., 3., 4., 4.],
[ 3., 3., 4., 4.]]]])
"""
def __init__(self, size=None, scale_factor=None):
super(UpsamplingNearest2d, self).__init__(size, scale_factor, mode='nearest')
def forward(self, input):
warnings.warn("nn.UpsamplingNearest2d is deprecated. Use nn.functional.interpolate instead.")
return super(UpsamplingNearest2d, self).forward(input)
class UpsamplingBilinear2d(Upsample):
r"""
对于由多个 input channels 组成的 input 数据,进行 2D bilinear 上采样.
通过 size 和 scale_factor 来指定尺度(scale).
当给定 size 时,其输出尺寸为:图片(h, w).
参数:
- size - tuple,ints 类型,输出尺寸:(H_out, W_out)
- scale_factor - int 类型值,图像 height 和 width 的缩放因子.
Warning:
该 class 类被废弃,由 nn.functional.interpolate 取代.
等价于 nn.functional.interpolate(..., mode='bilinear', align_corners=True).
Shape:
- Input - (N, C, H_in, W_in)
- Output - (N, C, H_out, W_out)
其中,
H_out = [H_in x scale_factor]
W_out = [W_in x scale_factor]
Examples:
>>> input = torch.arange(1, 5).view(1, 1, 2, 2)
>>> input
tensor([[[[ 1., 2.],
[ 3., 4.]]]])
>>> m = nn.UpsamplingBilinear2d(scale_factor=2)
>>> m(input)
tensor([[[[ 1.0000, 1.3333, 1.6667, 2.0000],
[ 1.6667, 2.0000, 2.3333, 2.6667],
[ 2.3333, 2.6667, 3.0000, 3.3333],
[ 3.0000, 3.3333, 3.6667, 4.0000]]]])
"""
def __init__(self, size=None, scale_factor=None):
super(UpsamplingBilinear2d, self).__init__(size, scale_factor, mode='bilinear', align_corners=True)
def forward(self, input):
warnings.warn("nn.UpsamplingBilinear2d is deprecated. Use nn.functional.interpolate instead.")
return super(UpsamplingBilinear2d, self).forward(input)
upsample 函数
def upsample(input, size=None, scale_factor=None, mode='nearest', align_corners=None):
r"""
根据给定 size 或 scale_factor 上采样输入input.
Warning:
该函数已废弃,替换为 torch.nn.functional.interpolate.
等价于 nn.functional.interpolate(...).
当前支持 temporal, spatial 和 volumetric 输入数据的上采样,其shape 分别为:3-D, 4-D 和 5-D.
输入数据的形式为:mini-batch x channels x [optional depth] x [optional height] x width.
上采样算法有:nearest, linear(3D-only), bilinear(4D-only), trilinear(5D-only).
"""
warnings.warn("nn.functional.upsample is deprecated. Use nn.functional.interpolate instead.")
return interpolate(input, size, scale_factor, mode, align_corners)
Examples - Upsample 函数
>>> input = torch.arange(1, 5).view(1, 1, 2, 2).float()
>>> input
tensor([[[[ 1., 2.],
[ 3., 4.]]]])
>>> m = nn.Upsample(scale_factor=2, mode='nearest')
>>> m(input)
tensor([[[[ 1., 1., 2., 2.],
[ 1., 1., 2., 2.],
[ 3., 3., 4., 4.],
[ 3., 3., 4., 4.]]]])
>>> m = nn.Upsample(scale_factor=2, mode='bilinear') # align_corners=False
>>> m(input)
tensor([[[[ 1.0000, 1.2500, 1.7500, 2.0000],
[ 1.5000, 1.7500, 2.2500, 2.5000],
[ 2.5000, 2.7500, 3.2500, 3.5000],
[ 3.0000, 3.2500, 3.7500, 4.0000]]]])
>>> m = nn.Upsample(scale_factor=2, mode='bilinear', align_corners=True)
>>> m(input)
tensor([[[[ 1.0000, 1.3333, 1.6667, 2.0000],
[ 1.6667, 2.0000, 2.3333, 2.6667],
[ 2.3333, 2.6667, 3.0000, 3.3333],
[ 3.0000, 3.3333, 3.6667, 4.0000]]]])
>>> # Try scaling the same data in a larger tensor
>>>
>>> input_3x3 = torch.zeros(3, 3).view(1, 1, 3, 3)
>>> input_3x3[:, :, :2, :2].copy_(input)
tensor([[[[ 1., 2.],
[ 3., 4.]]]])
>>> input_3x3
tensor([[[[ 1., 2., 0.],
[ 3., 4., 0.],
[ 0., 0., 0.]]]])
>>> m = nn.Upsample(scale_factor=2, mode='bilinear') # align_corners=False
>>> # Notice that values in top left corner are the same with the small input (except at boundary)
>>> m(input_3x3)
tensor([[[[ 1.0000, 1.2500, 1.7500, 1.5000, 0.5000, 0.0000],
[ 1.5000, 1.7500, 2.2500, 1.8750, 0.6250, 0.0000],
[ 2.5000, 2.7500, 3.2500, 2.6250, 0.8750, 0.0000],
[ 2.2500, 2.4375, 2.8125, 2.2500, 0.7500, 0.0000],
[ 0.7500, 0.8125, 0.9375, 0.7500, 0.2500, 0.0000],
[ 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000]]]])
>>> m = nn.Upsample(scale_factor=2, mode='bilinear', align_corners=True)
>>> # Notice that values in top left corner are now changed
>>> m(input_3x3)
tensor([[[[ 1.0000, 1.4000, 1.8000, 1.6000, 0.8000, 0.0000],
[ 1.8000, 2.2000, 2.6000, 2.2400, 1.1200, 0.0000],
[ 2.6000, 3.0000, 3.4000, 2.8800, 1.4400, 0.0000],
[ 2.4000, 2.7200, 3.0400, 2.5600, 1.2800, 0.0000],
[ 1.2000, 1.3600, 1.5200, 1.2800, 0.6400, 0.0000],
[ 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000]]]])
interpolate 函数
def interpolate(input, size=None, scale_factor=None, mode='nearest', align_corners=None):
r"""
根据给定 size 或 scale_factor,上采样或下采样输入数据input.
当前支持 temporal, spatial 和 volumetric 输入数据的上采样,其shape 分别为:3-D, 4-D 和 5-D.
输入数据的形式为:mini-batch x channels x [optional depth] x [optional height] x width.
上采样算法有:nearest, linear(3D-only), bilinear(4D-only), trilinear(5D-only).
参数:
- input (Tensor): input tensor
- size (int or Tuple[int] or Tuple[int, int] or Tuple[int, int, int]):输出的 spatial 尺寸.
- scale_factor (float or Tuple[float]): spatial 尺寸的缩放因子.
- mode (string): 上采样算法:nearest, linear, bilinear, trilinear, area. 默认为 nearest.
- align_corners (bool, optional): 如果 align_corners=True,则对齐 input 和 output 的角点像素(corner pixels),保持在角点像素的值. 只会对 mode=linear, bilinear 和 trilinear 有作用. 默认是 False.
"""
from numbers import Integral
from .modules.utils import _ntuple
def _check_size_scale_factor(dim):
if size is None and scale_factor is None:
raise ValueError('either size or scale_factor should be defined')
if size is not None and scale_factor is not None:
raise ValueError('only one of size or scale_factor should be defined')
if scale_factor is not None and isinstance(scale_factor, tuple)\
and len(scale_factor) != dim:
raise ValueError('scale_factor shape must match input shape. '
'Input is {}D, scale_factor size is {}'.format(dim, len(scale_factor)))
def _output_size(dim):
_check_size_scale_factor(dim)
if size is not None:
return size
scale_factors = _ntuple(dim)(scale_factor)
# math.floor might return float in py2.7
return [int(math.floor(input.size(i + 2) * scale_factors[i])) for i in range(dim)]
if mode in ('nearest', 'area'):
if align_corners is not None:
raise ValueError("align_corners option can only be set with the "
"interpolating modes: linear | bilinear | trilinear")
else:
if align_corners is None:
warnings.warn("Default upsampling behavior when mode={} is changed "
"to align_corners=False since 0.4.0. Please specify "
"align_corners=True if the old behavior is desired. "
"See the documentation of nn.Upsample for details.".format(mode))
align_corners = False
if input.dim() == 3 and mode == 'nearest':
return torch._C._nn.upsample_nearest1d(input, _output_size(1))
elif input.dim() == 4 and mode == 'nearest':
return torch._C._nn.upsample_nearest2d(input, _output_size(2))
elif input.dim() == 5 and mode == 'nearest':
return torch._C._nn.upsample_nearest3d(input, _output_size(3))
elif input.dim() == 3 and mode == 'area':
return adaptive_avg_pool1d(input, _output_size(1))
elif input.dim() == 4 and mode == 'area':
return adaptive_avg_pool2d(input, _output_size(2))
elif input.dim() == 5 and mode == 'area':
return adaptive_avg_pool3d(input, _output_size(3))
elif input.dim() == 3 and mode == 'linear':
return torch._C._nn.upsample_linear1d(input, _output_size(1), align_corners)
elif input.dim() == 3 and mode == 'bilinear':
raise NotImplementedError("Got 3D input, but bilinear mode needs 4D input")
elif input.dim() == 3 and mode == 'trilinear':
raise NotImplementedError("Got 3D input, but trilinear mode needs 5D input")
elif input.dim() == 4 and mode == 'linear':
raise NotImplementedError("Got 4D input, but linear mode needs 3D input")
elif input.dim() == 4 and mode == 'bilinear':
return torch._C._nn.upsample_bilinear2d(input, _output_size(2), align_corners)
elif input.dim() == 4 and mode == 'trilinear':
raise NotImplementedError("Got 4D input, but trilinear mode needs 5D input")
elif input.dim() == 5 and mode == 'linear':
raise NotImplementedError("Got 5D input, but linear mode needs 3D input")
elif input.dim() == 5 and mode == 'bilinear':
raise NotImplementedError("Got 5D input, but bilinear mode needs 4D input")
elif input.dim() == 5 and mode == 'trilinear':
return torch._C._nn.upsample_trilinear3d(input, _output_size(3), align_corners)
else:
raise NotImplementedError("Input Error: Only 3D, 4D and 5D input Tensors supported"
" (got {}D) for the modes: nearest | linear | bilinear | trilinear"
" (got {})".format(input.dim(), mode))
def upsample_nearest(input, size=None, scale_factor=None):
r"""
采用最近邻(nearest neighbour)像素值对输入 input 进行上采样.
Warning:
该函数已经废弃,取代为 torch.nn.functional.interpolate.
等价于 nn.functional.interpolate(..., mode='nearest').
当前支持 spatial 和 volumetric 上采样,(即 inputs 是 4 或 5 维).
参数:
- input (Tensor): input
- size (int or Tuple[int, int] or Tuple[int, int, int]): 输出的空间尺寸,spatial size.
- scale_factor (int): 空间尺寸缩放因子,必须是整数.
"""
# DeprecationWarning is ignored by default
warnings.warn("nn.functional.upsample_nearest is deprecated. Use nn.functional.interpolate instead.")
return interpolate(input, size, scale_factor, mode='nearest')
def upsample_bilinear(input, size=None, scale_factor=None):
r"""
采用双线性上采样(bilinear) 对输入 input 进行上采样.
Warning::
该函数已经废弃,取代为 torch.nn.functional.interpolate.
等价于 nn.functional.interpolate(..., mode='bilinear', align_corners=True).
输入数据 inputs 应该是 spatial (4 dimensional).
对于输入数据 inputs 是 volumetric (5 dimensional) 时,采用 upsample_trilinear.
参数:
- input (Tensor): input
- size (int or Tuple[int, int]): output spatial size.
- scale_factor (int or Tuple[int, int]): 空间尺寸的缩放因子.
"""
# DeprecationWarning is ignored by default
warnings.warn("nn.functional.upsample_bilinear is deprecated. Use nn.functional.interpolate instead.")
return interpolate(input, size, scale_factor, mode='bilinear', align_corners=True)
GRID_SAMPLE_INTERPOLATION_MODES = {
'bilinear': 0,
'nearest': 1,
}
GRID_SAMPLE_PADDING_MODES = {
'zeros': 0,
'border': 1,
'reflection': 2,
}