oneflow.nn.Fold

class oneflow.nn.Fold(output_size, kernel_size, dilation=1, padding=0, stride=1)

The documentation is referenced from: https://pytorch.org/docs/1.10/generated/torch.nn.Fold.html.

Combines an array of sliding local blocks into a large containing tensor, it also called col2img

Consider a batched input tensor containing sliding local blocks, e.g., patches of images, of shape \((N, C \times \prod(\text{kernel_size}), L)\), where \(N\) is batch dimension, \(C \times \prod(\text{kernel_size})\) is the number of values within a block (a block has \(\prod(\text{kernel_size})\) spatial locations each containing a \(C\)-channeled vector), and \(L\) is the total number of blocks. (This is exactly the same specification as the output shape of Unfold.) This operation combines these local blocks into the large output tensor of shape \((N, C, \text{output_size}[0], \text{output_size}[1], \dots)\) by summing the overlapping values. Similar to Unfold, the arguments must satisfy

\[L = \prod_d \left\lfloor\frac{\text{output_size}[d] + 2 \times \text{padding}[d] % - \text{dilation}[d] \times (\text{kernel_size}[d] - 1) - 1}{\text{stride}[d]} + 1\right\rfloor,\]

where \(d\) is over all spatial dimensions.

  • output_size describes the spatial shape of the large containing tensor of the sliding local blocks. It is useful to resolve the ambiguity when multiple input shapes map to same number of sliding blocks, e.g., with stride > 0.

The padding, stride and dilation arguments specify how the sliding blocks are retrieved.

  • stride controls the stride for the sliding blocks.

  • padding controls the amount of implicit zero-paddings on both sides for padding number of points for each dimension before reshaping.

  • dilation controls the spacing between the kernel points; also known as the à trous algorithm.

Parameters
  • output_size (int or tuple) – the shape of the spatial dimensions of the output (i.e., output.sizes()[2:])

  • kernel_size (int or tuple) – the size of the sliding blocks

  • stride (int or tuple) – the stride of the sliding blocks in the input spatial dimensions. Default: 1

  • padding (int or tuple, optional) – implicit zero padding to be added on both sides of input. Default: 0

  • dilation (int or tuple, optional) – a parameter that controls the stride of elements within the neighborhood. Default: 1

  • If output_size, kernel_size, dilation, padding or stride is an int or a tuple of length 1 then their values will be replicated across all spatial dimensions.

  • For the case of two output spatial dimensions this operation is sometimes called col2im.

Note

Fold calculates each combined value in the resulting large tensor by summing all values from all containing blocks. Unfold extracts the values in the local blocks by copying from the large tensor. So, if the blocks overlap, they are not inverses of each other.

In general, folding and unfolding operations are related as follows. Consider Fold and Unfold instances created with the same parameters:

>>> fold_params = dict(kernel_size=..., dilation=..., padding=..., stride=...)
>>> fold = nn.Fold(output_size=..., **fold_params)
>>> unfold = nn.Unfold(**fold_params)

Then for any (supported) input tensor the following equality holds:

fold(unfold(input)) == divisor * input

where divisor is a tensor that depends only on the shape and dtype of the input:

>>> input_ones = oneflow.ones(input.shape, dtype=input.dtype)
>>> divisor = fold(unfold(input_ones))

When the divisor tensor contains no zero elements, then fold and unfold operations are inverses of each other (up to constant divisor).

Warning

Currently, only unbatched (3D) or batched (4D) image-like output tensors are supported.

Shape:
  • Input: \((N, C \times \prod(\text{kernel_size}), L)\) or \((C \times \prod(\text{kernel_size}), L)\)

  • Output: \((N, C, \text{output_size}[0], \text{output_size}[1], \dots)\) or \((C, \text{output_size}[0], \text{output_size}[1], \dots)\) as described above

For example:

>>> import oneflow as flow
>>> import numpy as np

>>> x_tensor = flow.Tensor(np.random.randn(1, 9, 16))
>>> fold = flow.nn.Fold(output_size=(4, 4), kernel_size=3, padding=1)
>>> out = fold(x_tensor)
>>> out.shape
oneflow.Size([1, 1, 4, 4])