Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/fortran/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Pytorch 什么是称为';面积';用来做什么?_Pytorch_Interpolation - Fatal编程技术网

Pytorch 什么是称为';面积';用来做什么?

Pytorch 什么是称为';面积';用来做什么?,pytorch,interpolation,Pytorch,Interpolation,PyTorch函数torch.nn.functional.interpolate包含几种上采样模式,例如:最近的,线性,双线性,双三次,三线性,区域 area上采样模式用于什么?查看源代码,它显示area插值相当于通过调整张量大小。有关自适应平均池的说明,请参阅。因此,区域插值比上采样更适用于下采样。正如jodag所说,它是使用自适应平均池调整大小。虽然链接中的答案旨在解释什么是自适应平均池,但我发现解释有点模糊 TL;DRtorch.nn.functional.interpolate的区域模式

PyTorch函数
torch.nn.functional.interpolate
包含几种上采样模式,例如:
最近的
线性
双线性
双三次
三线性
区域


area
上采样模式用于什么?

查看源代码,它显示
area
插值相当于通过调整张量大小。有关自适应平均池的说明,请参阅。因此,
区域
插值比上采样更适用于下采样。

正如jodag所说,它是使用自适应平均池调整大小。虽然链接中的答案旨在解释什么是自适应平均池,但我发现解释有点模糊

TL;DR
torch.nn.functional.interpolate的
区域
模式
可能是人们想要减少图像采样时最直观的思考方式之一。 您可以将其视为对原始图像应用平均低通滤波器(LPF),然后进行采样。采样前应用LPF,以防止下采样图像中潜在的混叠混叠会在缩小的图像中产生莫尔条纹。 它可能被称为“面积”,因为它(大致)在平均输入像素时保留了输入和输出形状之间的面积比。更具体地说,输出图像中的每个像素将是输入图像中各个区域的平均值,其中该区域的
1/面积
将大致为输出图像的面积和输入图像的面积之间的比率

此外,具有
模式='area'
插值
函数调用源函数
adaptie_avg_pool2d
(用C++实现),该函数为输出张量中的每个像素分配输入计算区域内所有像素强度的平均值。该区域是按像素计算的,不同像素的大小可能不同。它的计算方法是将输出像素的高度和宽度乘以输入和输出(按该顺序)高度和宽度(分别)之间的比率,然后取一次结果值的
楼层
(用于区域的起始索引)和
单元
(用于区域的结束索引)

下面是对
nn.AdaptiveAvgPool2d
中发生的情况的深入分析:

首先,如上所述,您可以在此处找到自适应平均池的源代码(在C++中): 看看魔术发生的函数(或者至少是单帧在CPU上的魔术),
静态void adaptive\u avg\u pool2d\u single\u out\u frame
,我们有5个嵌套循环,在通道尺寸、宽度、高度上运行,在第三个循环的主体内发生魔术:

首先计算输入图像中的区域,该区域用于计算当前像素的值(回想一下,我们在输出中的所有像素上都有宽度和高度循环)。 这是怎么做到的

使用高度和宽度的开始和结束索引的简单计算如下:
地板((输入高度/输出高度)*当前输出像素高度)
用于开始和
ceil((输入高度/输出高度)*(当前输出像素高度+1))
,同样用于宽度

然后,所做的只是简单地平均该区域和当前通道中所有像素的强度,并将结果放入当前输出像素中

我编写了一个简单的Python代码段,它以同样的方式(循环,朴素)做同样的事情,并产生相同的结果。它采用张量
a
,并使用自适应平均池来调整
a
的大小,以两种方式来塑造
输出_形状
——一种是使用内置的
nn.AdaptiveAvgPool2d
,另一种是将源函数在C++中翻译成Python:
静态void adaptive_avg_pool2d_single_out_frame
。内置函数的结果保存在
b
中,我的翻译保存在
b_hat
中。您可以看到结果是等效的(您可以进一步使用空间形状并对此进行验证):


欢迎来到堆栈溢出!
import torch
from math import floor, ceil
from torch import nn
a = torch.randn(1, 3, 15, 17)
out_shape = (10, 11)
b = nn.AdaptiveAvgPool2d(out_shape)(a)

b_hat = torch.zeros(b.shape)
for d in range(a.shape[1]):
    for w in range(b_hat.shape[3]):
        for h in range(b_hat.shape[2]):
            startW = floor(w * a.shape[3] / out_shape[1])
            endW = ceil((w + 1) * a.shape[3] / out_shape[1])

            startH = floor(h * a.shape[2] / out_shape[0])
            endH = ceil((h + 1) * a.shape[2] / out_shape[0])
            
            b_hat[0, d, h, w] = torch.mean(a[0, d, startH: endH, startW: endW])

'''
Prints Mean Squared Error =  0 (or a very small number, due to precision error)
as both outputs are the same, proof of output equivalence:
'''
print(nn.MSELoss()(b_hat, b))