第九章:卷积神经网络(CNN)
学习目标
- 理解CNN的定义及其为什么适合处理图像
- 掌握卷积操作的原理和特征提取的层次性
- 理解池化层和全连接层的作用
- 了解经典CNN架构(AlexNet、VGG、ResNet等)
- 能够使用PyTorch构建简单的CNN模型
前置要求
第五章:深度学习概述(理解神经网络的基本结构和激活函数)。
CNN概述
CNN(Convolutional Neural Network,卷积神经网络)专门处理图像数据,能自动识别图像中的特征。它是图像识别、目标检测、人脸识别等视觉任务的核心技术。
为什么CNN适合处理图像?
图像是由像素组成的网格,相邻像素之间有关系(比如边缘是一条连续的线)。CNN能保留空间关系,不像传统方法把图像变成一串数字。它用"小窗口"扫描图像,就像人用眼睛逐区域观察一样。
CNN核心组件详解
1. 卷积层——特征提取的核心
卷积层是CNN最重要的部分。它使用滤波器(Filter/Kernel)在图像上滑动扫描,提取各种特征。
滤波器是什么?
滤波器是一个小矩阵(比如3×3),里面放着不同的数字权重。
• 边缘滤波器:能检测图像中的线条和边缘
• 纹理滤波器:能识别特定的纹理模式
• 颜色滤波器:能检测特定的颜色分布
一个卷积层可能有几十到几百个不同的滤波器,每个学习识别一种特征。
卷积操作的原理
想象你有一个小窗口(3×3像素),在图像上从左到右、从上到下滑动:
- 定位:窗口放在图像的某个位置
- 计算:窗口内的像素值与滤波器权重相乘,然后求和
- 输出:得到一个新的数值(特征值)
- 移动:窗口向右移动一格,重复上述过程
- 完成:扫描完整个图像,生成一张"特征图"
(224×224像素)
(多个滤波器扫描)
(每张对应一种特征)
卷积操作的Python/NumPy代码示例
import numpy as np
# 简单的5x5输入图像(灰度)
image = np.array([
[10, 10, 10, 0, 0],
[10, 10, 10, 0, 0],
[10, 10, 10, 0, 0],
[ 0, 0, 0, 10, 10],
[ 0, 0, 0, 10, 10]
], dtype=float)
# 3x3边缘检测滤波器(水平边缘)
kernel = np.array([
[-1, -1, -1],
[ 0, 0, 0],
[ 1, 1, 1]
], dtype=float)
# 手动实现2D卷积
def conv2d(image, kernel):
ih, iw = image.shape
kh, kw = kernel.shape
oh, ow = ih - kh + 1, iw - kw + 1
output = np.zeros((oh, ow))
for i in range(oh):
for j in range(ow):
region = image[i:i+kh, j:j+kw]
output[i, j] = np.sum(region * kernel)
return output
result = conv2d(image, kernel)
print("卷积结果(特征图):")
print(result)
# 输出: 检测到水平边缘的位置会有较大数值
特征提取的层次性
| 层数 | 提取的特征 | 例子 |
|---|---|---|
| 浅层(第1-2层) | 基础视觉元素 | 边缘、线条、简单颜色块 |
| 中层(第3-5层) | 形状和部件 | 圆形、方形、眼睛形状、轮子形状 |
| 深层(第6-N层) | 完整物体 | 人脸、汽车、猫、狗的整体形态 |
实例:CNN如何识别一张猫的照片
第1层卷积:检测到边缘线条 → 发现猫轮廓的边界
第2层卷积:检测到形状 → 发现圆形的眼睛、三角形的耳朵
第3层卷积:检测到部件 → 眼睛+耳朵+胡须的组合
第4层卷积:检测到整体 → "这像是猫的脸"
全连接层:综合判断 → 输出"这是猫(概率98%)"
2. 池化层——降维与关键特征保留
池化层的作用是缩小特征图的尺寸,同时保留最重要的特征信息。
为什么需要池化?
• 减少计算量:特征图太大,计算成本高
• 防止过拟合:去除过多细节,保留核心特征
• 增强鲁棒性:即使图像稍微移动、缩放,关键特征仍能被识别
常见池化方式
| 池化类型 | 原理 | 特点 |
|---|---|---|
| 最大池化(Max Pooling) | 在区域内取最大值 | 保留最强特征,最常用 |
| 平均池化(Average Pooling) | 在区域内取平均值 | 保留整体趋势,较平滑 |
3. 全连接层——最终分类决策
全连接层将前面提取的所有特征综合起来,做出最终判断。
- 接收输入:来自最后一层卷积/池化的特征
- 综合判断:将所有特征"投票"决定类别
- 输出结果:每个类别的概率值(如:猫90%、狗5%、鸟5%)
(多次)
(穿插)
著名CNN架构
| 架构 | 年份 | 特点 | 贡献 |
|---|---|---|---|
| AlexNet | 2012 | 8层,首次使用ReLU | 开启深度学习时代 |
| VGG | 2014 | 16-19层,结构简洁 | 证明层数深效果好 |
| ResNet | 2015 | 残差连接,突破100层 | 解决深层网络训练难问题 |
| YOLO | 2016 | 实时目标检测 | 速度与精度平衡 |
CNN的局限
• 主要处理图像,不适合序列数据(文本、语音)
• 对图像旋转、翻转敏感(需要数据增强)
• 需要大量标注数据训练
• 计算资源需求较大
使用PyTorch构建简单CNN
下面展示如何用PyTorch构建一个用于图像分类的简单CNN:
import torch
import torch.nn as nn
import torch.nn.functional as F
class SimpleCNN(nn.Module):
"""简单的CNN模型,用于手写数字识别(MNIST)"""
def __init__(self):
super(SimpleCNN, self).__init__()
# 第一个卷积层:1通道输入,32个滤波器,3x3窗口
self.conv1 = nn.Conv2d(1, 32, kernel_size=3, padding=1)
# 第二个卷积层:32通道输入,64个滤波器
self.conv2 = nn.Conv2d(32, 64, kernel_size=3, padding=1)
# 全连接层
self.fc1 = nn.Linear(64 * 7 * 7, 128) # 28x28图像经过两次池化后为7x7
self.fc2 = nn.Linear(128, 10) # 10个类别(数字0-9)
# Dropout层防止过拟合
self.dropout = nn.Dropout(0.25)
def forward(self, x):
# 第一层:卷积 → ReLU → 最大池化
x = F.relu(self.conv1(x)) # 输出: 32 x 28 x 28
x = F.max_pool2d(x, 2) # 输出: 32 x 14 x 14
# 第二层:卷积 → ReLU → 最大池化
x = F.relu(self.conv2(x)) # 输出: 64 x 14 x 14
x = F.max_pool2d(x, 2) # 输出: 64 x 7 x 7
# 展平为一维向量
x = x.view(-1, 64 * 7 * 7) # 输出: 3136
# 全连接层 + Dropout
x = F.relu(self.fc1(x))
x = self.dropout(x)
x = self.fc2(x) # 输出: 10(各类别得分)
return x
# 创建模型实例
model = SimpleCNN()
print(f"模型参数总量: {sum(p.numel() for p in model.parameters()):,}")
# 输出: 模型参数总量: 540,850
# 模拟前向传播
dummy_input = torch.randn(1, 1, 28, 28) # 批量大小1,1通道,28x28图像
output = model(dummy_input)
print(f"输出形状: {output.shape}") # 输出: torch.Size([1, 10])
本章小结
- CNN是专为图像处理设计的深度学习架构,通过卷积操作保留空间关系,逐层提取从简单到复杂的特征。
- 卷积层使用滤波器在图像上滑动扫描,提取边缘、形状、物体等层次化特征。
- 池化层缩小特征图尺寸,减少计算量并增强鲁棒性;全连接层综合所有特征做出分类决策。
- 经典CNN架构包括AlexNet(开启深度学习时代)、VGG(证明深层有效)、ResNet(残差连接突破深度限制)。
- CNN的局限包括:主要处理图像、对旋转敏感、需要大量标注数据和计算资源。
练习题
-
CNN中卷积层的主要作用是什么?
A. 将图像展平为一维向量
B. 使用滤波器在图像上滑动扫描,提取特征
C. 将特征图缩小到固定尺寸
D. 计算各类别的概率答案:B。卷积层使用滤波器在图像上滑动扫描,通过加权求和提取各种特征。
-
以下哪种池化方式最常用于CNN中?
A. 最小池化(Min Pooling)
B. 中值池化(Median Pooling)
C. 最大池化(Max Pooling)
D. 随机池化(Random Pooling)答案:C。最大池化在区域内取最大值,保留最强特征,是CNN中最常用的池化方式。
-
ResNet的核心创新是什么?
A. 使用更大的滤波器
B. 引入残差连接(跳跃连接)
C. 去掉全连接层
D. 使用循环结构答案:B。ResNet通过残差连接(跳跃连接)让梯度可以直接流过浅层,解决了深层网络训练困难的问题。