卷积神经网络(CNN)专为处理网格结构数据(如图像、语音)设计的深度学习模型,其内部构造通过模拟人类视觉系统的层级特征提取机制,实现从低级到高级的特征学习。

CNN 的核心构造由多个功能模块有序组合而成,每个模块承担特定任务,共同完成 “特征提取→特征整合→决策输出” 的全过程。

为防止文字讲解过于抽象我们结合代码一起解释卷积神经网络

首先下面展示的是一段简单的CNN结构:

import torch
import torch.nn as nn
import torch.nn.functional as F

class SimpleCNN(nn.Module):
    def __init__(self):
        super(SimpleCNN, self).__init__()
        self.conv1 = nn.Conv2d(1, 32, 3, 1)
        self.conv2 = nn.Conv2d(32, 64, 3, 1)
        self.fc1 = nn.Linear(64 * 12 * 12, 128)
        self.fc2 = nn.Linear(128, 10)
        self.max_pool = nn.MaxPool2d(2)
        self.dropout = nn.Dropout(0.25)

    def forward(self, x):
        x = F.relu(self.conv1(x))
        x = self.max_pool(F.relu(self.conv2(x)))
        x = torch.flatten(x, 1)
        x = F.relu(self.fc1(x))
        x = self.dropout(x)
        x = self.fc2(x)
        return x


# 实例化模型
model = SimpleCNN()
print(model)

对于新手,我们可能只能看出来这段代码导入了torch包还构建了一个SimpleCNN的类,下面我将逐行解释这段代码的使用.

导入PyTorch的神经网络模块和函数式接口

import torch
import torch.nn as nn
import torch.nn.functional as F

定义名为 SimpleCNN 的神经网络类,继承自 PyTorch 的 nn.Module 基类

class SimpleCNN(nn.Module):
    def __init__(self):
        super(SimpleCNN, self).__init__()

这里或许会有一些疑问,为什么要继承nn.Module,或者会问这个是什么东西

你可以按住ctrl再将鼠标拖到这个Module处,可以看到这里可以点进去,如下图一般:

点进去后会有一段解释

我在这里大致解释说明一下,nn.Module

nn.Module是 PyTorch 所有神经网络模块的基类,它提供了构建和训练模型的核心功能框架:

  1. 参数管理:①自动跟踪所有定义在类中的nn.Parameter(如卷积核权重、全连接层权重),可通过module.parameters()统一访问。②支持参数初始化、梯度计算、权重更新等操作(如优化器直接作用于module.parameters())。

  2. 模块化设计:允许嵌套子模块(如将多个卷积层封装为一个特征提取器),形成树形结构,便于组织复杂网络。

  3. 前向传播定义:通过实现forward()方法定义数据流向,使模型可像函数一样被调用(如output = model(input))。

  4. 状态管理:提供训练 / 评估模式切换(model.train()/model.eval()),影响如 Dropout、BatchNorm 等层的行为。

  5. 序列化支持:支持模型保存 / 加载(torch.save(model.state_dict(), path)),方便迁移学习和部署。

创建第一个卷积层(提取特征):

self.conv1 = nn.Conv2d(1, 32, 3, 1)

四个参数分别对应:输入通道数=1,输出通道数=32,卷积核大小=3×3,步长=1。

进一步解释一下,输入通道数为1的意思就是输入一张图像(灰色表示无颜色通道之分,故通道数=1),输出通道数为32表示使用了32个不同的卷积核,每个卷积核会生成一个独立的特征图(Feature Map),这些特征图的尺寸相同但是内容不同。

而这时的特征图尺寸是多少呢,我们可以来计算一下:

一般对于MNIST手写数字数据集(单通道灰度图),输入尺寸为28×28像素(关键基础,接下来每一层的特征图计算都会基于这个计算数字),输入层的输入尺寸:1×28×28(通道数×高度×宽度)

卷积层输出尺寸计算:

高度/宽度=(输入尺寸-卷积核+2×填充)/步长+1(此处的填充也就是Conv2d中的一个参数pedding)

               =(28-3+0)/1+1=26

故输出尺寸:32×26×26

创建第二个卷积层(与第一个卷积层思路一样,这里就不过多赘述)

self.conv2 = nn.Conv2d(32, 64, 3, 1)

创建第一个全连接层(将前序层提取的局部特征整合为全局特征,最终用于分类、回归等任务

self.fc1 = nn.Linear(64*12*12, 128)

全连接层的输入必须是一维向量,因此需先将前序层(如卷积层、池化层)输出的高维特征展平(Flatten)为一维向量,就是全连接层的输入特征数。

假设卷积层输出的特征图形状为(32,7,7)展平后的一维向量长度为:32×7×7=1568,则全连接层的输入特征数为1568

输入特征数=64×12×12(前序层输出的特征图展平后的大小)、

输出特征数=128

创建第二个全连接层

self.fc2 = nn.Linear(128, 10)

输入特征数=128

输出特征数=10(对应10个分类类别)

创建最大池化层(用于减少特征图的尺寸,降低计算复杂度,并在一定程度上防止过拟合)

self.max_pool = nn.MaxPool2d(2)

池化窗口大小=2×2,步长默认为2(与窗口大小相同),填充默认为0。

输出尺寸计算:

高度/宽度=输入尺寸/步长=24/2=12  (这里为什么是24呢我们后面会进行总体计算进行解释)

输出尺寸=64×12×12

创建Dropout层(防止模型过拟合,通过随机丢弃一部分神经元来增强模型的泛化能力)

self.dropout = nn.Dropout(0.25)

丢弃率=0.25(训练时随机忽略25%的神经元,防止过拟合)

定义前向传播过程

 def forward(self, x):
        x = F.relu(self.conv1(x))
        x = self.max_pool(F.relu(self.conv2(x)))
        x = torch.flatten(x, 1)
        x = F.relu(self.fc1(x))
        x = self.dropout(x)
        x = self.fc2(x)
        return x

输入X经过第一个卷积层,应用ReLU激活函数引入非线性;

输入X经过第二个卷积层,通过最大池化层进行降维;

将多维特征图展平为一维向量;

输入X经过第一个全连接层,应用ReLU激活函数;

应用Dropout正则化,训练时随机丢弃部分神经元;

输入X经过第二个全连接层,输出10维的原始得分,通常配合softmax进行分类。

以上就是SimpleCNN的总体框架,我们下面进行整体的计算(根据forward函数的流程):

输入层:灰色图像(1×28×28)

第一个卷积层(前面已经计算过了):32×26×26

第二个卷积层:高度/宽度=(26-3+0)/1+1=24,输出尺寸:64×24×24

最大池化层:高度/宽度=24/2=12,输出尺寸:64×12×12

展平操作:三维向量展平为一维向量:64×12×12=9216

第一个全连接层:将输入的9216维向量映射为128维向量,包含线性变化和ReLU激活:

                              线性变换:  

                                               

                             对每个样本i的第j个神经元的计算:

                              ReLU激活:

                              对每个元素的计算:

Dropout操作:

                     

第二个全连接层计算:将128维向量映射到10维向量:

                                      线性变换:

                                                      

                                      对每个样本i的第j个神经元的计算:

最终结果如图所示:

以上就是今天学习的全部内容,主要是搞懂CNN中的简单架构,有利于我们接下来更深入的学习

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