Unfold¶
- class torch.nn.Unfold(kernel_size, dilation=1, padding=0, stride=1)[原始碼][原始碼]¶
從批次輸入的張量中提取滑動區域性塊。
考慮一個批次輸入的張量,形狀為 ,其中 是批處理維度, 是通道維度, 代表任意空間維度。此操作將
input張量的空間維度中的每個kernel_size大小的滑動塊展平為一個 3-Doutput張量的列(即最後一個維度),形狀為 ,其中 是每個塊內的總值數(一個塊有 個空間位置,每個位置包含一個 通道向量),L 是此類塊的總數其中 由
input的空間維度組成(即上面的 ),d 遍歷所有空間維度。因此,在
output張量的最後一個維度(列維度)進行索引會給出特定塊內的所有值。padding、stride和dilation引數指定了如何檢索滑動塊。stride控制滑動塊的步長。padding控制在重塑之前,在每個維度的padding個點兩端新增的隱式零填充量。dilation控制核點之間的間距;也稱為 à trous 演算法。它比較難描述,但此連結有一個很好的視覺化說明dilation的作用。
- 引數
如果
kernel_size、dilation、padding或stride是一個 int 或長度為 1 的 tuple,它們的值將被複制到所有空間維度。對於兩個輸入空間維度的情況,此操作有時稱為
im2col。
注意
Fold透過對所有包含塊中的所有值求和來計算結果大張量中的每個組合值。Unfold透過從大張量複製來提取區域性塊中的值。因此,如果塊重疊,它們就不是彼此的逆操作。一般來說,摺疊和展開操作的關係如下。考慮使用相同引數建立的
Fold和Unfold例項>>> 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張量不包含零元素時,fold和unfold操作互為逆操作(僅相差一個常數因子)。警告
目前,僅支援 4 維輸入張量(批次影像類張量)。
- 形狀
輸入:
輸出: 如上所述
示例
>>> 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)