卷积神经网络CNN

机器学习专题 · 掌握卷积神经网络核心技术

专题:Python机器学习系统学习

关键词:Python, 机器学习, CNN, 卷积神经网络, 卷积层, 池化, ResNet, AlexNet, 图像分类, PyTorch

一、CNN概述

生物启发:视觉皮层

卷积神经网络(Convolutional Neural Network, CNN)的设计灵感来源于生物视觉皮层(visual cortex)的结构。1962年,Hubel和Wiesel通过猫的视觉实验发现,视觉皮层中的神经元只对特定方向的边缘或条状模式产生响应。这种"局部感受野"(local receptive field)机制启发了CNN的核心设计理念:每个神经元只关注输入图像的局部区域,而不是全局信息。

为什么需要CNN

传统的全连接网络在处理图像时面临三个严峻挑战:第一,参数爆炸问题。一张224×224的RGB图像就有224×224×3=150,528个像素值,如果全连接层第一个隐层有1024个神经元,则需要超过1.5亿个参数,训练几乎不可能。第二,空间结构信息的丢失。全连接网络将二维图像展平为一维向量,彻底破坏了像素之间的空间邻接关系。第三,平移不变性缺失。图像中的目标物体不论出现在左上角还是右下角,都应被识别为同一物体,全连接网络无法做到这一点。

CNN的三个核心思想

局部连接(Local Connectivity):每个神经元只与输入的一个局部区域(感受野)相连,大大减少了参数量。例如,一个5×5的卷积核只连接25个输入像素,而不是整张图。

权重共享(Weight Sharing):同一个卷积核在整个输入图像上滑动,参数完全相同。这意味着无论目标出现在图像的任何位置,检测该特征的卷积核都能识别——这是平移不变性的数学基础。

池化(Pooling):对特征图进行下采样,进一步减少参数数量,同时提供局部平移不变性,使模型对微小的位置变化更加鲁棒。

二、卷积层

卷积操作

卷积操作可以理解为用一个可学习的"滤波器"(卷积核)在输入图像上滑动,在每个位置计算滤波器与对应局部区域的点积。这个操作本质上是在检测输入中是否存在特定的局部模式——比如边缘、纹理、角点等。第一层卷积通常检测低级特征(边缘、颜色块),深层卷积则组合低级特征形成高级语义特征(眼睛、车轮、人脸)。

Padding(填充)

卷积操作后特征图的尺寸会缩小,且边缘像素被计算的次数少于中心像素。Padding通过在输入边界周围填充额外的像素(通常为0)来解决这两个问题。常用的模式有两种:

Stride(步长)

步长是卷积核每次滑动的像素数。步长为1时,卷积核逐像素滑动,输出特征图尺寸最大、信息最密集。步长大于1时,特征图尺寸显著减小,相当于同时做卷积和下采样。较大的步长可以减少计算量,但也可能丢失细节信息。

通道与多通道卷积

彩色图像有RGB三个通道,中间层的特征图也可能有多个通道(如64、128、256)。多通道卷积时,每个卷积核的深度与输入通道数相同,即一个卷积核实际上是一个三维张量(高×宽×输入通道数)。输出特征图的通道数等于卷积核的个数。例如,输入RGB图像(3通道),使用64个3×3的卷积核,输出特征图有64个通道。

卷积核/过滤器

卷积核(Kernel/Filter)是CNN中最重要的可学习参数。常见尺寸有1×1、3×3、5×5、7×7。小卷积核(如3×3)参数量小、可堆叠更深、非线性更强,是VGGNet之后的主流选择。1×1卷积核用于改变通道数(降维或升维),是GoogLeNet和ResNet中的重要组件。

输出特征图尺寸计算

假设输入尺寸为H×W,卷积核尺寸为K,Padding为P,Stride为S,则输出特征图尺寸为:

H_out = (H + 2P - K) / S + 1

W_out = (W + 2P - K) / S + 1

结果必须为整数,否则说明超参数不合法。例如,输入32×32,卷积核5×5,Padding=0,Stride=1,输出为28×28;Stride=2时输出为14×14。

PyTorch实现

PyTorch中通过nn.Conv2d实现二维卷积,主要参数包括:

import torch.nn as nn # 定义卷积层:输入通道3(RGB),输出通道64,卷积核3x3 conv = nn.Conv2d(in_channels=3, out_channels=64, kernel_size=3, stride=1, padding=1) # 前向传播:输入形状为 (batch_size, 3, 224, 224) x = torch.randn(4, 3, 224, 224) out = conv(x) # 输出形状: (4, 64, 224, 224)

三、池化层

最大池化(Max Pooling)

