和鲸社区深度学习基础训练营2025年关卡3_Q1(1)
Q1: 给定一个大小为 32x32x1 的灰度图像(MNIST 手写数字图像),以及一个大小为 3x3x1x8 的卷积核,使用 conv2D_gemm 函数(我们上文中实现的)对图像进行卷积运算,步幅为 1,并填充方式为 same。 请问卷积结果的形状是多少?
1.纯numpy
import numpy as np# 生成随机图像和卷积核
input_image = np.random.rand(32, 32, 1) # 32x32x1
kernel = np.random.rand(3, 3, 1, 8) # 3x3x1x8# 执行卷积运算
output = np.zeros((32, 32, 8)) # 初始化输出数组# 使用'same'填充方式
pad_width = ((1, 1), (1, 1), (0, 0))
padded_image = np.pad(input_image, pad_width, mode='constant')# 执行卷积
for i in range(8): # 对每个卷积核for y in range(32): # 高度方向for x in range(32): # 宽度方向# 提取当前3x3区域region = padded_image[y:y+3, x:x+3, :]# 点乘并求和output[y, x, i] = np.sum(region * kernel[:, :, :, i])print("卷积结果的形状:", output.shape)
运行结果:
2.使用 scipy.signal.convolve2d
import numpy as np
from scipy.signal import convolve2d# 生成随机输入图像和卷积核
input_image = np.random.rand(32, 32, 1) # 32x32x1
kernel = np.random.rand(3, 3, 1, 8) # 3x3x1x8# 初始化输出数组
output = np.zeros((32, 32, 8))# 对每个卷积核执行卷积
for i in range(8):# 提取当前卷积核(3x3x1)current_kernel = kernel[:, :, 0, i]# 对每个通道执行卷积output[:, :, i] = convolve2d(input_image[:, :, 0], current_kernel, mode='same', boundary='fill')print("卷积结果的形状:", output.shape)
运行结果:
3.pytorch中的卷积函数
代码1
import torch
import torch.nn as nnconv_layer = nn.Conv2d(in_channels=1, out_channels=8, kernel_size=3, stride=1, padding=1)
input_tensor = torch.randn(1, 1, 32, 32)
output = conv_layer(input_tensor)
print(output.shape) # 查看输出张量的形状
代码2
import torch
import torch.nn as nn# 生成随机输入图像和卷积核
input_image = torch.rand(1, 1, 32, 32) # (batch_size, channels, height, width)
kernel = torch.rand(8, 1, 3, 3) # (out_channels, in_channels, height, width)# 创建卷积层
conv = nn.Conv2d(in_channels=1, out_channels=8, kernel_size=3, stride=1, padding=1, bias=False) # padding=1实现'same'# 手动设置卷积核权重
conv.weight = nn.Parameter(kernel)# 执行卷积
output = conv(input_image)print("卷积结果的形状:", output.shape)
运行结果:
(batch_size, channels, height, width)