1. 從全連接到卷積
?
?2. 圖像卷積
3. 圖形卷積代碼
互相關操作
import torch
from torch import nn
from d2l import torch as d2ldef corr2d(X, K):"""計算2維互相關運算"""h, w = K.shapeY = 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
?驗證上述二維互相關運算的輸出
X = torch.tensor([[0.0, 1.0, 2.0], [3.0, 4.0, 5.0], [6.0, 7.0, 8.0]])
K = torch.tensor([[0.0, 1.0], [2.0, 3.0]])
corr2d(X, K)
?實現二維卷積層
class Conv2D(nn.Module):def __init__(self, kernel_size):super().__init__()self.weight = nn.Parameter(torch.rand(kernel_size))self.bias = nn.Parameter(torch.zeros(1))def forward(self, x):return corr2d(x, self.weight) + self.bias
卷積層的一個簡單應用: 檢測圖像中不同顏色的邊緣
X = torch.ones((6, 8))
X[:, 2:6] = 0
X
K = torch.tensor([[1.0, -1.0]])
輸出Y中的1代表從白色到黑色的邊緣,-1代表從黑色到白色的邊緣
Y = corr2d(X, K)
Y
?卷積核K只可以檢測垂直邊緣
corr2d(X.t(), K) # X轉置
?學習由X生成Y的卷積核(3e-2為學習率)
conv2d = nn.Conv2d(1,1, kernel_size=(1,2),bias=False)# b,c,h,w
# 這個二維卷積層使用四維輸入和輸出格式(批量大小、通道、高度、寬度),
# 其中批量大小和通道數都為1
X = X.reshape((1, 1, 6, 8))
Y = Y.reshape((1, 1, 6, 7))for i in range(10):Y_hat = conv2d(X)l = (Y_hat - Y)**2conv2d.zero_grad()l.sum().backward()conv2d.weight.data[:] -= 3e-2 * conv2d.weight.gradif (i + 1) % 2 == 0:print(f'batch{i+1}, loss{l.sum():.3f}')
所學的卷積核的權重張量,與之前的權重(1, -1)很接近
conv2d.weight.data.reshape((1, 2))
小結
- 二維卷積層的核心計算是二維互相關運算。最簡單的形式是,對二維輸入數據和卷積核執行互相關操作,然后添加一個偏置。
- 我們可以設計一個卷積核來檢測圖像的邊緣。
- 我們可以從數據中學習卷積核的參數。
- 學習卷積核時,無論用嚴格卷積運算或互相關運算,卷積層的輸出不會受太大影響。
- 當需要檢測輸入特征中更廣區域時,我們可以構建一個更深的卷積網絡。