FA_CNN卷积神经网络二---PyTorch

FA :Formulas and Algorithm,CNN:Convolutional Neural Network

1. 引言

卷积神经网络(CNN)是深度学习中最经典的网络结构之一,在图像分类、目标检测等领域有着广泛的应用。本文将从卷积的基本原理出发,结合 PyTorch 框架,手把手带你搭建一个简单的卷积层,并通过 CIFAR10 数据集进行实战演示,最后使用 TensorBoard 可视化卷积前后的图像变化。

2. 卷积原理

在开始写代码之前,我们先来理解卷积的核心概念。

2.1 什么是卷积

卷积操作本质上是一个特征提取的过程:通过一个可学习的卷积核(kernel)在输入数据上滑动,逐位置计算加权和,从而提取出局部特征。

2.2 一维、二维与三维卷积

PyTorch 中提供了三种常用的卷积类:

  • Conv1d:一维卷积,常用于处理序列数据(如文本、音频、时间序列)。
  • Conv2d:二维卷积,常用于处理图像数据,是本文的主角。
  • Conv3d:三维卷积,常用于处理视频、医学影像等立体数据。

2.3 卷积核(kernel_size)

卷积核是卷积操作的核心参数。以 kernel_size=3 为例,它表示使用一个 3 × 3 的卷积核在图像上滑动。

在训练过程中,卷积核中的数值会通过反向传播不断调整优化,最终学习到能够提取有效特征的参数。可以说,训练神经网络的过程,本质上就是对卷积核参数不断调整的过程。

2.4 输入与输出的关系

卷积层的输出尺寸由输入尺寸、卷积核大小、步长(stride)和填充(padding)共同决定。在下面的实战中,我们将通过代码直观地看到输入输出尺寸的变化。

  • Input: (N,Cin,Hin,Win)(N, C_{in}, H_{in}, W_{in})(N,Cin,Hin,Win)
  • Output: (N,Cout,Hout,Wout)(N, C_{out}, H_{out}, W_{out})(N,Cout,Hout,Wout) where

Hout=⌊Hin+2×padding0−dilation0×(kernel_size0−1)−1stride0+1⌋ H_{out} = \left\lfloor \frac{H_{in} + 2 \times \text{padding}0 - \text{dilation}0 \times (\text{kernel\_size}0 - 1) - 1}{\text{stride}0} + 1 \right\rfloor Hout=⌊stride0Hin+2×padding0−dilation0×(kernel_size0−1)−1+1⌋

Wout=⌊Win+2×padding1−dilation1×(kernel_size1−1)−1stride1+1⌋ W_{out} = \left\lfloor \frac{W_{in} + 2 \times \text{padding}1 - \text{dilation}1 \times (\text{kernel\_size}1 - 1) - 1}{\text{stride}1} + 1 \right\rfloor Wout=⌊stride1Win+2×padding1−dilation1×(kernel_size1−1)−1+1⌋

3. 搭建卷积层

下面我们使用 PyTorch 搭建一个简单的卷积神经网络模型。

3.1 导入依赖

python 复制代码
import torch
from torch import nn
import torchvision
from torch.nn import Conv2d
from torch.utils.data import DataLoader

3.2 加载 CIFAR10 数据集

python 复制代码
dataset = torchvision.datasets.CIFAR10(
    "./dataset",
    train=False,
    transform=torchvision.transforms.ToTensor(),
    download=True
)

dataloader = DataLoader(dataset, batch_size=64)

3.3 定义卷积网络模型

python 复制代码
class Tudui(nn.Module):
    def __init__(self):
        super(Tudui, self).__init__()
        # 彩色图像输入为 3 层,我们想让它的输出为 6 层,选用 3 * 3 的卷积核
        self.conv1 = Conv2d(
            in_channels=3,
            out_channels=6,
            kernel_size=3,
            stride=1,
            padding=0
        )

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

3.4 实例化模型并查看结构

python 复制代码
tudui = Tudui()
print(tudui)

运行结果:

text 复制代码
Files already downloaded and verified
Tudui(
  (conv1): Conv2d(3, 6, kernel_size=(3, 3), stride=(1, 1))
)

可以看到,模型包含一个 Conv2d 卷积层,输入通道为 3,输出通道为 6,卷积核大小为 3 × 3。

4. 卷积层处理图片

接下来,我们让卷积层真正处理一批图片,观察输入和输出的尺寸变化。

python 复制代码
import torch
import torchvision
from torch import nn
from torch.nn import Conv2d
from torch.utils.data import DataLoader

dataset = torchvision.datasets.CIFAR10(
    "./dataset",
    train=False,
    transform=torchvision.transforms.ToTensor(),
    download=True
)

dataloader = DataLoader(dataset, batch_size=64)


class Tudui(nn.Module):
    def __init__(self):
        super(Tudui, self).__init__()
        # 彩色图像输入为 3 层,我们想让它的输出为 6 层,选用 3 * 3 的卷积核
        self.conv1 = Conv2d(
            in_channels=3,
            out_channels=6,
            kernel_size=3,
            stride=1,
            padding=0
        )

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


