我已经看过了official doc。我很难理解这个函数是用来做什么的,它是如何工作的。有人能用外行的话解释一下吗?
5lwkijsr1#
unfold将Tensor想象为具有重复的值的列/行的较长Tensor,这些值"折叠"在彼此的顶部,然后"展开":
unfold
size
step
例如,对于2x5Tensor,用step=1展开它,并在dim=1上修补size=2:
step=1
dim=1
size=2
x = torch.tensor([[1,2,3,4,5], [6,7,8,9,10]])
>>> x.unfold(1,2,1) tensor([[[ 1, 2], [ 2, 3], [ 3, 4], [ 4, 5]], [[ 6, 7], [ 7, 8], [ 8, 9], [ 9, 10]]])
fold大致与此操作相反,但在输出中对"重叠"值求和。
fold
s5a0g9ez2#
unfold和fold用于简化“滑动窗口”操作(如卷积)。假设您要将函数foo应用于特征Map/图像中的每个5x5窗口:
foo
5x5
from torch.nn import functional as f windows = f.unfold(x, kernel_size=5)
现在windows有了批处理的size-(55x.size(1))-num_windows,您可以在windows上应用foo:
windows
x.size(1)
processed = foo(windows)
现在您需要将processed“折叠”回x的原始大小:
processed
x
out = f.fold(processed, x.shape[-2:], kernel_size=5)
您需要注意padding和kernel_size,它们可能会影响您将processed“折叠”回x大小的能力。此外,fold * 对重叠元素求和 *,因此您可能需要将fold的输出除以补丁大小。请注意,torch.unfold执行的操作与nn.Unfold不同。有关详细信息,请参见this thread。
padding
kernel_size
torch.unfold
nn.Unfold
6gpjuf903#
x = torch.arange(1, 9).float() print(x) # dimension, size, step print(x.unfold(0, 2, 1)) print(x.unfold(0, 3, 2))
输出:
tensor([1., 2., 3., 4., 5., 6., 7., 8.]) tensor([[1., 2.], [2., 3.], [3., 4.], [4., 5.], [5., 6.], [6., 7.], [7., 8.]]) tensor([[1., 2., 3.], [3., 4., 5.], [5., 6., 7.]])
一个二个一个一个
mcdcgff04#
由于4-DTensor没有答案,并且nn.functional. unflown()只接受4-DTensor,我将对此进行解释。假设输入Tensor的形状为(batch_size, channels, height, width),我举了一个例子,其中batch_size = 1, channels = 2, height = 3, width = 3。
(batch_size, channels, height, width)
batch_size = 1, channels = 2, height = 3, width = 3
kernel_size = 2,它只是一个2x2内核
kernel_size = 2
4条答案
按热度按时间5lwkijsr1#
unfold
将Tensor想象为具有重复的值的列/行的较长Tensor,这些值"折叠"在彼此的顶部,然后"展开":size
确定折叠的大小step
确定折叠的频率例如,对于2x5Tensor,用
step=1
展开它,并在dim=1
上修补size=2
:fold
大致与此操作相反,但在输出中对"重叠"值求和。s5a0g9ez2#
unfold
和fold
用于简化“滑动窗口”操作(如卷积)。假设您要将函数foo
应用于特征Map/图像中的每个5x5
窗口:现在
windows
有了批处理的size
-(55x.size(1)
)-num_windows,您可以在windows
上应用foo
:现在您需要将
processed
“折叠”回x
的原始大小:您需要注意
padding
和kernel_size
,它们可能会影响您将processed
“折叠”回x
大小的能力。此外,fold
* 对重叠元素求和 *,因此您可能需要将fold
的输出除以补丁大小。请注意,
torch.unfold
执行的操作与nn.Unfold
不同。有关详细信息,请参见this thread。6gpjuf903#
一维展开很容易:
输出:
二维展开(也称为 * 修补 *)
一个二个一个一个
mcdcgff04#
由于4-DTensor没有答案,并且nn.functional. unflown()只接受4-DTensor,我将对此进行解释。
假设输入Tensor的形状为
(batch_size, channels, height, width)
,我举了一个例子,其中batch_size = 1, channels = 2, height = 3, width = 3
。kernel_size = 2
,它只是一个2x2内核