展开

classtorch.nn.Unfold(kernel_size, dilation=1, padding=0, stride=1)[源代码]

从批处理输入张量中提取滑动局部块。

考虑一个形状为$(N, C, *)$的批量input张量,其中$N$是批处理维度,$C$是通道维度,而$*$表示任意空间维度。此操作将input张量的空间维度中每个大小为kernel_size的滑动块展平成一个3-D output张量,其形状为$(N, C \times \prod(\text{kernel\_size}), L)$。其中$C \times \prod(\text{kernel\_size})$表示每个块内的总值数,即每个块有$\prod(\text{kernel\_size})$个空间位置,每个位置包含一个具有$C$通道的向量。而$L$表示这样的块总数。

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

其中 $\text{spatial\_size}$input 的空间维度(上面的$*$)决定,而$d$ 跨越所有空间维度。

因此,对output的最后一维(即列维度)进行索引,可以获取某个块内的所有值。

paddingstridedilation 参数定义了如何获取滑动块。

  • stride 控制滑动块的步长。

  • padding 控制每个维度在重塑之前每侧隐式填充的零的点数。

  • dilation 控制核点之间的间距,也称为 à trous 算法。它更难描述,但这个 链接 提供了一个很好的可视化来展示 dilation 的作用。

参数
  • kernel_size (inttuple) – 滑动窗口的大小

  • dilation (int元组, 可选) – 控制邻域内元素步长的参数。默认值:1

  • padding (int元组, 可选) – 输入两侧隐式添加的零填充。默认值:0

  • stride (int元组, 可选) – 指定输入空间维度中滑动块的步长。默认值:1

  • 如果 kernel_sizedilationpaddingstride 是一个整数或包含单个元素的元组,那么它们的值将在所有空间维度上重复。

  • 当有两个输入空间维度时,此操作有时被称为im2col

注意

Fold 通过将所有包含块中的值相加来计算结果大张量中每个组合的值。Unfold 则从大张量中复制值以提取局部块中的内容。因此,如果这些块有重叠,则它们不是彼此的逆操作。

一般来说,折叠和展开操作之间的关系如下。考虑使用相同参数创建的FoldUnfold 实例:

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

对于任何受支持的 input 张量,下列等式成立:

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

其中 divisor 是一个张量,仅依赖于 input 的形状和数据类型:

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

divisor张量中不含零元素时,foldunfold操作互为逆运算(不考虑常数除数)。

警告

目前仅支持4维输入张量(批处理后的图像-like张量)。

形状:
  • 输入: $(N, C, *)$

  • 输出为: $(N, C \times \prod(\text{kernel\_size}), L)$,如上所述

示例:

>>> unfold = nn.Unfold(kernel_size=(2, 3))
>>> input = torch.randn(2, 5, 3, 4)
>>> output = unfold(input)
>>> # each patch contains 30 values (2x3=6 vectors, each of 5 channels)
>>> # 4 blocks (2x3 kernels) in total in the 3x4 input
>>> output.size()
torch.Size([2, 30, 4])

>>> # Convolution is equivalent with Unfold + Matrix Multiplication + Fold (or view to output shape)
>>> inp = torch.randn(1, 3, 10, 12)
>>> w = torch.randn(2, 3, 4, 5)
>>> inp_unf = torch.nn.functional.unfold(inp, (4, 5))
>>> out_unf = inp_unf.transpose(1, 2).matmul(w.view(w.size(0), -1).t()).transpose(1, 2)
>>> out = torch.nn.functional.fold(out_unf, (7, 8), (1, 1))
>>> # or equivalently (and avoiding a copy),
>>> # out = out_unf.view(1, 2, 7, 8)
>>> (torch.nn.functional.conv2d(inp, w) - out).abs().max()
tensor(1.9073e-06)
本页目录