# How to upsample a given multi-channel temporal, spatial or volumetric data in PyTorch?

PyTorchServer Side ProgrammingProgramming

A temporal data can be represented as a 1D tensor, and spatial data as 2D tensor while a volumetric data can be represented as a 3D tensor. The Upsample class provided by torch.nn module supports these types of data to be upsampled. But these data must be in the form N ☓ C ☓ D (optional) ☓ H (optional) ☓ W (optional),Where N is the minibatch size, C is the numberchannels, D, H and W are depth, height and width of the data, respectively. Hence, to upsample a temporal data (1D), we need it to be in 3D in the form of N ☓ C ☓ W, spatial data (2D) need to be in 4D in the form of N ☓ C ☓ H ☓ W, whereas volumetric data (3D) need to be in 5D in the form of N ☓ C ☓ D ☓ H ☓ W.

It supports different scale factors and modes. On a 3D(temporal) tensor, we can apply mode='linear' and 'nearest'. On a 4D (Spatial) tensor we can apply mode='nearest', 'bilinear' and 'bicubic'. On a 5D (Volumetric) tensor, we can apply mode='nearest' and 'trilinear'.

## Syntax

torch.nn.Upsample()

## Steps

You could use the following steps to upsample temporal, spatial or volumetric data

• Import the required library. In all the following examples, the required Python library is torch. Make sure you have already installed it.

import torch
• Define temporal (3D), spatial (4D) or volumetric (5D) tensors and print them.

input = torch.tensor([[1., 2.],[3., 4.]]).view(1,2,2)
print(input.size())
print("Input Tensor:\n", input)
• Create an instance of Upsample with scale_fator and mode to upsample a given multichannel data.

upsample = torch.nn.Upsample(scale_factor=3, mode='nearest')
• Upsample the above-defined temporal, spatial or volumetric tensor using the created instance.

output = upsample(input)
• Print the above upsampled tensor.

print("Upsample by a scale_factor=3 with mode='nearest':\n",output)

## Example 1

In this program, we upsample a temporal  with different scale_factor and modes.

# Python program to upsample a 3D (Temporal) tensor
# 3D tensor we can apply mode='linear' and 'nearest'
import torch

# define a tensor and view as a 3D tensor
input = torch.tensor([[1., 2.],[3., 4.]]).view(1,2,2)
print(input.size())
print("Input Tensor:\n", input)

# create an instance of Upsample with scale_factor and mode
upsample1 = torch.nn.Upsample(scale_factor=2)
output1 = upsample1(input)
print("Upsample by a scale_factor=2\n", output1)

# define upsample with scale_factor and mode
upsample2 = torch.nn.Upsample(scale_factor=3)
output2 = upsample2(input)
print("Upsample by a scale_factor=3 with default mode:\n", output2)
upsample2 = torch.nn.Upsample(scale_factor=3, mode='nearest')
output2 = upsample2(input)
print("Upsample by a scale_factor=3 mode='nearest':\n", output2)
upsample_linear = torch.nn.Upsample(scale_factor=3, mode='linear')
output_linear = upsample_linear(input)
print("Upsample by a scale_factor=3, mode='linear':\n", output_linear)

## Output

torch.Size([1, 2, 2])
Input Tensor:
tensor([[[1., 2.],[3., 4.]]])
Upsample by a scale_factor=2
tensor([[[1., 1., 2., 2.],[3., 3., 4., 4.]]])
Upsample by a scale_factor=3 with default mode:
tensor([[[1., 1., 1., 2., 2., 2.],[3., 3., 3., 4., 4., 4.]]])
Upsample by a scale_factor=3 mode='nearest':
tensor([[[1., 1., 1., 2., 2., 2.],[3., 3., 3., 4., 4., 4.]]])
Upsample by a scale_factor=3, mode='linear':
tensor([[[1.0000, 1.0000, 1.3333, 1.6667, 2.0000, 2.0000],[3.0000, 3.0000, 3.3333, 3.6667, 4.0000, 4.0000]]])

Note the differences between output tensors with different scale_factors and modes.

## Example 2

In the following Python program, we upsample a 4D(Spatial) tensor with different scale_factors and modes..

# Python program to upsample a 4D (Spatial) tensor
# on 4D(Spatial) tensor we can apply mode='nearest', 'bilinear' and 'bicubic'

import torch

# define a tensor and view as a 4D tensor
input = torch.tensor([[1., 2.],[3., 4.]]).view(1,1,2,2)
print(input.size())
print("Input Tensor:\n", input)

# upsample using mode='nearest'
upsample_nearest = torch.nn.Upsample(scale_factor=3,
mode='nearest')
output_nearest = upsample_nearest(input)

# upsample using mode='bilinear'
upsample_bilinear = torch.nn.Upsample(scale_factor=3,
mode='bilinear')

output_bilinear = upsample_bilinear(input)
# upsample using mode='bicubic'
upsample_bicubic = torch.nn.Upsample(scale_factor=3, mode='bicubic')
output_bicubic = upsample_bicubic(input)

