torch.nn.AvgPool2d( kernel_size , stride=None , padding=0 , ceil_mode=False , count_include_pad=True , divisor_override=None )
功能:在由多个平面组成的输入信号上应用2D平均池化操作,具体计算公式如下:
o u t ( N i , C i , h , w ) = 1 k H ∗ k W ∑ m = 0 k H − 1 ∑ m = 0 k H − 1 i n p u t ( N i , C i , s t r i d e [ 0 ] × h + m , s t r i d e [ 1 ] × w + n ) 假设输入尺寸是 ( N , C , H , W ) , 输出尺寸是 ( N , C , H o u t , W o u t ) , 池化核尺寸是 ( k H , k W ) out(N_i,C_i,h,w)=\frac{1}{kH*kW}\sum^{kH-1}_{m=0}\sum^{kH-1}_{m=0}input(N_i,C_i,stride[0]\times h+m,stride[1]\times w+n)\\ 假设输入尺寸是(N,C,H,W),输出尺寸是(N,C,H_{out},W_{out}),池化核尺寸是(kH,kW) out(Ni,Ci,h,w)=kH∗kW1m=0∑kH−1m=0∑kH−1input(Ni,Ci,stride[0]×h+m,stride[1]×w+n)假设输入尺寸是(N,C,H,W),输出尺寸是(N,C,Hout,Wout),池化核尺寸是(kH,kW)
如果padding
非零,则会在输入图像的四周隐式地填充0,可以通过指定参数count_include_pad
来确定是否将该0纳入池化计算过程。
输入:
kernel_size
:池化核的尺寸大小stride
:窗口的移动步幅,默认与kernel_size
大小一致padding
:在两侧的零填充宽度大小ceil_mode
:设为True
时,在计算输出形状的过程中采用向上取整的操作,否则,采用向下取整count_include_pad
:布尔类型,当为True
时,将在平均池化计算中包括零填充,否则,不包括零填充divisor_override
:如果被指定,则除数会被代替成divisor_override
。换句话说,如果不指定该变量,则平均池化的计算过程其实是在一个池化核内,将元素相加再除以池化核的大小,也就是divisor_override
默认为池化核的高×宽;如果该变量被指定,则池化过程为将池化核内元素相加再除以divisor_override
。注意:
参数的kernel_size
、stride
、padding
可以是:
输出形状的计算公式为:
H o u t = ⌊ H i n + 2 × p a d d i n g [ 0 ] − k e r n e l _ s i z e [ 0 ] s t r i d e [ 0 ] + 1 ⌋ W o u t = ⌊ W i n + 2 × p a d d i n g [ 1 ] − k e r n e l _ s i z e [ 1 ] s t r i d e [ 1 ] + 1 ⌋ 其中, H i n 和 W i n 为输入的高和宽,默认向下取整 ( 可指定参数来修改取整规则 ) H_{out}=\lfloor{\frac{H_{in}+2\times padding[0]-kernel\_size[0]}{stride[0]}+1}\rfloor\\ W_{out}=\lfloor{\frac{W_{in}+2\times padding[1]-kernel\_size[1]}{stride[1]}+1}\rfloor\\ 其中,H_{in}和W_{in}为输入的高和宽,默认向下取整(可指定参数来修改取整规则) Hout=⌊stride[0]Hin+2×padding[0]−kernel_size[0]+1⌋Wout=⌊stride[1]Win+2×padding[1]−kernel_size[1]+1⌋其中,Hin和Win为输入的高和宽,默认向下取整(可指定参数来修改取整规则)
padding
大小要小于池化核的尺寸大小
一般用法
import torch
from torch import nn
img=torch.arange(16).reshape(1,1,4,4)
# 池化核和池化步长均为2
pool=nn.AvgPool2d(2,stride=2)
img_2=pool(img)
print(img)
print(img_2)
输出
# 原图像
tensor([[[[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15]]]])
# 池化后图像,长宽均为原来的一半
tensor([[[[ 2, 4],
[10, 12]]]])
ceil_mode设为True与Fasle的区别
import torch
from torch import nn
img=torch.arange(20,dtype=torch.float).reshape(1,1,4,5)
pool_f=nn.AvgPool2d(2,stride=2,padding=0,ceil_mode=False)
pool_t=nn.AvgPool2d(2,stride=2,padding=0,ceil_mode=True)
img_2=pool_f(img)
img_3=pool_t(img)
print(img)
print(img_2)
print(img_3)
输出
# 原图像
tensor([[[[ 0., 1., 2., 3., 4.],
[ 5., 6., 7., 8., 9.],
[10., 11., 12., 13., 14.],
[15., 16., 17., 18., 19.]]]])
# 默认情况,ceil_mode为False
tensor([[[[ 3., 5.],
[13., 15.]]]])
# ceil_mode为True
tensor([[[[ 3.0000, 5.0000, 6.5000],
[13.0000, 15.0000, 16.5000]]]])
# 由于5不能被2整除,所以一个下取整,一个上取整
padding设与不设的区别
import torch
from torch import nn
img=torch.arange(16,dtype=torch.float).reshape(1,1,4,4)
pool_t=nn.AvgPool2d(2,stride=2,padding=1)
pool_f=nn.AvgPool2d(2,stride=2)
img_2=pool_t(img)
img_3=pool_f(img)
print(img)
print(img_2)
print(img_3)
输出
# 原图
tensor([[[[ 0., 1., 2., 3.],
[ 4., 5., 6., 7.],
[ 8., 9., 10., 11.],
[12., 13., 14., 15.]]]])
# 填充宽度为1,默认填充的0会被用于池化计算
tensor([[[[0.0000, 0.7500, 0.7500],
[3.0000, 7.5000, 4.5000],
[3.0000, 6.7500, 3.7500]]]])
# 未填充结果
tensor([[[[ 2.5000, 4.5000],
[10.5000, 12.5000]]]])
# 填充后的图像经过池化运算得到的图像尺寸可以用上面的公式计算出来
count_include_pad设为True与False的区别
import torch
from torch import nn
img=torch.arange(16,dtype=torch.float).reshape(1,1,4,4)
pool_t=nn.AvgPool2d(2,stride=2,padding=1,count_include_pad=True)
pool_f=nn.AvgPool2d(2,stride=2,padding=1,count_include_pad=False)
img_2=pool_t(img)
img_3=pool_f(img)
print(img)
print(img_2)
print(img_3)
输出
# 原图
tensor([[[[ 0., 1., 2., 3.],
[ 4., 5., 6., 7.],
[ 8., 9., 10., 11.],
[12., 13., 14., 15.]]]])
# 填充宽度为1,count_include_pad为True(默认情况)
# 填充的0被用于池化计算
tensor([[[[0.0000, 0.7500, 0.7500],
[3.0000, 7.5000, 4.5000],
[3.0000, 6.7500, 3.7500]]]])
# 填充的0未被用于池化计算
tensor([[[[ 0.0000, 1.5000, 3.0000],
[ 6.0000, 7.5000, 9.0000],
[12.0000, 13.5000, 15.0000]]]])
divisor_override设与未设的区别
import torch
from torch import nn
img=torch.arange(16,dtype=torch.float).reshape(1,1,4,4)
pool_1=nn.AvgPool2d(2,stride=2)
pool_d1=nn.AvgPool2d(2,stride=2,divisor_override=2)
pool_d2=nn.AvgPool2d(2,stride=2,divisor_override=3)
img_1=pool_1(img)
img_2=pool_d1(img)
img_3=pool_d2(img)
print(img)
print(img_1)
print(img_2)
print(img_3)
输出
# 原图像
tensor([[[[ 0., 1., 2., 3.],
[ 4., 5., 6., 7.],
[ 8., 9., 10., 11.],
[12., 13., 14., 15.]]]])
# 未设置divisor_override,此时是普通的平均池化操作
tensor([[[[ 2.5000, 4.5000],
[10.5000, 12.5000]]]])
# divisor_override设置为2,以左上角四个元素为例
# 池化后第一个元素为原图左上角四个元素相加除以2
tensor([[[[ 5., 9.],
[21., 25.]]]])
# divisor_override设置为3,
# 即四个元素相加除以3
tensor([[[[ 3.3333, 6.0000],
[14.0000, 16.6667]]]])
torch.nn.AvgPool2d():https://pytorch.org/docs/stable/generated/torch.nn.AvgPool2d.html?highlight=avgpool2d#torch.nn.AvgPool2d