最大池化是最常用的池化操作,在池化窗口内取最大值作为输出。例如,2×2的最大池化将输入尺寸减半,每个2×2区域只保留最大值。最大池化擅长保留最突出的特征(如最强的边缘响应),对纹理和边缘检测效果优异。

平均池化(Average Pooling)

平均池化取池化窗口内的平均值,保留区域的整体统计信息而非最突出特征。早期网络中平均池化使用较多,但后来逐渐被最大池化替代。不过,在全局平均池化(Global Average Pooling, GAP)中,平均池化仍有重要应用。

全局平均池化(Global Average Pooling, GAP)

GAP对整个特征图的每个通道取全局平均值,直接将特征图从(通道×高×宽)压缩为(通道×1×1),然后用这个向量直接分类。GAP替代了全连接层,大幅减少了参数量,同时为每个通道赋予了明确的语义含义(每个通道对应一个类别)。GoogLeNet和ResNet都广泛使用了GAP。

池化的作用

PyTorch实现

import torch.nn as nn # 2x2 最大池化,步长为2 maxpool = nn.MaxPool2d(kernel_size=2, stride=2) # 全局平均池化 gap = nn.AdaptiveAvgPool2d((1, 1)) x = torch.randn(4, 64, 28, 28) out = maxpool(x) # 输出: (4, 64, 14, 14) out = gap(x) # 输出: (4, 64, 1, 1)

四、经典CNN架构

LeNet-5:开山之作

1998年由Yann LeCun提出,用于手写数字识别(MNIST数据集)。LeNet-5由两个卷积-池化模块后接三个全连接层组成:第一个卷积使用5×5核输出6个特征图,经过2×2平均池化;第二个卷积使用5×5核输出16个特征图,再经2×2平均池化;最后接三个全连接层输出10类(0-9)。LeNet-5证明了端到端学习的可行性,奠定了现代CNN的基本框架。

AlexNet:ImageNet突破

2012年由Alex Krizhevsky等提出,在ImageNet图像分类竞赛中将top-5错误率从26%降至15.3%,开启了深度学习革命。AlexNet的创新包括:使用ReLU激活函数解决Sigmoid的梯度消失问题;使用Dropout(丢弃率0.5)防止过拟合;使用重叠最大池化(3×3窗口,步长2);在双GPU上并行训练(当时单GPU显存不足);数据增强(随机裁剪、水平翻转)。网络结构为5个卷积层+3个全连接层,参数量约6000万。

VGGNet:小卷积核堆叠

2014年由Oxford的Visual Geometry Group提出。VGGNet的核心贡献是证明了多个小卷积核(3×3)堆叠可以替代大卷积核,同时具有更少的参数量和更强的非线性表达能力。例如,两个3×3卷积堆叠等价于一个5×5卷积的感受野(2层覆盖5×5区域),三个3×3堆叠等价于7×7,但参数量只有后者的(3×3×2)/(7×7)≈55%。VGG16和VGG19是最常用的版本,分别有16层和19层可学习参数。

GoogLeNet / Inception:Inception模块

2014年由Google提出,在相同年的ImageNet竞赛中以更少的参数(约500万,仅为AlexNet的1/12)取得冠军。其核心是Inception模块,在同一层中并行使用1×1、3×3、5×5卷积和3×3最大池化,然后将所有输出在通道维度上拼接。Inception模块的关键技巧是在3×3和5×5卷积之前先使用1×1卷积进行降维,大幅减少了计算量。GoogLeNet还使用辅助分类器缓解梯度消失问题。

ResNet:残差学习

2015年由何恺明等提出,通过残差块(Residual Block)跳跃连接(Skip Connection)解决了深层网络的退化问题(degradation problem)。ResNet的核心思想是让网络学习残差映射F(x)=H(x)-x而非直接映射H(x),这样即使多层不学习任何东西(F(x)=0),网络也能通过恒等映射x传递信息,不会退化。

ResNet有多个变体:ResNet-18、ResNet-34、ResNet-50、ResNet-101和ResNet-152。ResNet-50及以上版本使用"瓶颈块"(Bottleneck Block):先用1×1卷积降维,再用3×3卷积提取特征,最后用1×1卷积升维。ResNet-152有152层但参数量仍可控(约6000万),在ImageNet上top-5错误率降至3.57%,超过人类水平。

核心理解:ResNet的跳跃连接是目前几乎所有深层网络的标准组件。它不仅解决了梯度消失问题,还加速了训练收敛,使得上百层甚至上千层的网络训练成为可能。

DenseNet:密集连接

