CNN (Convolutional Neural Network, 卷积神经网络)

1. 前言:为什么要用卷积?

在 CNN 出现之前,处理图像使用的是全连接网络(MLP)。但 MLP 有两个致命缺陷:

  1. 参数爆炸:一张 1024×10241024 \times 1024 的彩色图片,如果第一层有 1000 个神经元,参数量就超过 30 亿,内存根本存不下。
  2. 丢失空间信息:MLP 需要把图片“拉直”成一维向量,这导致像素之间的左右、上下位置关系全部丢失。

CNN 的核心思想:利用局部感受野(Local Receptive Fields)权值共享(Weight Sharing)。它模拟了人类视觉系统——先看局部特征(边缘、线条),再组合成复杂的形状(眼睛、鼻子),最后识别出物体(脸)。


2. 网络概述:三大核心层

一个标准的 CNN 通常由以下三部分交替堆叠而成:

2.1 卷积层 (Convolutional Layer) —— “提取特征”

卷积核(Kernel)就像一个过滤器,在图像上滑动。它做的是点积运算,提取图像的纹理、颜色和形状。

  • 输入:图像矩阵。
  • 输出:特征图(Feature Map)。

2.2 激活层 (Activation Layer) —— “非线性化”

通常使用 ReLU。如果没有激活层,无论叠多少层卷积,最终都只是线性变换,无法处理复杂的图像模式。

2.3 池化层 (Pooling Layer) —— “降维压缩”

通常使用 Max Pooling。它在保留关键特征的同时,减小特征图的尺寸。

  • 作用:减少计算量,同时防止过拟合,提高模型对物体微小位移的鲁棒性。

3. 详细网络结构:PyTorch 实现

我们手写一个经典的 CNN 结构,包含两个卷积池化层和一个全连接层。

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

class SimpleCNN(nn.Module):
    def __init__(self, num_classes=10):
        super(SimpleCNN, self).__init__()
        
        # 第一层卷积:输入1通道(灰度图),输出32通道,卷积核3x3
        # 输出尺寸计算: (W - K + 2P) / S + 1
        self.conv1 = nn.Conv2d(in_channels=1, out_channels=32, kernel_size=3, padding=1)
        
        # 第二层卷积:输入32,输出64
        self.conv2 = nn.Conv2d(32, 64, kernel_size=3, padding=1)
        
        # 池化层:2x2 窗口,尺寸减半
        self.pool = nn.MaxPool2d(kernel_size=2, stride=2)
        
        # 全连接层
        # 假设输入是 28x28 (MNIST规格),经过两次pool后变为 7x7
        self.fc1 = nn.Linear(64 * 7 * 7, 128)
        self.fc2 = nn.Linear(128, num_classes)

    def forward(self, x):
        # 第一组:卷积 -> ReLU -> 池化
        x = self.pool(F.relu(self.conv1(x)))
        
        # 第二组:卷积 -> ReLU -> 池化
        x = self.pool(F.relu(self.conv2(x)))
        
        # 展平 (Flatten):将 (Batch, 64, 7, 7) 转为 (Batch, 64*7*7)
        x = x.view(-1, 64 * 7 * 7)
        
        # 全连接输出
        x = F.relu(self.fc1(x))
        x = self.fc2(x)
        return x

# 测试模型
model = SimpleCNN()
dummy_input = torch.randn(1, 1, 28, 28)
output = model(dummy_input)
print(f"输入尺寸: {dummy_input.shape}")
print(f"输出尺寸 (类别概率): {output.shape}")

4. CNN 的“四大金刚”参数

在你的 daomanpy.com 教程中,一定要给学员讲清楚这四个参数,这是调参的基础:

  1. Stride (步长):卷积核每次滑动的距离。步长越大,特征图缩小越快。
  2. Padding (填充):在图片边缘补零。作用是保持输出尺寸不变,并保护边缘信息不丢失。
  3. Channel (通道):第一层通常是 3 (RGB),后续层通过卷积核数量增加通道数,代表提取了更多种类的特征。
  4. Receptive Field (感受野):特征图上的一个点能对应原图多大的区域。层数越深,感受野越大。

5. 总结与进阶

为什么 CNN 这么强?

  • 平移不变性:无论猫在图片的左上角还是右下角,卷积核都能通过滑动检测到它。
  • 层次化提取:浅层学线条,中层学器官,深层学语义。

进阶方向:

  • ResNet:引入残差连接,解决深层网络退化问题。
  • MobileNet:使用深度可分离卷积,专门为手机等移动端设计的极速模型。

既然你已经在做 Python AI 教程,下一节需要我为你演示如何利用 Tensorboard 可视化卷积核到底在图片里“看到了”什么吗?这在教学中非常有视觉冲击力。