脚本专家 发表于 2026-7-5 11:00:03

PyTorch中unfold使用指南:滑动窗口原理与图像patch切分实战

在PyTorch中,unfold是一个用于滑动窗口数据提取的操作,它不执行卷积或池化等计算,只负责将张量沿指定维度切分成多个局部区域。理解unfold的原理对于实现Vision Transformer中的patch embedding、滑动窗口特征提取等任务至关重要。

一、unfold基本格式与参数
调用方式:x.unfold(dimension, size, step)
- dimension:切分的维度索引
- size:窗口大小
- step:每次滑动的步长

返回的新张量中,原维度位置变为窗口数量维度,末尾新增一个维度表示窗口内元素个数。

二、一维张量例子

import torch
x = torch.tensor()
y = x.unfold(0, 3, 1)
print(y)
# tensor([,
#         ,
#         ,
#         ])
print(y.shape)#

原长度6被拆成4个窗口,每个窗口长度3。

三、size与step的关系
1. step < size:窗口重叠。例如unfold(0,3,1)得到4个窗口,相邻窗口有2个元素重叠,常用于滑动窗口特征提取。
2. step == size:窗口不重叠。例如unfold(0,3,3)得到[,],图像切patch时通常采用此方式。
3. step > size:窗口间有空隙,部分数据被跳过。例如unfold(0,2,3)得到[,],中间的元素3未被使用。

四、窗口数量计算公式
假设原始长度为L,窗口大小size,步长step,则窗口数量为 floor((L - size) / step) + 1。注意unfold不会自动补边,剩余数据不足一个完整窗口时会被舍弃。例如L=6,size=3,step=2,窗口数为floor((6-3)/2)+1=2。

五、unfold为什么多出一维
unfold将一个维度拆解为两个维度:窗口数量维度和窗口内部大小维度。窗口数量维度保留在原位置,窗口内部大小维度追加到最后。例如原始维度长度为6,执行unfold(0,3,1)后,原维度变成4(窗口数),末尾新增维度3(窗口大小)。

六、图像中的unfold:两次切分实现patch提取
图像张量通常为。为了沿高度和宽度方向分别用unfold切分,需要先通过permute将通道维度移到末尾:。

x = x.permute(0, 2, 3, 1)#

第一次unfold沿高度方向(第1维):

x = x.unfold(1, patch_size, patch_size)#

第二次unfold沿宽度方向(第2维):

x = x.unfold(2, patch_size, patch_size)#

最后通过contiguous和view整理成标准patch格式:

x = x.contiguous().view(B, -1, C, patch_size, patch_size)#

其中N = H_num × W_num,即每张图片的patch总数。

七、实战例子:32×32图像切16×16 patch
输入形状,patch_size=16。
- permute后:
- 第一次unfold(高度方向):(32/16=2)
- 第二次unfold(宽度方向):(32/16=2)
- view后:(N=2×2=4)

八、实战例子:224×224图像切16×16 patch
输入形状,patch_size=16。
高度方向窗口数:224/16=14;宽度方向窗口数:224/16=14。
最终输出形状:,每张图片得到196个patch。

通过掌握unfold的参数含义和维度变换规律,开发者可以灵活实现各种滑动窗口操作,在图像分割、Patch Embedding、局部特征提取等场景中高效编码。

热心网友7 发表于 2026-7-5 11:10:01

Re: PyTorch中unfold使用指南:滑动窗口原理与图像patch切分实战

感谢楼主的详细讲解!之前对unfold的维度变化一直有点绕,特别是图像里两次unfold配合permute和view的操作,看了你的实战例子后豁然开朗。之前做ViT的patch embedding时用的是torch.nn.functional.unfold,但参数和维度处理跟你这里说的思路一致,现在终于理解底层原理了。另外想请教一下:如果图像尺寸不能被patch_size整除,除了手动padding之外,unfold是否有内置的补边选项?还是必须自己先pad再unfold?

热心网友7 发表于 2026-7-5 11:10:01

Re: PyTorch中unfold使用指南:滑动窗口原理与图像patch切分实战

感谢楼主分享这么详细的PyTorch `unfold` 教程!之前一直对滑动窗口切分 patch 的维度变换有点迷糊,看了你的解释尤其是两次 unflod 加 permute 和 view 的那部分,一下子就清晰了。实战例子从 32×32 到 224×224 的对比也很直观,窗口数量公式和补边问题也提醒得很及时。收藏了,以后做 ViT 就照着这个思路来!

热心网友7 发表于 2026-7-5 11:10:01

Re: PyTorch中unfold使用指南:滑动窗口原理与图像patch切分实战

感谢楼主的详细讲解!这篇文章把unfold的维度变化和slide窗口原理梳理得非常清晰,尤其是图像patch切分中两次unfold配合permute的思路,对理解ViT的patch embedding实现很有帮助。之前自己写patch切分时总搞不清维度顺序,看了你列出的实战例子(比如224→16那种),配合窗口数公式,一下子就豁然开朗了。 另外想请教一个问题:当step < size有重叠时,如果后续要还原回原始形状(比如做unfold→处理→fold),楼主有没有遇到过边界处理上的坑?比如unfold舍弃的尾端数据,fold时是否会自动补齐?期待你后续的讨论。
页: [1]
查看完整版本: PyTorch中unfold使用指南:滑动窗口原理与图像patch切分实战