捷徑

Unfold

class torch.nn.Unfold(kernel_size, dilation=1, padding=0, stride=1)[source][來源]

從批次輸入 Tensor 中提取滑動局部區塊。

考量一個批次的 input 張量,其形狀為 (N,C,)(N, C, *),其中 NN 是批次維度,CC 是通道維度,而 * 代表任意的空間維度。 這個操作會將 input 空間維度內每個滑動的 kernel_size 大小的區塊,扁平化成一個 3D output 張量的列(也就是最後一個維度),其形狀為 (N,C×(kernel_size),L)(N, C \times \prod(\text{kernel\_size}), L),其中 C×(kernel_size)C \times \prod(\text{kernel\_size}) 是每個區塊內值的總數(一個區塊有 (kernel_size)\prod(\text{kernel\_size}) 個空間位置,每個位置包含一個 CC-通道的向量),而 LL 是這種區塊的總數。

L=dspatial_size[d]+2×padding[d]dilation[d]×(kernel_size[d]1)1stride[d]+1,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,

其中 spatial_size\text{spatial\_size} 是由 input 的空間維度構成的(如上面的 * 所示),而 dd 則遍歷所有空間維度。

因此,索引 output 的最後一個維度(欄維度)會得到特定區塊內的所有值。

paddingstridedilation 參數指定如何檢索滑動區塊。

  • stride 控制滑動區塊的步幅。

  • padding 控制在重塑形狀之前,在每個維度的 padding 個點上,在兩側添加的隱式零填充量。

  • dilation 控制 kernel 點之間的間距;也稱為 à trous 演算法。 雖然很難描述,但這個 連結 有一個很好的視覺化展示了 dilation 的作用。

參數
  • kernel_size (inttuple) – 滑動區塊的大小

  • dilation (inttuple, optional) – 一個控制鄰域內元素步幅的參數。預設值:1

  • padding (inttuple, optional) – 要添加到輸入兩側的隱式零填充。預設值:0

  • stride (inttuple, optional) – 輸入空間維度中滑動區塊的步幅。預設值:1

  • 如果 kernel_sizedilationpaddingstride 是一個 int 或長度為 1 的 tuple,則它們的值將在所有空間維度上複製。

  • 在兩個輸入空間維度的情況下,此操作有時稱為 im2col

注意

Fold 通過對所有包含區塊中的所有值求和來計算結果大張量中的每個組合值。Unfold 通過從大張量複製來提取本地區塊中的值。 因此,如果區塊重疊,它們彼此不是反函數。

通常,folding 和 unfolding 操作的相關方式如下。 考慮使用相同參數建立的 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 的形狀和 dtype 的張量

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

divisor 張量不包含零元素時,foldunfold 操作是彼此的反函數(最多到一個常數除數)。

警告

目前,僅支援 4-D 輸入張量(批次化圖像類張量)。

形狀
  • 輸入: (N,C,)(N, C, *)

  • 輸出:如同上述說明的 (N,C×(kernel_size),L)(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)

文件

存取 PyTorch 的完整開發者文件

檢視文件

教學

取得初學者和進階開發者的深入教學

檢視教學

資源

尋找開發資源並獲得您的問題解答

檢視資源