视频链接:动手学习深度学习–多输入多输出通道
课程主页:https://courses.d2l.ai/zh-v2/
教材:https://zh-v2.d2l.ai/
1、多输入通道
import torch
from d2l import torch as d2l
import os
os.environ["KMP_DUPLICATE_LIB_OK"]="TRUE"
"====================1、多输入通道===================="
def corr2d_multi_in(X, K):
# 先遍历“X”和“K”的第0个维度(通道维度),再把它们加在一起
return sum(d2l.corr2d(x, k) for x, k in zip(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.]])
'''
2、多输出通道
torch.stack:增加新的维度进行堆叠 【若不懂,可参考文章链接】
"====================2、多输出通道===================="
def corr2d_multi_in_out(X, K):
# 迭代“K”的第0个维度,每次都对输入“X”执行互相关运算。
# 最后将所有结果都叠加在一起
return torch.stack([corr2d_multi_in(X, k) for k in K], 0)
# torch.stack:增加新的维度进行堆叠
K = torch.stack((K, K + 1, K + 2), 0) # 三个两层2×2的卷积
print(K.shape)
'''
输出:
torch.Size([3, 2, 2, 2])
'''
print(corr2d_multi_in_out(X, K))
'''
输出:
tensor([[[ 56., 72.],
[104., 120.]],
[[ 76., 100.],
[148., 172.]],
[[ 96., 128.],
[192., 224.]]])
'''
3、1×1卷积层等价于 一个全连接
"====================3、1×1卷积层===================="
# 1×1卷积 等价于 一个全连接
def corr2d_multi_in_out_1x1(X, K):
c_i, h, w = X.shape # torch.Size([3, 3, 3])
c_o = K.shape[0] # 2
# 将 X 和 K 转化为矩阵
X = X.reshape((c_i, h * w)) # (3,9) 将高和宽拉成一条向量
K = K.reshape((c_o, c_i)) # (2,3)
# 全连接层中的矩阵乘法
Y = torch.matmul(K, X) # (2,3) × (3,9) = (2,9)
return Y.reshape((c_o, h, w)) # (2,9) ==> (2,3,3)
X = torch.normal(0, 1, (3, 3, 3))
K = torch.normal(0, 1, (2, 3, 1, 1))
Y1 = corr2d_multi_in_out_1x1(X, K)
Y2 = corr2d_multi_in_out(X, K)
# 有一些浮点精度的区别,相减小于一个很小的值。几乎认为Y1和Y2是两个完全一样的值
assert float(torch.abs(Y1 - Y2).sum()) < 1e-6