1. 概述
1.1 什么是卷积神经网络(CNN)?
- 定义: 卷积神经网络(Convolutional Neural Network, CNN)是一种用于处理具有网格状拓扑结构数据的深度学习模型,特别适合处理图像、视频等数据。
- 起源与发展: CNN 最初是为解决计算机视觉问题设计的,并逐渐扩展到自然语言处理、医学影像分析等领域。
- 核心思想: 使用卷积操作提取局部特征,通过层叠结构逐层提取更高维的抽象特征。
1.2 为什么选择 CNN?
- 图像处理的复杂度高,传统全连接网络在处理高分辨率图片时需要大量参数,导致计算代价巨大。
- CNN 的局部连接与权重共享机制大幅减少了参数量,同时保留了关键特征,提高了模型的训练效率和泛化能力。
1.3 CNN 的主要任务
- 分类: 将整张图像划归到某个类别。
- 目标检测: 识别图像中目标的位置和类别。
- 图像分割: 对图像中的每个像素进行分类(例如语义分割和实例分割)。
2. CNN 的核心组成部分
2.1 卷积层(Convolutional Layer)
-
功能: 提取输入数据中的局部特征,例如边缘、角点、纹理等。
-
卷积核:
- 定义: 卷积核是一个小矩阵(例如 3×3),用于在图像上滑动,提取局部信息。
-
作用: 每个卷积核负责提取一种特定的特征。
- 参数: 卷积核的数量、大小、权重等由模型设计决定。
-
卷积过程:
- 将卷积核与输入的局部区域逐点相乘,并将结果累加生成特征图。
-
每次滑动卷积核后,生成一个新的特征点。
-
权重共享:
- 减少参数数量:每个卷积核在整个图像中共享一组权重。
-
提高训练效率:减少计算资源需求,同时增强特征提取的一致性。
import torch
import torch.nn as nn
import matplotlib.pyplot as plt
import osdef showimg(img):plt.imshow(img)# 隐藏刻度plt.axis("off")plt.show()def test001():dir = os.path.dirname(__file__)img = plt.imread(os.path.join(dir, "彩色.png"))# 创建卷积核# in_channels:输入数据的通道数# out_channels:输出特征图数,和filter数一直conv = nn.Conv2d(in_channels=4, out_channels=1, kernel_size=3, stride=1, padding=1)# 注意:卷积层对输入的数据有形状要求 [batch, channel, height, width]# 需要进行形状转换 H, W, C -> C, H, Wimg = torch.tensor(img, dtype=torch.float).permute(2, 0, 1)print(img.shape)# 接着变形:CHW -> NCHWnewimg = img.unsqueeze(0)print(newimg.shape)# 送入卷积核运算一下newimg = conv(newimg)print(newimg.shape)# 蒋BCHW->HWCnewimg = newimg.squeeze(0).permute(1, 2, 0)showimg(newimg.detach().numpy())# 多卷积核
def test002():dir = os.path.dirname(__file__)img = plt.imread(os.path.join(dir, "彩色.png"))# 定义一个多特征图输出的卷积核conv = nn.Conv2d(in_channels=4, out_channels=3, kernel_size=3, stride=1, padding=1)# 图形要进行变形处理img = torch.tensor(img).permute(2, 0, 1).unsqueeze(0)# 使用卷积核对图片进行卷积计算outimg = conv(img)print(outimg.shape)# 把图形形状转换回来以方便显示outimg = outimg.squeeze(0).permute(1, 2, 0)print(outimg.shape)# showimg(outimg)# 显示这些特征图for idx in range(outimg.shape[2]):showimg(outimg[:, :, idx].squeeze(-1).detach())if __name__ == "__main__":test002()
2.2 池化层(Pooling Layer)
-
功能: 对特征图进行降维,减少参数量与计算量,同时增强模型的鲁棒性。
-
类型:
-
最大池化: 取池化窗口内的最大值,适合提取显著特征。
-
平均池化: 取池化窗口内的平均值,更适合获取全局特征。
-
步长与窗口大小:
-
池化窗口(如 2×2)的大小和步长决定了输出特征图的尺寸。
-
较大的步长可以更大程度地压缩数据,但可能丢失更多细节信息。
-
边缘填充(Padding):
- 填充边界数据以保持特征图尺寸不变,特别适用于需要多层池化的网络。
池化的API
import torch
import torch.nn as nn# 1. API 基本使用
def test01():inputs = torch.tensor([[0, 1, 2], [3, 4, 5], [6, 7, 8]]).float()inputs = inputs.unsqueeze(0).unsqueeze(0)# 1. 最大池化# 输入形状: (N, C, H, W)polling = nn.MaxPool2d(kernel_size=2, stride=1, padding=0)output = polling(inputs)print(output)# 2. 平均池化polling = nn.AvgPool2d(kernel_size=2, stride=1, padding=0)output = polling(inputs)print(output)# 2. stride 步长
def test02():inputs = torch.tensor([[0, 1, 2, 3], [4, 5, 6, 7], [8, 9, 10, 11], [12, 13, 14, 15]]).float()inputs = inputs.unsqueeze(0).unsqueeze(0)# 1. 最大池化polling = nn.MaxPool2d(kernel_size=2, stride=2, padding=0)output = polling(inputs)print(output)# 2. 平均池化polling = nn.AvgPool2d(kernel_size=2, stride=2, padding=0)output = polling(inputs)print(output)# 3. padding 填充
def test03():inputs = torch.tensor([[0, 1, 2], [3, 4, 5], [6, 7, 8]]).float()inputs = inputs.unsqueeze(0).unsqueeze(0)# 1. 最大池化polling = nn.MaxPool2d(kernel_size=2, stride=1, padding=1)output = polling(inputs)print(output)# 2. 平均池化polling = nn.AvgPool2d(kernel_size=2, stride=1, padding=1)output = polling(inputs)print(output)# 4. 多通道池化
def test04():inputs = torch.tensor([[[0, 1, 2], [3, 4, 5], [6, 7, 8]],[[10, 20, 30], [40, 50, 60], [70, 80, 90]],[[11, 22, 33], [44, 55, 66], [77, 88, 99]]]).float()inputs = inputs.unsqueeze(0)# 最大池化polling = nn.MaxPool2d(kernel_size=2, stride=1, padding=0)output = polling(inputs)print(output)if __name__ == '__main__':test04()
2.3 全连接层(Fully Connected Layer)
- 功能: 将前面卷积层和池化层提取的高维特征映射到分类空间。
- 结构: 与传统的神经网络类似,所有输入节点与输出节点全连接。
- 缺点: 参数量巨大,容易导致过拟合。
2.4 激活函数
-
常用激活函数:
- ReLU: 将负值设为 0,引入非线性,提高表达能力。
-
Sigmoid 和 Tanh: 在深度网络中容易导致梯度消失问题,不适合较深的网络。
- Leaky ReLU: 允许负值通过,解决 ReLU 的“神经元死亡”问题。
卷积层API的实现
import torch
import torch.nn as nn
import matplotlib.pyplot as plt
import osdef showimg(img):plt.imshow(img)# 隐藏刻度plt.axis("off")plt.show()def test001():dir = os.path.dirname(__file__)img = plt.imread(os.path.join(dir, "彩色.png"))# 创建卷积核# in_channels:输入数据的通道数# out_channels:输出特征图数,和filter数一直conv = nn.Conv2d(in_channels=4, out_channels=1, kernel_size=3, stride=1, padding=1)# 注意:卷积层对输入的数据有形状要求 [batch, channel, height, width]# 需要进行形状转换 H, W, C -> C, H, Wimg = torch.tensor(img, dtype=torch.float).permute(2, 0, 1)print(img.shape)# 接着变形:CHW -> BCHWnewimg = img.unsqueeze(0)print(newimg.shape)# 送入卷积核运算一下newimg = conv(newimg)print(newimg.shape)# 蒋BCHW->HWCnewimg = newimg.squeeze(0).permute(1, 2, 0)showimg(newimg.detach().numpy())# 多卷积核
def test002():dir = os.path.dirname(__file__)img = plt.imread(os.path.join(dir, "彩色.png"))# 定义一个多特征图输出的卷积核conv = nn.Conv2d(in_channels=4, out_channels=3, kernel_size=3, stride=1, padding=1)# 图形要进行变形处理img = torch.tensor(img).permute(2, 0, 1).unsqueeze(0)# 使用卷积核对图片进行卷积计算outimg = conv(img)print(outimg.shape)# 把图形形状转换回来以方便显示outimg = outimg.squeeze(0).permute(1, 2, 0)print(outimg.shape)# showimg(outimg)# 显示这些特征图for idx in range(outimg.shape[2]):showimg(outimg[:, :, idx].squeeze(-1).detach())if __name__ == "__main__":test002()
3. CNN 的计算与优化细节
3.1 卷积计算过程
-
输入图像通过卷积层后生成特征图,其计算公式为:
Output(i,j)=∑m∑nInput(i+m,j+n)×Kernel(m,n)Output(i, j) = \sum_{m}\sum_{n}Input(i+m, j+n) \times Kernel(m, n)Output(i,j)=m∑n∑Input(i+m,j+n)×Kernel(m,n)
- 卷积核大小: 影响输出特征图的尺寸。
- 步长(Stride): 卷积核每次移动的距离。步长越大,特征图越小。
- 边缘填充(Padding): 用零填充边缘,防止特征图尺寸过小。
3.2 参数共享与局部连接
- 参数共享: 减少卷积核权重数量,例如 3×3 卷积核在 32×32 图像上共享一组参数。
- 局部连接: 每个神经元仅与输入的一部分相连,充分利用局部特性。
3.3 多通道卷积
- 多通道输入: 彩色图像有 3 个通道(RGB),每个通道单独进行卷积。
- 多卷积核输出: 多个卷积核提取不同的特征,输出多通道特征图。
4. 高级操作
4.1 反卷积(转置卷积)
- 用于将特征图尺寸放大,常用于生成对抗网络(GAN)和语义分割任务。
- 核心思想: 将卷积核进行逆操作以恢复输入特征的空间分布。
4.2 空洞卷积(膨胀卷积)
- 作用: 在卷积核之间插入空隙,以扩大感受野。
- 特点: 在不增加参数的情况下捕捉更大范围的特征,适用于语义分割和目标检测。
4.3 深度可分离卷积
- 定义: 分解为深度卷积(对每个通道独立操作)和 1×1 卷积(通道间融合)。
- 优点: 减少计算量和参数量,提高计算效率。
5. 感受野(Receptive Field)
5.1 什么是感受野?
- 定义: 一个神经元在输入数据上感知的区域范围。
- 作用: 决定网络对输入数据的敏感程度。
5.2 感受野的优化
- 小卷积核的堆叠: 多个 3×3 卷积核堆叠可替代 7×7 卷积核,实现更细致的特征提取。
- 空洞卷积: 在扩大感受野的同时不增加计算复杂度。
6. 应用与案例
6.1 数据增强
-
方法:
- 随机旋转、裁剪、翻转等空间变换。
-
颜色抖动、灰度化等颜色调整。
- 添加噪声以模拟真实环境。
6.2 卷积神经网络案例
-
模型结构:
- 输入尺寸:32×32×3。
-
两层卷积 + 池化后连接全连接层。
- 最终输出对应类别数的概率分布。
-
实现框架:
- PyTorch/Keras 等深度学习框架。
7. 实践与思考
7.1 如何改进 CNN 模型?
- 网络深度: 使用更深的网络(如 ResNet)。
- 正则化: 使用 Dropout、权重衰减等防止过拟合。
- 优化策略: 调整学习率调度,使用更高效的优化器(如 Adam)。
7.2 未解难题与研究方向
- 轻量化网络: 移动设备上的 CNN 应用如何进一步减小模型规模?
- 鲁棒性增强: 提高对噪声、遮挡等不确定因素的适应能力。
- 自监督学习: 无需大量标注数据,模型如何自主提取有效特征?
8. 总结
卷积神经网络是计算机视觉领域的核心技术,其通过局部连接、权重共享等机制实现了高效特征提取和学习。通过优化感受野、增强池化层功能等手段,CNN 不仅能解决传统方法无法应对的复杂任务,还为智能化的未来奠定了技术基础。