2017年由Huang Gao等提出,进一步推进了跳跃连接的思想。在DenseNet中,每一层的输入是之前所有层输出的拼接(concatenation),每一层的输出又作为后续所有层的输入。这种密集连接(Dense Connection)带来几个优势:缓解梯度消失(梯度可以直接流向前面的层)、特征复用(每一层都能看到之前所有层的特征)、参数量更少(每层只产生很少的新特征图)。DenseNet的每个"密集块"(Dense Block)内特征图尺寸不变,块之间通过过渡层(Transition Layer)进行降采样。

五、CNN的训练

数据增强(Data Augmentation)

数据增强是在训练时对训练样本施加随机变换,生成更多样化的训练数据,是最有效的防过拟合技术之一。对于图像任务,常用的增强方法包括:随机翻转(水平翻转是最常用的,垂直翻转较少)、随机旋转(通常±10°到±30°)、随机裁剪(从大图中随机裁剪一块,缩放到固定尺寸)、颜色抖动(调整亮度、对比度、饱和度、色调)、随机擦除(Cutout/Random Erasing)、混合增强(Mixup/CutMix将两张图混合)。PyTorch中通过torchvision.transforms实现。

from torchvision import transforms train_transform = transforms.Compose([ transforms.RandomResizedCrop(224), transforms.RandomHorizontalFlip(), transforms.ColorJitter(brightness=0.2, contrast=0.2), transforms.ToTensor(), transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) ])

迁移学习(Transfer Learning)

在计算机视觉领域,几乎没有人从零开始训练完整CNN。迁移学习的做法是:使用在ImageNet等大型数据集上预训练好的模型(如ResNet-50、VGG-16、EfficientNet),然后针对自己的任务进行微调(Fine-tuning)。常见策略有:特征提取(冻结卷积层权重,只训练新添加的分类器层)、全模型微调(整个网络以较小的学习率继续训练)、渐进解冻(逐步从最后一层向前解冻)。迁移学习大大降低了对标注数据量的需求,几千张图片即可训练出高性能模型。

学习率调度(Learning Rate Scheduling)

学习率是CNN训练中最重要的超参数之一。常用的调度策略包括:Step Decay(每N个epoch学习率乘以一个衰减因子,如0.1)、Exponential Decay(按指数连续衰减)、Cosine Annealing(按余弦曲线从高到低变化,可配合热重启)、ReduceLROnPlateau(验证损失不再下降时自动降低学习率)、Warmup(训练初期逐步增大学习率,帮助模型稳定进入收敛状态)。

Batch Normalization

Batch Normalization(BN)是2015年提出的技术,通过在每一层的激活值上做标准化(减均值、除以标准差),然后用可学习的缩放和偏移参数恢复表达能力。BN彻底解决了内部协变量偏移(Internal Covariate Shift)问题,使训练可以使用更大的学习率、更少关注初始化、加速收敛数十倍。在现代CNN中,BN已成为标配,通常放在卷积层之后、激活函数之前。

六、CNN的应用

图像分类

图像分类是CNN最基础也最成熟的应用,输入一张图像,输出类别标签。从LeNet-5到EfficientNet,CNN在ImageNet上的top-5错误率已从16.4%降至2%以下,远超人类水平(约5.1%)。经典分类网络包括:AlexNet、VGG、GoogLeNet、ResNet、DenseNet、EfficientNet、ConvNeXt等。

目标检测(Object Detection)

目标检测同时完成两个任务:定位图像中物体的位置(输出边界框)和识别物体类别。主流方法分为两大流派:

图像分割(Image Segmentation)

图像分割是对每个像素进行分类,分为语义分割(同一类别的多个实例不加区分)和实例分割(区分同一类别的不同个体):

人脸识别(Face Recognition)

人脸识别是CNN在生物识别领域的典型应用。DeepFace和FaceNet是里程碑工作:FaceNet使用三元组损失(Triplet Loss)将人脸图像映射到欧几里得空间,使得同一人的特征向量距离近、不同人的距离远。现代人脸识别系统使用Margin-based Softmax变体(如ArcFace、CosFace)进一步提升了判别能力,在LFW(Labeled Faces in the Wild)数据集上准确率超过99.8%。

图像生成(DCGAN)

DCGAN(Deep Convolutional GAN)将CNN引入生成对抗网络。生成器使用转置卷积(Transposed Convolution)从随机噪声逐步生成逼真图像,判别器使用下采样CNN区分真假图像。DCGAN带来若干重要经验:使用批归一化(生成器和判别器几乎所有层都加BN)、使用Adam优化器、全卷积架构(避免全连接层)、使用LeakyReLU激活函数。DCGAN为后续的StyleGAN、BigGAN等高质量图像生成模型奠定了基础。