torch.nn.functional.conv2d
是 PyTorch 中用于进行二维卷积操作的函数。卷积操作是深度学习中卷积神经网络(CNN)的核心部分,用于提取图像特征,常见于图像分类、目标检测和语义分割等任务中。
torch.nn.functional.conv2d(input, weight, bias=None, stride=1, padding=0, dilation=1, groups=1)
input
(Tensor): 输入张量,形状为 (N, C_in, H, W)
,其中 N
是批量大小,C_in
是输入通道数,H
是高度,W
是宽度。weight
(Tensor): 卷积核权重,形状为 (C_out, C_in // groups, kH, kW)
,其中 C_out
是输出通道数,kH
是卷积核高度,kW
是卷积核宽度。bias
(Tensor, 可选): 偏置,形状为 (C_out)
。如果为 None
,则不添加偏置。stride
(int 或 tuple, 可选): 卷积步长,默认值为 1
。padding
(int 或 tuple, 可选): 输入的每一边填充的大小,默认值为 0
。dilation
(int 或 tuple, 可选): 卷积核元素之间的间距,默认值为 1
。groups
(int, 可选): 将输入分组,默认值为 1
。groups
的值大于 1
时,相当于对输入进行组卷积。
返回一个张量,形状为 (N, C_out, H_out, W_out)
,表示卷积后的输出。
import torch
import torch.nn.functional as F
# 创建一个形状为 (1, 1, 5, 5) 的输入张量
input = torch.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]]]], dtype=torch.float32)
# 创建一个形状为 (1, 1, 3, 3) 的卷积核
weight = torch.tensor([[[[1, 0, -1],
[1, 0, -1],
[1, 0, -1]]]], dtype=torch.float32)
# 执行卷积操作
output = F.conv2d(input, weight)
print("卷积后的输出:\n", output)
输出:
卷积后的输出:
tensor([[[[-6., -6., -6.],
[-6., -6., -6.],
[-6., -6., -6.]]]])
import torch
import torch.nn.functional as F
# 创建一个形状为 (1, 1, 5, 5) 的输入张量
input = torch.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]]]], dtype=torch.float32)
# 创建一个形状为 (1, 1, 3, 3) 的卷积核
weight = torch.tensor([[[[1, 0, -1],
[1, 0, -1],
[1, 0, -1]]]], dtype=torch.float32)
# 添加偏置
bias = torch.tensor([1], dtype=torch.float32)
# 设置步长和填充
stride = 2
padding = 1
# 执行卷积操作
output = F.conv2d(input, weight, bias=bias, stride=stride, padding=padding)
print("卷积后的输出:\n", output)
输出:
卷积后的输出:
tensor([[[[ -8., -3., 14.],
[-35., -5., 43.],
[-38., -3., 44.]]]])
import torch
import torch.nn.functional as F
import cv2
import numpy as np
# 读取图像,读者应该修改图片路径
input_image = cv2.imread('2015.jpg')
# 创建一个形状为 (3, 1, 3, 3) 的卷积核
conv_kernel = torch.tensor([[[[-1, 0, 1],
[-2, 0, 2],
[-1, 0, 1]]],
[[[-1, 0, 1],
[-2, 0, 2],
[-1, 0, 1]]],
[[[-1, 0, 1],
[-2, 0, 2],
[-1, 0, 1]]]], dtype=torch.float32)
print(conv_kernel.shape) # 应输出 (3, 1, 3, 3)
# 将图像转换为 tensor 并调整形状
input_tensor = torch.tensor(input_image, dtype=torch.float32)
input_tensor = torch.unsqueeze(input_tensor, 0) # 变为 (1, 高, 宽, 通道)
input_tensor = torch.permute(input_tensor, (0, 3, 1, 2)) # 变为 (1, 通道, 高, 宽)
print(input_tensor.shape) # 应输出 (1, 3, 高, 宽)
# 执行卷积操作
conv_output = F.conv2d(input_tensor, conv_kernel, groups=3)
print(conv_output.shape) # 应输出 (1, 3, 高, 宽)
# 调整输出形状并裁剪到 0-255 范围
output_image = torch.permute(conv_output, (0, 2, 3, 1)) # 变为 (1, 高, 宽, 通道)
output_image = output_image.squeeze() # 变为 (高, 宽, 通道)
output_image = torch.clamp(output_image, 0, 255) # 裁剪到 0-255 范围
cv2.imshow('Convolved Image', output_image.numpy().astype(np.uint8))
cv2.waitKey()
cv2.destroyAllWindows()