nn.AdaptiveAvgPool2d(output_size)
函数作用:自适应进行平均池化。不用管输入、stride、padding,函数参数只有输出大小,其他的这个函数帮你搞定。
问题就是,我想知道他是咋搞定的?
先把例子摆上来:
input = torch.randn(20, 3, 10, 9)
m = nn.AdaptiveAvgPool2d((5, 7))
output = m(input)
(N, C, H_in, W_in)
或 (C, H_in W_in)
。这里的 N 表示batch_size,C 表示通道数量。 (N, C, S_0, S_1)
或 (C, S_0, S_1)
,这里 C 不会改变。假设输入是input = torch.randn(20, 3, 10, 9)
他的参数有三种写法:
m = nn.AdaptiveAvgPool2d((5, 7))
m = nn.AdaptiveAvgPool2d(7)
m = nn.AdaptiveAvgPool2d((None, 7))
o u t p u t = i n p u t + 2 ∗ p a d d i n g − k e r n e l s t r i d e + 1 output = \frac{input+2*padding -kernel}{stride}+1 output=strideinput+2∗padding−kernel+1
其中 p a d d i n g = 0 、 s t r i d e = i n p u t o u t p u t , k e r n e l = i n p u t − ( o u t p u t − 1 ) ∗ s t r i d e padding=0、stride=\frac{input}{output},kernel=input-(output-1)*stride padding=0、stride=outputinput,kernel=input−(output−1)∗stride
举例:input size = 6*6,output = 2*3
计算:padding = 0、stride为3和2、kernel size = 3*2
代码验证:
m = nn.AdaptiveAvgPool2d((2, 3))
temp = torch.tensor([1.0,2,3,4,5,6,7,8,9,0,
1.0,2,3,4,5,6,7,8,9,0,
1.0,2,3,4,5,6,7,8,9,0,
1.0,2,3,4,5,6])
input = temp.reshape(1,6,6)
print("input1")
print(input)
output = m(input)
print("output1")
print(output)
自适应公式是这样的:
i 从0开始:
K i = c e i l ( ( i + 1 ) ∗ i n p u t o u t p u t ) − f l o o r ( i ∗ i n p u t o u t p u t ) K_i=ceil((i+1)*\frac{input}{output})-floor(i*\frac{input}{output}) Ki=ceil((i+1)∗outputinput)−floor(i∗outputinput)
S i = f l o o r ( ( i + 1 ) ∗ i n p u t o u t p u t ) − f l o o r ( i ∗ i n p u t o u t p u t ) S_i=floor((i+1)*\frac{input}{output})-floor(i*\frac{input}{output}) Si=floor((i+1)∗outputinput)−floor(i∗outputinput)
上述公式由源码推导,实际代码中并没有去计算核大小和步长,因为核大小和步长是在不算变化的。
举例解释一波:
假设我们输入size是1维的14,我们想要的输出的size是4,
14/4=3.5
那么我们核大小就为向上取整为4,步长随之而变
输出的size改为3,
14/3=4.666
那么我们核大小就为向上取整为5,步长随之而变