-
两个原则:
- 平移不变性
- 局部性
这两个在图片里面找模式的原则启发了之后的设计。
-
重新考察全连接层
-
将输入和输出变形为矩阵(宽度,高度)
-
将权重变形为
4-D
张量( h h h, w w w)到( h ′ h' h′, w ′ w' w′)
h i , j = ∑ k , l w i , j , k , l x k , l = ∑ a , b v i , j , a , b x i + a , j + b h_{i, j}=\sum_{k, l} w_{i, j, k, l} x_{k, l}=\sum_{a, b} v_{i, j, a, b} x_{i+a, j+b} hi,j=k,l∑wi,j,k,lxk,l=a,b∑vi,j,a,bxi+a,j+b
V V V是 W W W的重新索引 v i , j , a , b = w i , j , i + a , j + b v_{i, j, a, b}=w_{i, j, i+a, j+b} vi,j,a,b=wi,j,i+a,j+b
-
-
原则 #1 - 平移不变性
-
x x x的平移导致 h h h的平移: h i , j = ∑ a , b v i , j , a , b x i + a , j + b h_{i, j}=\sum_{a, b} v_{i, j, a, b} x_{i+a, j+b} hi,j=∑a,bvi,j,a,bxi+a,j+b
-
v v v不应该依赖于( i i i, j j j)[( a a a, b b b)可以看作是我们要识别的东西]
-
解决方案:加一个限制, v i , j , a , b = v a , b v_{i,j,a,b} = v_{a,b} vi,j,a,b=va,b
h i , j = ∑ a , b v a , b x i + a , j + b h_{i, j}=\sum_{a, b} v_{a, b} x_{i+a, j+b} hi,j=a,b∑va,bxi+a,j+b
这就是2维卷积(交叉相关)
-
-
原则 #2 - 局部性
-
当评估 h i , j h_{i,j} hi,j时,我们不应该用远离 x i , j x_{i,j} xi,j的参数
-
解决方案:当 ∣ a ∣ , ∣ b ∣ > Δ |a|, |b| > \Delta ∣a∣,∣b∣>Δ时,使得 v a , b = 0 v_{a,b} = 0 va,b=0
h i , j = ∑ a = − Δ Δ ∑ b = − Δ Δ v a , b x i + a , j + b h_{i, j}=\sum_{a=-\Delta}^{\Delta} \sum_{b=-\Delta}^{\Delta} v_{a, b} x_{i+a, j+b} hi,j=a=−Δ∑Δb=−Δ∑Δva,bxi+a,j+b
-
-
对全连接层使用平移不变性和局部性得到卷积层
h i , j = ∑ a , b v i , j , a , b x i + a , j + b → h i , j = ∑ a = − Δ Δ ∑ b = − Δ Δ v a , b x i + a , j + b h_{i, j}=\sum_{a, b} v_{i, j, a, b} x_{i+a, j+b} \quad \rightarrow \quad h_{i, j}=\sum_{a=-\Delta}^{\Delta} \sum_{b=-\Delta}^{\Delta} v_{a, b} x_{i+a, j+b} hi,j=a,b∑vi,j,a,bxi+a,j+b→hi,j=a=−Δ∑Δb=−Δ∑Δva,bxi+a,j+b -
交叉相关 vs 卷积
-
二维交叉相关
y i , j = ∑ a = 1 h ∑ b = 1 w w a , b x i + a , j + b y_{i, j}=\sum_{a=1}^{h} \sum_{b=1}^{w} w_{a, b} x_{i+a, j+b} yi,j=a=1∑hb=1∑wwa,bxi+a,j+b -
二维卷积
y i , j = ∑ a = 1 h ∑ b = 1 w w − a , − b x i + a , j + b y_{i, j}=\sum_{a=1}^{h} \sum_{b=1}^{w} w_{-a, -b} x_{i+a, j+b} yi,j=a=1∑hb=1∑ww−a,−bxi+a,j+b -
由于对称性,在实际使用中没有区别
-
-
卷积层将输入和核矩阵进行交叉相关,加上偏移后得到输出;核矩阵和偏移是可学习的参数;核矩阵的大小是超参数(局部性)。
-
互相关运算
import torch def corr2d(X, K): """计算二维互相关运算""" h, w = K.shape Y = torch.zeros((X.shape[0] - h + 1, X.shape[1] - w + 1)) for i in range(Y.shape[0]): for j in range(Y.shape[1]): Y[i, j] = (X[i:i + h, j:j + w] * K).sum() return Y