一、MaxPooling前向传播与反向传播
MaxPooling就是对卷积区域进行最大值计算。
1、MaxPooling池化区域与步长相同时,即只对最大区域进行梯度计算,最后将梯度平均到四个区域中。
1
3
1
4
5
2
4
6
9
6
1
2
3
4
5
6
c
o
n
v
(
2
,
2
)
s
t
r
i
d
e
=
2
>
5
6
9
6
梯
度
坐
标
>
0
0
0
0
1
0
0
1
1
0
0
0
0
0
0
1
梯
度
值
>
0
0
0
0
0.25
0
0
0.25
0.25
0
0
0
0
0
0
0.25
\begin{gathered} \begin{matrix} 1 & 3 & 1 & 4 \\ 5 & 2 &4 & 6 \\ 9 & 6 & 1 & 2 \\ 3 & 4 & 5 & 6\end{matrix} \quad conv(2,2) stride=2 > \begin{matrix} 5 & 6 \\ 9 & 6\end{matrix} \quad 梯度坐标> \begin{matrix} 0 & 0 & 0 & 0 \\ 1 & 0 & 0 & 1 \\ 1 & 0 & 0 & 0 \\ 0 & 0 & 0 & 1\end{matrix} \quad 梯度值> \begin{matrix} 0 & 0 & 0 & 0 \\ 0.25 & 0 & 0 & 0.25 \\ 0.25 & 0 & 0 & 0 \\ 0 & 0 & 0 & 0.25\end{matrix} \end{gathered}
1593326414154626conv(2,2)stride=2>5966梯度坐标>0110000000000101梯度值>00.250.2500000000000.2500.25
下图中,红色的框表示池化区域,得到5,而对应的下标计数为1,最后将所有的梯度平均。1/4
2、MaxPooling池化区域与步长不相同时,进行池化操作之后,对于重复出现的最大值进行重复计数,最后再根据计数进行梯度平均。
1
3
1
4
5
2
4
6
9
6
1
2
3
4
5
6
c
o
n
v
(
2
,
2
)
s
t
r
i
d
e
=
1
>
5
4
6
9
6
6
9
6
6
梯
度
坐
标
>
0
0
0
0
1
0
1
2
2
2
0
0
0
0
0
1
梯
度
值
>
0
0
0
0
0.11
0.11
0
0.22
0.22
0.22
0
0
0
0
0
0.11
\begin{gathered} \begin{matrix} 1 & 3 & 1 & 4 \\ 5 & 2 &4 & 6 \\ 9 & 6 & 1 & 2 \\ 3 & 4 & 5 & 6\end{matrix} \quad conv(2,2) stride=1 > \begin{matrix} 5 & 4& 6 \\ 9 & 6 & 6 \\9 & 6 & 6\end{matrix} \quad 梯度坐标> \begin{matrix} 0 & 0 & 0 & 0 \\ 1 & 0 & 1 & 2 \\ 2 & 2 & 0 & 0 \\ 0 & 0 & 0 & 1\end{matrix} \quad 梯度值> \begin{matrix} 0 & 0 & 0 & 0 \\ 0.11 & 0.11 & 0 & 0.22 \\ 0.22 & 0.22 & 0 & 0 \\ 0 & 0 & 0 & 0.11\end{matrix} \end{gathered}
1593326414154626conv(2,2)stride=1>599466666梯度坐标>0120002001000201梯度值>00.110.22000.110.220000000.2200.11
当步长小于池化区域时,存在重叠区域,那么将进行重复计算,对应梯度也按照权重分配。
上图中,5、4分别是最大值,因此梯度计数回到对应的位置分别为1。下图中,绿、红的最大值均为6,因此被计数两次,梯度坐标为2。
二、AvgPooling前向传播与反向传播
AvgPooling就是对卷积区域进行均值计算。
1、AvgPooling池化区域与步长相同时,对全局进行梯度平均。
1
3
1
4
5
2
4
6
9
6
1
2
3
4
5
6
c
o
n
v
(
2
,
2
)
s
t
r
i
d
e
=
2
>
2.75
3.75
5.5
3.5
梯
度
坐
标
>
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1
梯
度
值
>
0.0265
0.0265
0.0265
0.0265
0.0265
0.0265
0.0265
0.0265
0.0265
0.0265
0.0265
0.0265
0.0265
0.0265
0.0265
0.0265
\begin{gathered} \begin{matrix} 1 & 3 & 1 & 4 \\ 5 & 2 &4 & 6 \\ 9 & 6 & 1 & 2 \\ 3 & 4 & 5 & 6\end{matrix} \quad conv(2,2) stride=2 > \begin{matrix} 2.75 & 3.75 \\ 5.5 & 3.5\end{matrix} \quad 梯度坐标> \begin{matrix} 1 & 1 & 1 & 1 \\ 1 & 1 & 1 & 1 \\ 1 & 1 & 1 & 1 \\ 1 & 1 & 1 & 1\end{matrix} \quad 梯度值> \begin{matrix} 0.0265 & 0.0265 & 0.0265 & 0.0265 \\ 0.0265 & 0.0265 & 0.0265 & 0.0265 \\ 0.0265 & 0.0265 & 0.0265 & 0.0265 \\ 0.0265 & 0.0265 & 0.0265 & 0.0265\end{matrix} \end{gathered}
1593326414154626conv(2,2)stride=2>2.755.53.753.5梯度坐标>1111111111111111梯度值>0.02650.02650.02650.02650.02650.02650.02650.02650.02650.02650.02650.02650.02650.02650.02650.0265
2、AvgPooling池化区域与步长不相同时,对全局按照重叠区域进行权重平均。对重复计算的区域进行重复计数。
1
3
1
4
5
2
4
6
9
6
1
2
3
4
5
6
c
o
n
v
(
2
,
2
)
s
t
r
i
d
e
=
1
>
2.75
2.5
3.75
5.5
3.25
3.25
5.5
4
3.5
梯
度
坐
标
>
1
2
2
1
2
4
4
2
2
4
4
2
1
2
2
1
梯
度
值
>
0.0287
0.0556
0.0556
0.0287
0.0556
0.1111
0.1111
0.0556
0.0556
0.1111
0.1111
0.0556
0.0287
0.0265
0.0265
0.0287
\begin{gathered} \begin{matrix} 1 & 3 & 1 & 4 \\ 5 & 2 &4 & 6 \\ 9 & 6 & 1 & 2 \\ 3 & 4 & 5 & 6\end{matrix} \quad conv(2,2) stride=1 > \begin{matrix} 2.75 & 2.5 &3.75\\ 5.5 & 3.25 & 3.25 \\5.5&4&3.5\end{matrix} \quad 梯度坐标> \begin{matrix} 1 & 2 & 2 & 1 \\ 2 & 4 & 4 & 2 \\ 2 & 4 & 4 & 2 \\ 1 & 2 & 2 & 1\end{matrix} \quad 梯度值> \begin{matrix} 0.0287& 0.0556& 0.0556& 0.0287\\ 0.0556& 0.1111 & 0.1111 & 0.0556\\ 0.0556& 0.1111 & 0.1111 & 0.0556 \\ 0.0287& 0.0265 & 0.0265 & 0.0287\end{matrix} \end{gathered}
1593326414154626conv(2,2)stride=1>2.755.55.52.53.2543.753.253.5梯度坐标>1221244224421221梯度值>0.02870.05560.05560.02870.05560.11110.11110.02650.05560.11110.11110.02650.02870.05560.05560.0287
这里把重复计数问题通过滑动窗口的形式表现出来:
左图中数字1,在进行平均池化计算时,由于会被红色个窗口进行平均计算,因此梯度坐标为1,即均值计算计数为1;3经过红、黑两个窗口进行均值计算,计数梯度为2;2这个数字经过红、黑、绿、粉四个窗口进行均值计算,因此计数为4。
三、代码
import torch
import numpy as np
img = np.array([
[1,3,1,4],
[5,2,4,6],
[9,6,1,2],
[3,4,5,6],])
img = img.astype(np.float)
img = torch.tensor(img,requires_grad=True).float()
img = img.unsqueeze(0)
img.retain_grad() #保留梯度
pool = torch.nn.functional.avg_pool2d(img,kernel_size=(2,2),stride=1) #平均池化
# pool = torch.nn.functional.max_pool2d(vara,kernel_size=(2,2),stride=1) # 最大池化
print(pool) #池化结果
pool = torch.mean(pool) #均值计算
pool.backward() #梯度回传
print(img.grad) #输出梯度