21多輸入多輸出通道
import torch
from d2l import torch as d2ldef corr2d(X, K):"""計算二維互相關運算"""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# 多輸入通道互相關運算
def corr2d_multi_in(X, K):#對于每對輸入通道 x 和濾波器 k,調用 corr2d 函數,并將所有結果相加。return sum(corr2d(x, k) for x, k in zip(X, K))#zip(X, K) 會生成一個元組迭代器,其中每個元組包含 X 和 K 中的對應元素# X 是一個具有兩個輸入通道的張量,K 是一個具有兩個通道的濾波器。
X = torch.tensor([[[0.0, 1.0, 2.0], [3.0, 4.0, 5.0], [6.0, 7.0, 8.0]],[[1.0, 2.0, 3.0], [4.0, 5.0, 6.0], [7.0, 8.0, 9.0]]])
K = torch.tensor([[[0.0, 1.0], [2.0, 3.0]], [[1.0, 2.0], [3.0, 4.0]]])print(corr2d_multi_in(X, K))
"""
tensor([[ 56., 72.],[104., 120.]])
"""# 多輸出通道
def corr2d_multi_in_out(X, K):#對于每個輸出通道的濾波器 k,調用 corr2d_multi_in 函數,并將所有結果堆疊在一起形成新的張量。return torch.stack([corr2d_multi_in(X, k) for k in K], 0)# 將 K 擴展為一個具有三個輸出通道的新濾波器
# K,K中每個元素加1,K中每個元素加2
K = torch.stack((K, K + 1, K + 2), 0)
print(K.shape)
#torch.Size([3, 2, 2, 2])
#具有3個輸出通道、每個輸出通道有2個輸入通道的2x2濾波器的卷積核集合。
"""
第0維:新維度插入到最前面,堆疊的張量沿著第0維度排列。torch.Size([3, 2, 2, 2])
第1維:新維度插入到第二個位置,堆疊的張量沿著第1維度排列。torch.Size([2, 3, 2, 2])
第2維:新維度插入到第三個位置,堆疊的張量沿著第2維度排列。torch.Size([2, 2, 3, 2])
"""print(corr2d_multi_in_out(X, K))
"""
tensor([[[ 56., 72.],[104., 120.]],[[ 76., 100.],[148., 172.]],[[ 96., 128.],[192., 224.]]])
"""# 1 * 1 卷積核
#可以將卷積層看作在每個像素位置應用的全連接層
#以c_i個輸入值轉換為c_o個輸出值
def corr2d_multi_in_out_1x1(X, K):c_i, h, w = X.shape #獲取輸入張量 X 的通道數、高度和寬度。c_o = K.shape[0] #獲取卷積核 K 的輸出通道數。X = X.reshape((c_i, h * w)) # 3 * 9K = K.reshape((c_o, c_i)) # 2 * 3Y = torch.matmul(K, X)return Y.reshape((c_o, h, w)) # 2 * 3 * 3X = torch.normal(0, 1, (3, 3, 3))#表示具有2個輸出通道,每個通道對應3個輸入通道 1x1的濾波器
K = torch.normal(0, 1, (2, 3, 1, 1))
Y1 = corr2d_multi_in_out_1x1(X, K)
Y2 = corr2d_multi_in_out(X, K)
assert float(torch.abs(Y1 - Y2).sum()) < 1e-6