欢迎光临
我们一直在努力

PyTorch 两种卷积写法彻底对比:F.conv2d 函数式 vs nn.Conv2d 类实战(超详细入门笔记)

一、前言

本文对比 手动卷积演示代码 和 标准模型卷积实战代码,区分 torch.nn.functional.conv2d(函数式卷积)与 torch.nn.Conv2d(类形式卷积层)的用法、场景、底层逻辑,同时梳理张量维度、网络执行流程、数据集调用等全套知识点,适合深度学习入门复习。


二、代码 1:函数式卷积 F.conv2d 手动卷积演示

完整代码

python

运行

import torch
import torch.nn.functional as F

# 1. 定义原始二维输入矩阵(模拟单通道图像)
input = torch.tensor([[1,2,0,3,1],
[0,1,2,3,1],
[1,2,1,0,0],
[5,2,3,1,1],
[2,1,0,1,1]])

# 2. 手动定义卷积核
kernel = torch.tensor([[1,2,1],
[0,1,0],
[2,1,0]])

# 3. 维度变换:转为卷积要求的 4 维格式 [N, C, H, W]
# N=1(批次), C=1(通道), H=5(高), W=5(宽)
input = torch.reshape(input,(1,1,5,5))

# 卷积核也转为4维:[out_C, in_C, kH, kW]
kernel = torch.reshape(kernel,(1,1,3,3))

# 4. 调用函数式卷积完成计算
output = F.conv2d(input, kernel, stride=1)

# 5. 打印卷积结果
print(output)

逐行详细解析

1. 库导入

python

运行

import torch
import torch.nn.functional as F

  • torch:基础张量运算库,用来创建矩阵、变形、计算;
  • torch.nn.functional:简写为 F,函数式神经网络算子库,内部包含卷积、激活、池化等纯计算函数,无内置可训练参数。

2. 定义输入与卷积核

python

运行

# 原始输入:二维张量 [H, W] 5行5列
input = torch.tensor([[1,2,0,3,1],…])
# 手动自定义 3×3 卷积核
kernel = torch.tensor([[1,2,1],…])

  • 此处是纯数学矩阵,模拟一张 5×5 单通道灰度图;
  • 卷积核由用户手动指定固定数值,不是模型自动训练出来的参数。

3. reshape 维度扩充(核心重点)

python

运行

input = torch.reshape(input,(1,1,5,5))

PyTorch 二维卷积 conv2d 强制要求输入为 4 维张量,格式规定: [batch_size, channels, height, width] → 简写 [N, C, H, W]