tudui = Tudui()

for data in dataloader:
    imgs, targets = data
    output = tudui(imgs)
    print(imgs.shape)   # 输入为 3 通道 32×32 的 64 张图片
    print(output.shape) # 输出为 6 通道 30×30 的 64 张图片

运行结果(节选):

text 复制代码
Files already downloaded and verified
torch.Size([64, 3, 32, 32])
torch.Size([64, 6, 30, 30])
torch.Size([64, 3, 32, 32])
torch.Size([64, 6, 30, 30])
torch.Size([64, 3, 32, 32])
torch.Size([64, 6, 30, 30])
...

4.1 结果分析

从输出结果可以清晰地看到:

  • 输入 :[64, 3, 32, 32],表示 64 张 32 × 32 的彩色图片(3 通道)。
  • 输出 :[64, 6, 30, 30],表示 64 张 30 × 30 的图片,通道数变为 6。

这是因为卷积核大小为 3 × 3、步长为 1、无填充,导致图像尺寸从 32 × 32 缩小为 30 × 30;同时输出通道数由 3 变为 6,实现了特征的提取与升维。

5. TensorBoard 可视化

为了更直观地观察卷积前后的变化,我们使用 TensorBoard 将输入图像和卷积后的输出图像可视化。

5.1 完整代码

python 复制代码
import torch
import torchvision
from torch import nn
from torch.nn import Conv2d
from torch.utils.data import DataLoader
from torch.utils.tensorboard import SummaryWriter

dataset = torchvision.datasets.CIFAR10(
    "./dataset",
    train=False,
    transform=torchvision.transforms.ToTensor(),
    download=True
)

dataloader = DataLoader(dataset, batch_size=64)


class Tudui(nn.Module):
    def __init__(self):
        super(Tudui, self).__init__()
        # 彩色图像输入为 3 层,我们想让它的输出为 6 层,选用 3 * 3 的卷积核
        self.conv1 = Conv2d(
            in_channels=3,
            out_channels=6,
            kernel_size=3,
            stride=1,
            padding=0
        )

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


tudui = Tudui()
writer = SummaryWriter("logs")
step = 0

for data in dataloader:
    imgs, targets = data
    output = tudui(imgs)
    print(imgs.shape)
    print(output.shape)

    writer.add_images("input", imgs, step)

    # 把原来 6 个通道拉为 3 个通道,为了保证所有维度总数不变,其余的分量分到第一个维度中
    output = torch.reshape(output, (-1, 3, 30, 30))
    writer.add_images("output", output, step)

    step = step + 1

5.2 启动 TensorBoard

在 Anaconda 终端中,激活对应的 Python 环境(如 py3.6.3),然后输入以下命令:

bash 复制代码
tensorboard --logdir=C:\Users\wangy\Desktop\03CV\logs

将输出的网址复制到浏览器地址栏并回车,即可查看 TensorBoard 中卷积前后的图像对比。

6. 总结

本文从卷积的基本原理出发,完成了以下内容:

  1. 理解了 Conv1d / Conv2d / Conv3d 的区别与适用场景。
  2. 掌握了 kernel_size 的含义及其在训练中的动态调整机制。
  3. 使用 PyTorch 搭建了包含 Conv2d 的简单网络模型。
  4. 通过 CIFAR10 数据集实战,直观看到了卷积前后输入输出尺寸的变化。
  5. 使用 TensorBoard 可视化卷积前后的图像,加深对卷积特征提取的理解。

卷积层是构建更复杂 CNN(如 LeNet、VGG、ResNet 等)的基础模块。掌握了本文的内容,你就迈出了深度学习图像处理的第一步。接下来可以尝试调整 kernel_size、stride、padding 等参数,观察输出尺寸的变化,进一步加深理解。

相关推荐
镜象科技1 小时前
校园抑郁筛查实战:匿名、隐私与信任的平衡
人工智能
远航计算机1 小时前
AI 看不见图,它只读旁边的字
人工智能·chatgpt·aigc
tq10861 小时前
AI 时代 UX 的范式重构:从空间寻路到注意力分配
人工智能
玫瑰互动GEO1 小时前
把GeoReady九维当工程项做:储能管理官网的AI就绪度改造笔记
人工智能·ai·ai搜索·seo优化·豆包·deepseek·geo优化
小肝一下1 小时前
1.大模型介绍
python·langchain·大模型·ollama·langgrap
文慧的科技江湖1 小时前
2026年10月21日充电桩行业招投标早报:平台第一次进了标的名字,还是没进报价表
大数据·人工智能·开源·新能源·充电桩·新能源汽车·招投标
xiangjiaodalishi1 小时前
从 0 到 1 搭建 AI 友好的网站结构:信息架构与 GEO 的交叉地带
人工智能·python
生石花1 小时前
TRAE Agent 模式实战:让它帮我写 WMS 的 RAG 工具路由,它连防御都替我写了
人工智能