一文了解什么是——卷积神经网络CNN
为什么还有人不会CNN啊?写这么详细你还不看呐QWQ
目录
2. 非线性激活函数(Activation Function)
5. 全连接层(Fully Connected Layer)
卷积神经网络(CNN)详解
一、概述
卷积神经网络(Convolutional Neural Network, CNN)是一种深度学习中的前馈神经网络,特别适合用于图像、语音、文本等具有局部结构特征的数据。CNN 是受生物学中视觉皮层结构启发而设计的,能够自动提取输入数据的空间和局部相关性,是目前计算机视觉中最重要和广泛使用的模型之一。
二、CNN 与传统神经网络的区别
传统的全连接神经网络(Fully Connected Neural Network, FCNN)存在以下问题:
-
参数过多:例如一张 224×224 像素的RGB图像,有 224×224×3 = 150,528 个输入节点(乘以3是因为RGB有三个通道)。
-
无法捕捉局部结构:FCNN 每个神经元与前一层的所有节点相连,忽略了像素间的空间关系。
-
容易过拟合:大规模参数量导致学习泛化能力差。
而 CNN 通过使用局部连接(local connectivity)和共享权重(weight sharing)等设计思想,有效地克服了上述问题。
三、CNN 的核心组成部分
1. 卷积层(Convolutional Layer)
目的:提取图像中的局部特征,如边缘、角点、纹理等。
1.1 卷积操作的定义
在数学上,卷积操作(convolution)是一个积分变换,但在深度学习中,我们通常使用其离散形式:
其中:
-
表示输入图像
-
表示卷积核(或称滤波器)
-
表示卷积操作
-
为输出特征图(feature map)上的值
1.2 特征图(Feature Map)
每一个卷积核在输入图像上滑动并与局部区域计算加权和,生成一个新的二维矩阵,称为特征图,反映了该卷积核对某一特定特征(如边缘)的响应程度。
1.3 超参数
-
卷积核大小(Kernel Size):如 3×3, 5×5(注意:这里需要为奇数)
-
步幅(Stride):卷积核每次滑动的距离,决定输出尺寸。
-
填充(Padding):是否在输入图像边缘补零,以保持输出尺寸与输入一致。
2. 非线性激活函数(Activation Function)
目的:引入非线性因素,使网络具有更强的表达能力。
常用的激活函数:
-
ReLU(Rectified Linear Unit):
-
Leaky ReLU、ELU、Sigmoid、Tanh 等
ReLU 是最常用的,因为计算简单,梯度传播稳定。
3. 池化层(Pooling Layer)
目的:压缩特征图的空间尺寸,降低计算量和过拟合风险,同时保留主要特征。
常见的池化方式:
-
最大池化(Max Pooling):取局部区域中的最大值。
-
平均池化(Average Pooling):取局部区域的平均值。
超参数包括:
-
池化窗口大小(如 2×2)
-
步幅(通常等于窗口大小)
4. 扁平化层(Flatten Layer)
扁平化层(Flatten Layer)的主要作用是将多维的张量(tensor)数据展开成一维向量,以便能够连接到后续的全连接层中。
-
卷积层和池化层输出的是二维或三维的特征图,例如:
(Channels, Height, Width)
-
全连接层期望输入的是一维向量
因此,扁平化层起到了一个 “维度转换”的桥梁作用。
📐 举例说明
假设某卷积神经网络中,最后一层卷积后得到的特征图维度是:
那么扁平化后变为一维向量:
此时,输出形状为:
这就是全连接层所需的输入格式。
5. 全连接层(Fully Connected Layer)
全连接层(FC Layer),也称为密集层(Dense Layer),是传统神经网络中的核心组成部分。
在 CNN 中,它主要出现在模型的尾部,用于:
-
综合前面层提取到的局部特征
-
实现最终的决策(例如分类)
全连接层中的每个神经元都与上一层所有的输出单元相连接,使其具有全局信息整合能力。
🧮 数学原理
设:
-
输入向量为
-
权重矩阵为
-
偏置向量为
则输出向量 为:
每个输出神经元都可以表示为:
随后通常会接一个激活函数(如 ReLU、Softmax)。
🧠 为什么 CNN 要加全连接层?
-
CNN 前几层负责提取局部特征(边缘、形状、纹理、物体局部结构)
-
全连接层将这些特征整合为全局信息,用于最终分类或预测任务
可以把 CNN 卷积部分当作自动特征提取器,而全连接层则像是一个分类器。
📐 举例说明
继续刚才的例子:
-
Flatten 后是一个大小为
3136
的向量 -
接一个全连接层输出大小为
128
则这一层有:
参数量=3136×128+128=401,536
其中包含了:
-
权重:3136×128 = 401,408
-
偏置:128
接着可以继续连接一个分类层,例如输出为10类:
nn.Linear(128, 10)
6. 输出层(Output Layer)
对于分类任务:
-
通常使用 Softmax 函数:
输出为每个类别的概率分布。
四、CNN 的典型结构
一个典型的 CNN 网络结构如下所示:
输入图像 → 卷积层 → ReLU → 池化层
→ 卷积层 → ReLU → 池化层 → Flatten → 全连接层 → Softmax 输出
五、CNN 的参数计算
1. 卷积输出尺寸公式:
设输入尺寸为 ,卷积核大小为
,步幅为 S,填充为 P,输出尺寸为
:
六、CNN 的训练过程
-
前向传播(Forward Propagation):计算网络输出。
-
损失函数计算:衡量预测与实际标签的差异(如交叉熵损失)。
-
反向传播(Backpropagation):使用链式法则计算梯度。
-
参数更新:使用优化器(如 SGD, Adam)更新权重和偏置。
七、经典 CNN 架构
以下是一些具有代表性的 CNN 模型:
模型名称 | 特点 |
---|---|
LeNet-5 | 最早的CNN之一,用于手写数字识别 |
AlexNet | 2012年ImageNet冠军,使用ReLU和Dropout |
VGGNet | 使用大量的3×3卷积核堆叠 |
GoogLeNet | 引入Inception模块,结构更深但计算高效 |
ResNet | 引入残差连接,解决深层网络的退化问题 |
八、CNN示例
使用 Python + PyTorch 实现的经典 CNN 模型(LeNet-5)代码,这个网络是最早被广泛使用的卷积神经网络之一,用于手写数字识别(如 MNIST 数据集)
import torch
import torch.nn as nn
import torch.nn.functional as F
from torchvision import datasets, transforms
from torch.utils.data import DataLoader
# ✅ 1. 定义 LeNet-5 网络结构
class LeNet5(nn.Module):
def __init__(self):
super(LeNet5, self).__init__()
# 输入:1x28x28
self.conv1 = nn.Conv2d(1, 6, kernel_size=5, padding=2) # 输出:6x28x28
self.pool1 = nn.AvgPool2d(2, stride=2) # 输出:6x14x14
self.conv2 = nn.Conv2d(6, 16, kernel_size=5) # 输出:16x10x10
self.pool2 = nn.AvgPool2d(2, stride=2) # 输出:16x5x5
self.fc1 = nn.Linear(16 * 5 * 5, 120) # 展平后输入
self.fc2 = nn.Linear(120, 84)
self.fc3 = nn.Linear(84, 10) # 最终10类输出
def forward(self, x):
x = F.relu(self.conv1(x)) # C1
x = self.pool1(x) # S2
x = F.relu(self.conv2(x)) # C3
x = self.pool2(x) # S4
x = x.view(-1, 16 * 5 * 5) # 展平
x = F.relu(self.fc1(x)) # 全连接1
x = F.relu(self.fc2(x)) # 全连接2
x = self.fc3(x) # 输出层(无激活,交给Loss)
return x
# ✅ 2. 准备数据(MNIST)
transform = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.1307,), (0.3081,)) # MNIST 均值和标准差
])
train_dataset = datasets.MNIST(root='./data', train=True, download=True, transform=transform)
test_dataset = datasets.MNIST(root='./data', train=False, transform=transform)
train_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)
test_loader = DataLoader(test_dataset, batch_size=1000)
# ✅ 3. 模型初始化与优化器
device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
model = LeNet5().to(device)
optimizer = torch.optim.Adam(model.parameters(), lr=0.001)
criterion = nn.CrossEntropyLoss()
# ✅ 4. 训练函数
def train(model, loader, optimizer, criterion, epoch):
model.train()
total_loss = 0
for batch_idx, (data, target) in enumerate(loader):
data, target = data.to(device), target.to(device)
optimizer.zero_grad()
output = model(data) # 前向传播
loss = criterion(output, target) # 计算损失
loss.backward() # 反向传播
optimizer.step() # 更新参数
total_loss += loss.item()
print(f"Epoch {epoch}, Loss: {total_loss:.4f}")
# ✅ 5. 测试函数
def test(model, loader):
model.eval()
correct = 0
total = 0
with torch.no_grad(): # 关闭梯度计算
for data, target in loader:
data, target = data.to(device), target.to(device)
output = model(data)
pred = output.argmax(dim=1)
correct += (pred == target).sum().item()
total += target.size(0)
acc = 100. * correct / total
print(f"Test Accuracy: {acc:.2f}%")
# ✅ 6. 开始训练
for epoch in range(1, 6): # 训练5轮
train(model, train_loader, optimizer, criterion, epoch)
test(model, test_loader)
Epoch 1, Loss: 267.0351
Test Accuracy: 97.25%
Epoch 2, Loss: 79.5980
Test Accuracy: 98.07%
Epoch 3, Loss: 56.7498
Test Accuracy: 98.29%
Epoch 4, Loss: 45.3591
Test Accuracy: 98.47%
Epoch 5, Loss: 36.6190
Test Accuracy: 98.83%
八、CNN 的优势
-
自动提取特征,减少人工特征工程
-
局部感知、参数共享,显著降低模型复杂度
-
强大的图像识别、检测、分割能力
九、典型应用场景
-
图像分类(Image Classification)
-
目标检测(Object Detection)
-
图像分割(Image Segmentation)
-
面部识别(Face Recognition)
-
医学图像分析(Medical Imaging)
-
视频分析(Video Surveillance)
十、小结
卷积神经网络通过模仿人类视觉系统的结构,有效提取图像的局部特征,逐层构建抽象表示,是目前图像识别、语音识别等任务中不可或缺的模型。掌握其原理和结构,对于深入学习深度学习具有重要意义。
更多推荐
所有评论(0)