参数解释:

  • 第一个 1:batch_size 批次大小,代表一批只有 1 张图;
  • 第二个 1:channels 通道数,代表单通道灰度图;
  • 5, 5:图像原始高度、宽度。
  • python

    运行

    kernel = torch.reshape(kernel,(1,1,3,3))

    卷积核标准 4 维格式:[out_channels, in_channels, kH, kW]

    • 第 1 个1:输出通道数;
    • 第 2 个1:输入通道数(和输入图像通道一致);
    • 3,3:卷积核尺寸。

    核心规则:只要使用卷积算子,必须补全 4 个维度,哪怕只有 1 张图、1 个通道。

    4. F.conv2d 函数调用

    python

    运行

    output = F.conv2d(input, kernel, stride=1)

  • 函数特点:纯计算函数,不持有参数;
  • 必须手动传入:输入张量、卷积核、步长;
  • stride=1:卷积核每次滑动 1 个像素;
  • 默认 padding=0:图像外围不补 0。
  • 5. 输出形状计算


    三、代码 2:类形式卷积 nn.Conv2d + 数据集实战

    完整代码

    python

    运行

    import torch.nn
    import torchvision
    from torch import nn
    from torch.utils.data import DataLoader
    from torch.utils.tensorboard import SummaryWriter

    # 1. 加载CIFAR10测试集
    torch_dataset = torchvision.datasets.CIFAR10(
    root="../dataset",
    train=False,
    transform=torchvision.transforms.ToTensor(),
    download=True
    )

    # 2. 批量数据加载器
    dataloader = DataLoader(dataset=torch_dataset, batch_size=64)

    # 3. 自定义卷积网络(继承nn.Module)
    class f1(nn.Module):
    def __init__(self):
    super().__init__()
    # 定义卷积层(类形式卷积)
    self.conv2d=torch.nn.Conv2d(in_channels=3,out_channels=6,kernel_size=3,stride=1)

    # 前向传播:数据运算逻辑
    def forward(self, x):
    x=self.conv2d(x)
    return x

    # 4. TensorBoard日志器
    writer = SummaryWriter("logs3")
    # 5. 实例化网络
    f=f1()
    step=0

    # 6. 循环遍历批次数据
    for data in dataloader:
    imgs,target=data
    # 传入图像,执行卷积运算
    output =f(imgs)
    # 可视化原始图片
    writer.add_images("input",imgs,step)

    # 重塑维度,适配TensorBoard显示
    output = torch.reshape(output,(-1,3,30,30))
    writer.add_images("output",output,step)
    step+=1

    # 关闭日志
    writer.close()

    逐行详细解析

    1. 库导入

    python

    运行

    import torchvision # 视觉库:数据集、图像预处理
    from torch import nn # 神经网络模块:网络层、模型基类
    from torch.utils.data import DataLoader # 批量加载数据
    from torch.utils.tensorboard import SummaryWriter # 可视化

    2. 加载 CIFAR10 数据集

    python

    运行

    torch_dataset = torchvision.datasets.CIFAR10(
    root="../dataset", # 数据集存放路径,../ 代表上一级目录
    train=False, # False = 加载测试集(10000张)
    transform=ToTensor(), # 预处理:PIL图 → 张量 + 归一化 + 维度转换
    download=True # 本地无文件则自动下载
    )

    • 单张图像形状:[3, 32, 32],3 通道 RGB 彩色图;
    • 像素范围:[0, 1]。

    3. DataLoader 批量打包

    python

    运行

    dataloader = DataLoader(dataset=torch_dataset, batch_size=64)

    • batch_size=64:每一批取出 64 张图片;
    • 输出数据形状:[64, 3, 32, 32],标准 4 维卷积输入格式。

    4. 自定义网络类(PyTorch 标准模型写法)

    python

    运行

    class f1(nn.Module):
    def __init__(self):
    super().__init__()
    # 定义卷积层:类形式 Conv2d
    self.conv2d=torch.nn.Conv2d(in_channels=3,out_channels=6,kernel_size=3,stride=1)

  • nn.Module:所有自定义网络必须继承的基类,负责参数管理、反向传播、模型保存;
  • __init__ 初始化函数:
    • 仅在模型创建时执行 1 次;
    • 作用:定义网络层、自动创建可训练参数(卷积核 + 偏置);
    • 此阶段不做任何图像运算。
  • nn.Conv2d 核心参数详解

    表格

    参数取值含义
    in_channels=3 3 输入通道数,对应 RGB 三通道图像
    out_channels=6 6 输出通道数,代表使用 6 个卷积核,输出 6 组特征图
    kernel_size=3 3 卷积核大小 3×3
    stride=1 1 卷积核滑动步长为 1

    默认参数:padding=0,不补 0。

    5. forward 前向传播函数

    python

    运行

    def forward(self, x):
    x=self.conv2d(x)
    return x

    • 网络真正执行运算的地方;
    • 规则:外部调用 模型实例(输入) 时,PyTorch 会自动执行 forward;
    • 每一批数据都会走一遍该函数,完成卷积计算。

    6. 模型实例化 & 循环推理

    python

    运行

    f=f1() # 创建模型,执行 __init__,初始化卷积核参数

    for data in dataloader:
    imgs,target=data # 解包:图像张量 + 标签
    output =f(imgs) # 传入图像 → 自动调用forward → 执行卷积

    • f(imgs) 是整套代码的运算入口;
    • 卷积输入:[64, 3, 32, 32];
    • 卷积输出尺寸计算: \\((32-3)\\div1 +1 = 30\\) 输出形状:[64, 6, 30, 30]

    7. reshape 与 TensorBoard 可视化

    python

    运行

    output = torch.reshape(output,(-1,3,30,30))

  • 原始输出通道为 6,TensorBoard 仅支持 1/3 通道图片渲染,直接使用会报警告;
  • (-1, 3, 30, 30):
    • -1:自动推导批次维度;
    • 3:强制改为 3 通道,适配 RGB 可视化;
  • 注意:reshape 返回新张量,必须用变量接收,否则修改无效。
  • 8. writer.close()

    将内存中日志完整写入本地文件,防止日志丢失。


    四、两段代码核心对比(重点总结)

    1. 卷积 API 本质区别(最核心)

    表格

    对比项代码 1:F.conv2d(函数式)代码 2:nn.Conv2d(类形式)
    所属模块 torch.nn.functional torch.nn
    参数持有 无内置参数,卷积核手动传入、固定不变 自带 weight/bias 可训练参数,框架自动初始化
    使用位置 任意位置,多用于临时计算、原理演示 写在 __init__ 中,标准网络层写法
    训练属性 卷积核不参与反向传播、无法训练 参数被模型收集,可配合优化器训练更新
    适用场景 学习卷积原理、手动验证计算、固定特征提取 搭建深度学习模型、模型训练、工程实战

    2. 输入数据形式对比

  • 代码 1

    • 输入:手动定义 5×5 二维矩阵(模拟单张灰度图);
    • 维度:手动 reshape 为 [1, 1, 5, 5](单批次、单通道);
    • 数据来源:手动构造张量。
  • 代码 2

    • 输入:CIFAR10 标准数据集,RGB 彩色图;
    • 维度:[64, 3, 32, 32](多批次、三通道);
    • 数据来源:torchvision 官方数据集 + DataLoader 批量加载。
  • 3. 代码结构与执行流程对比

    代码 1 流程(简单流程)

  • 创建矩阵 + 卷积核
  • 统一转为 4 维张量
  • 调用 F.conv2d 直接计算
  • 输出结果
  • 特点:一步计算,无网络结构、无循环、无训练逻辑。

    代码 2 流程(标准深度学习流程)

  • 加载数据集 → DataLoader 分批
  • 定义网络类(继承 nn.Module)
    • __init__:搭建卷积层(仅执行 1 次)
    • forward:定义运算逻辑(循环执行)
  • 实例化模型
  • 循环遍历每一批数据 → 送入模型推理
  • TensorBoard 可视化
  • 特点:工业级标准流程,可直接扩展为训练网络。

    4. 通道数差异

    • 代码 1:单通道图像(C=1),输出单通道特征图;
    • 代码 2:RGB 三通道图像(C=3),卷积输出 6 通道特征图。

    5. reshape 作用差异

    • 代码 1:补全卷积必需的 4 维格式,为了正常执行卷积;
    • 代码 2:修改通道数,为了适配 TensorBoard 可视化。

    五、通用知识点汇总(复习必背)

  • 卷积统一要求 无论哪种卷积方式,输入必须是 4 维张量:[N, C, H, W](批次、通道、高、宽)。

  • 卷积尺寸通用公式 \\(H_{out} = \\frac{H_{in} – kH}{stride} + 1 \\quad (padding=0)\\)

  • 使用选择建议

    • 学习卷积原理、手写验证 → 用 F.conv2d;
    • 搭建模型、训练网络、项目开发 → 用 nn.Conv2d。
  • PyTorch 网络固定分工

    • __init__:定义层、初始化参数(只执行一次);
    • forward:数据前向运算(每一条数据都执行)。
  • TensorBoard 限制 图像可视化仅支持 1 通道(灰度)、3 通道(RGB),多通道特征图需要维度转换才能显示。


  • 六、易错点整理

  • 卷积算子必须 4 维输入,二维矩阵一定要用 reshape 扩维;
  • reshape 不会原地修改张量,必须接收返回值;
  • nn.Module 不要拼写错误(禁止写成 Moudle);
  • F.conv2d 卷积核固定,nn.Conv2d 卷积核可训练;
  • 输入通道数必须和上一层输出通道数保持一致。
  • 赞(0)
    未经允许不得转载:171主机测评 » PyTorch 两种卷积写法彻底对比:F.conv2d 函数式 vs nn.Conv2d 类实战(超详细入门笔记)
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址