# display the outputs
print("Upsample by a scale_factor=3, mode='nearest':\n", output_nearest)
print("Upsample by a scale_factor=3, mode='bilinear':\n",
output_bilinear)
print("Upsample by a scale_factor=3, mode='bicubic':\n", output_bicubic)

## Output

torch.Size([1, 1, 2, 2])
Input Tensor:
tensor([[[[1., 2.],[3., 4.]]]])
Upsample by a scale_factor=3, mode='nearest':
tensor([[[[1., 1., 1., 2., 2., 2.],
[1., 1., 1., 2., 2., 2.],
[1., 1., 1., 2., 2., 2.],
[3., 3., 3., 4., 4., 4.],
[3., 3., 3., 4., 4., 4.],
[3., 3., 3., 4., 4., 4.]]]])
Upsample by a scale_factor=3, mode='bilinear':
tensor([[[[1.0000, 1.0000, 1.3333, 1.6667, 2.0000, 2.0000],
[1.0000, 1.0000, 1.3333, 1.6667, 2.0000, 2.0000],
[1.6667, 1.6667, 2.0000, 2.3333, 2.6667, 2.6667],
[2.3333, 2.3333, 2.6667, 3.0000, 3.3333, 3.3333],
[3.0000, 3.0000, 3.3333, 3.6667, 4.0000, 4.0000],
[3.0000, 3.0000, 3.3333, 3.6667, 4.0000, 4.0000]]]])
Upsample by a scale_factor=3, mode='bicubic':
tensor([[[[0.6667, 0.7778, 1.0926, 1.4630, 1.7778, 1.8889],
[0.8889, 1.0000, 1.3148, 1.6852, 2.0000, 2.1111],
[1.5185, 1.6296, 1.9444, 2.3148, 2.6296, 2.7407],
[2.2593, 2.3704, 2.6852, 3.0556, 3.3704, 3.4815],
[2.8889, 3.0000, 3.3148, 3.6852, 4.0000, 4.1111],
[3.1111, 3.2222, 3.5370, 3.9074, 4.2222, 4.3333]]]])

Note the differences between output tensors with different scale_factors and modes.

## Example 3

In this program, we upsample a 5D (Volumetric) tensor with different scale_factors and modes.

# Python program to upsample a 5D (Volumetric) tensor
# on 5D (Volumetric) tensor we can apply mode='nearest' and 'trilinear'

import torch

# define a tensor and view as a 5D tensor
input = torch.tensor([[1., 2.],[3., 4.]]).view(1,1,1,2,2)
print(input.size())
print("Input Tensor:\n", input)

# use mode='nearest', factor=2
upsample_nearest = torch.nn.Upsample(scale_factor=2, mode='nearest')
output_nearest = upsample_nearest(input)
print("Upsample by a scale_factor=2, mode='nearest'\n",
output_nearest)

# use mode='nearest', factor=3
upsample_nearest = torch.nn.Upsample(scale_factor=3,
mode='nearest')
output_nearest = upsample_nearest(input)
print("Upsample by a scale_factor=3, mode='nearest'\n",
output_nearest)

# use mode='trilinear'
upsample_trilinear = torch.nn.Upsample(scale_factor=2,
mode='trilinear')
output_trilinear = upsample_trilinear(input)
print("Upsample by a scale_factor=2, mode='trilinear':\n",
output_trilinear)

## Output

torch.Size([1, 1, 1, 2, 2])
Input Tensor:
tensor([[[[[1., 2.],[3., 4.]]]]])
Upsample by a scale_factor=2, mode='nearest'
tensor([[[[[1., 1., 2., 2.],
[1., 1., 2., 2.],
[3., 3., 4., 4.],
[3., 3., 4., 4.]],
[[1., 1., 2., 2.],
[1., 1., 2., 2.],
[3., 3., 4., 4.],
[3., 3., 4., 4.]]]]])
Upsample by a scale_factor=3, mode='nearest'
tensor([[[[[1., 1., 1., 2., 2., 2.],
[1., 1., 1., 2., 2., 2.],
[1., 1., 1., 2., 2., 2.],
[3., 3., 3., 4., 4., 4.],
[3., 3., 3., 4., 4., 4.],
[3., 3., 3., 4., 4., 4.]],
[[1., 1., 1., 2., 2., 2.],
[1., 1., 1., 2., 2., 2.],
[1., 1., 1., 2., 2., 2.],
[3., 3., 3., 4., 4., 4.],
[3., 3., 3., 4., 4., 4.],
[3., 3., 3., 4., 4., 4.]],
[[1., 1., 1., 2., 2., 2.],
[1., 1., 1., 2., 2., 2.],
[1., 1., 1., 2., 2., 2.],
[3., 3., 3., 4., 4., 4.],
[3., 3., 3., 4., 4., 4.],
[3., 3., 3., 4., 4., 4.]]]]])
Upsample by a scale_factor=2, mode='trilinear':
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]],
[[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]]]]])
Updated on 20-Jan-2022 08:28:44