卷积Conv2D
import torch.nn as nn
# With square kernels and equal stride
m = nn.Conv2d(3, 4, 3, stride=1, padding=1)
#input = torch.randn(20, 3, 50, 100)
input = torch.arange(1,97).reshape(2,3,4,4).float()
output = m(input)
print(m)
print(input.shape)
print(input)
# Conv2d(3, 4, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
# torch.Size([2, 3, 4, 4])
# tensor([[[[ 1., 2., 3., 4.],
# [ 5., 6., 7., 8.],
# [ 9., 10., 11., 12.],
# [13., 14., 15., 16.]],
# [[17., 18., 19., 20.],
# [21., 22., 23., 24.],
# [25., 26., 27., 28.],
# [29., 30., 31., 32.]],
# [[33., 34., 35., 36.],
# [37., 38., 39., 40.],
# [41., 42., 43., 44.],
# [45., 46., 47., 48.]]],
# [[[49., 50., 51., 52.],
# [53., 54., 55., 56.],
# [57., 58., 59., 60.],
# [61., 62., 63., 64.]],
# [[65., 66., 67., 68.],
# [69., 70., 71., 72.],
# [73., 74., 75., 76.],
# [77., 78., 79., 80.]],
# [[81., 82., 83., 84.],
# [85., 86., 87., 88.],
# [89., 90., 91., 92.],
# [93., 94., 95., 96.]]]])
import torch.nn as nn
import torch
m = nn.Conv2d(3, 2, 3, stride=1, padding=1)
# 设置模式化的权重
with torch.no_grad():
# 第一个卷积核:检测水平特征
m.weight.data[0, 0, :, :] = torch.tensor([[1, 1, 1], [0, 0, 0], [-1, -1, -1]]).float()
m.weight.data[0, 1, :, :] = torch.tensor([[1, 1, 1], [0, 0, 0], [-1, -1, -1]]).float()
m.weight.data[0, 2, :, :] = torch.tensor([[1, 1, 1], [0, 0, 0], [-1, -1, -1]]).float()
# 第二个卷积核:检测垂直特征
m.weight.data[1, 0, :, :] = torch.tensor([[1, 0, -1], [1, 0, -1], [1, 0, -1]]).float()
m.weight.data[1, 1, :, :] = torch.tensor([[1, 0, -1], [1, 0, -1], [1, 0, -1]]).float()
m.weight.data[1, 2, :, :] = torch.tensor([[1, 0, -1], [1, 0, -1], [1, 0, -1]]).float()
m.bias.data = torch.zeros(2)
input = torch.arange(1, 97).reshape(2, 3, 4, 4).float()
print("原始输入数据:")
print(f"输入形状: {input.shape}")
print(input[0, 0]) # 第一张图片的R通道
# 手动添加padding来查看padding后的矩阵
def show_padded_matrix(input_tensor, padding=1):
padded = torch.nn.functional.pad(input_tensor, (padding, padding, padding, padding), mode='constant', value=0)
return padded
# 对第一张图片的所有通道添加padding
padded_input = show_padded_matrix(input[0], padding=1)
print(f"\nPadding后的矩阵形状: {padded_input.shape}")
print("\nPadding后的矩阵 (第一张图片):")
for channel in range(3):
print(f"\n通道 {channel} (R/G/B):")
print(padded_input[channel])
# 计算输出
output = m(input)
print(f"\n卷积输出形状: {output.shape}")
print("输出数据 (第一张图片):")
print(output[0])
# 原始输入数据:
# 输入形状: torch.Size([2, 3, 4, 4])
# tensor([[ 1., 2., 3., 4.],
# [ 5., 6., 7., 8.],
# [ 9., 10., 11., 12.],
# [13., 14., 15., 16.]])
# Padding后的矩阵形状: torch.Size([3, 6, 6])
# Padding后的矩阵 (第一张图片):
# 通道 0 (R/G/B):
# tensor([[ 0., 0., 0., 0., 0., 0.],
# [ 0., 1., 2., 3., 4., 0.],
# [ 0., 5., 6., 7., 8., 0.],
# [ 0., 9., 10., 11., 12., 0.],
# [ 0., 13., 14., 15., 16., 0.],
# [ 0., 0., 0., 0., 0., 0.]])
# 通道 1 (R/G/B):
# tensor([[ 0., 0., 0., 0., 0., 0.],
# [ 0., 17., 18., 19., 20., 0.],
# [ 0., 21., 22., 23., 24., 0.],
# [ 0., 25., 26., 27., 28., 0.],
# [ 0., 29., 30., 31., 32., 0.],
# [ 0., 0., 0., 0., 0., 0.]])
# 通道 2 (R/G/B):
# tensor([[ 0., 0., 0., 0., 0., 0.],
# [ 0., 33., 34., 35., 36., 0.],
# [ 0., 37., 38., 39., 40., 0.],
# [ 0., 41., 42., 43., 44., 0.],
# [ 0., 45., 46., 47., 48., 0.],
# [ 0., 0., 0., 0., 0., 0.]])
# 卷积输出形状: torch.Size([2, 2, 4, 4])
# 输出数据 (第一张图片):
# tensor([[[-129., -198., -207., -141.],
# [ -48., -72., -72., -48.],
# [ -48., -72., -72., -48.],
# [ 153., 234., 243., 165.]],
# [[-120., -12., -12., 126.],
# [-198., -18., -18., 207.],
# [-234., -18., -18., 243.],
# [-168., -12., -12., 174.]]], grad_fn=)