pytorch中的unfold

torch.nn.functional.unfold

如果将卷积看作 滑动窗口+求和 的话,那么这个方法就是只有 滑动窗口 这一步了。

如图,a.unfold(0, 2, 1),表示在a的第0维以卷积核长度为2步长为1的方式开始取值。a的维度为(5,5),其第0维相当于行,所以图中是竖着取值的,最终得到维度为(4,5,2)的结果,因为a的0维只有5个数,而你要以步长为1两个两个地取,故只能取出4对,第二维中的5表示有5行,第三维中的2表示取出来的两个对。

假如要对二维图像进行卷积,卷积核要是二维的怎么做呢?则可以连续使用两次unfold(先对行卷,再对列卷)

注意两次unfold所在的维度是不同的,得到的结果就是维度为(4,4,2,2)的结果。

torch.nn.Unfold

nn包中的Unfold有点不同,它可以指定一个多维的卷积核,直观感觉上,它应该是直接将特征图中的每个像素点扩展成卷积核的感受野部分,比如直接将(2,3,3)的图像升维成(2,2,2,2,2)这种(第二维为channel,使用2*2的卷积核),但实际上并不是这样。

输入是(2,3,3)得到的却是一个(8,4)的矩阵。

其实这里除了滑动窗口外它还多做了两步

  1. 将滑动窗口得到的结果展平成1维数组
  2. 将多个channel得到的展平后结果进行拼接(想象n个channel上有n个窗口同时滑动,每次都将所有的滑动窗口拼接成一个长的一维数组)

所以结果维度中的8表示的是C * kernel_w * kernel_h(即文档中的 C*Π(kernel_size)),这是因为它表示的是将kernel得到的结果展平并拼接所有channel的结果,4则表示单个channel中可以卷4次。

要想得到预想的结果,可以直接再reshape成(2,2,2,2,2)就行。

另,Unfold的第二个参数 dilation 表示卷积空洞数量,想想空洞卷积是怎样的。

Leave a Comment