目录
[十六、添加Batch Normalization](#十六、添加Batch Normalization)
在前面的文章中,我们已经学习了:
二维卷积
多通道卷积
池化层
卷积反向传播
神经网络训练流程
我们知道:
卷积层负责提取特征
池化层负责压缩特征
全连接层负责完成分类
那么问题来了:
如何把这些组件组合起来?
一个完整的卷积神经网络长什么样?
经典CNN是如何设计的?
如何使用PyTorch搭建CNN?
事实上:
现代视觉模型
几乎都建立在CNN思想之上
例如:
LeNet
AlexNet
VGG
GoogLeNet
ResNet
YOLO
本文将系统讲解:
CNN整体结构
经典CNN演进过程
LeNet结构
AlexNet结构
VGG结构
CNN搭建原则
PyTorch实战
二、卷积神经网络整体结构
一个典型CNN通常包含:
输入层
卷积层
激活层
池化层
全连接层
输出层
整体流程:

工作过程:
提取低级特征
↓
提取高级特征
↓
压缩特征
↓
完成分类
三、CNN为什么比普通神经网络更强
假设:
图片大小
224 × 224 × 3
如果直接连接全连接层:
224×224×3
=
150528个输入
参数量巨大。
而CNN采用:
局部连接
权重共享
优势:
参数更少
训练更快
更容易学习图像特征
四、LeNet:CNN的起点
1998年:
Yann LeCun
提出:
LeNet-5
用于:
手写数字识别
结构:

特点:
2层卷积
2层池化
3层全连接
虽然简单。
但开启了CNN时代。
五、LeNet网络结构解析
输入:
32×32灰度图
第一层:
Conv 5×5
输出:
28×28×6
池化:
14×14×6
第二层:
Conv 5×5
输出:
10×10×16
最终:
全连接分类
完成:
0~9数字识别
六、AlexNet:深度学习爆发点
2012年:
ImageNet竞赛
出现:
AlexNet
作者:
Alex Krizhevsky
结构:

重大创新:
ReLU
Dropout
GPU训练
最终:
ImageNet准确率大幅提升
引爆深度学习浪潮。
七、VGG:统一卷积设计
2014年:
VGGNet
提出:
全部使用3×3卷积
结构:

特点:
结构统一
易于扩展
实现简单
经典版本:
VGG16
VGG19
八、为什么卷积层越来越深
早期网络:
提取边缘
中间层:
提取纹理
深层:
提取目标轮廓
最后:
识别物体
例如:
边缘
↓
眼睛
↓
人脸
↓
人物
这就是深层CNN的优势。
九、典型CNN搭建原则
原则一:
卷积核逐渐增多
例如:
32
↓
64
↓
128
↓
256
原则二:
特征图逐渐减小
例如:
224×224
↓
112×112
↓
56×56
↓
28×28
原则三:
通道越来越多
空间越来越小
十、CNN分类网络结构示例
假设:
输入:
64×64×3
网络:

最终:
输出类别概率
十一、PyTorch搭建CNN
导入模块:
python
import torch
import torch.nn as nn
定义网络:
python
class SimpleCNN(nn.Module):
def __init__(self):
super().__init__()
self.conv1 = nn.Conv2d(
3,
32,
3,
padding=1
)
self.pool = nn.MaxPool2d(
2,
2
)
self.conv2 = nn.Conv2d(
32,
64,
3,
padding=1
)
self.fc = nn.Linear(
64 * 16 * 16,
10
)
十二、实现前向传播
python
def forward(self,x):
x = self.pool(
torch.relu(
self.conv1(x)
)
)
x = self.pool(
torch.relu(
self.conv2(x)
)
)
x = x.view(
x.size(0),
-1
)
x = self.fc(x)
return x
整个流程:
卷积
↓
ReLU
↓
池化
↓
卷积
↓
ReLU
↓
池化
↓
全连接
十三、创建模型
python
model = SimpleCNN()
print(model)
输出:
卷积层
池化层
全连接层
说明网络搭建成功。
十四、测试输入
构造图片:
python
x = torch.randn(
1,
3,
64,
64
)
预测:
y = model(x)
print(y.shape)
输出:
torch.Size([1,10])
表示:
10个类别
十五、添加Dropout防止过拟合
CNN训练时容易:
过拟合
解决:
python
self.dropout = nn.Dropout(
0.5
)
使用:
x = self.dropout(x)
作用:
随机关闭部分神经元
提升泛化能力。
十六、添加Batch Normalization
现代CNN几乎都会使用:
BN层
代码:
self.bn1 = nn.BatchNorm2d(32)
前向传播:
python
x = self.bn1(
self.conv1(x)
)
优势:
加速收敛
提升稳定性
十七、训练CNN
损失函数:
python
criterion = nn.CrossEntropyLoss()
优化器:
python
optimizer = torch.optim.Adam(
model.parameters(),
lr=0.001
)
训练:
python
for epoch in range(10):
output = model(x)
loss = criterion(
output,
label
)
optimizer.zero_grad()
loss.backward()
optimizer.step()
这就是完整训练流程。
十八、CNN参数量计算
假设:
输入通道
3
卷积核:
32个
3×3
参数:
3×3×3×32
=
864
再加:
32个偏置
总计:
896
相比全连接层:
少得多
十九、面试高频问题
CNN由哪些部分组成?
卷积层
激活层
池化层
全连接层
LeNet有什么意义?
第一个成功CNN
AlexNet最大贡献是什么?
推动深度学习爆发
VGG为什么经典?
统一采用3×3卷积
CNN为什么参数少?
局部连接
权重共享
为什么卷积层越往后通道越多?
提取更丰富高级特征
二十、总结
卷积神经网络的发展历程:
LeNet
↓
AlexNet
↓
VGG
↓
GoogLeNet
↓
ResNet
↓
EfficientNet
↓
Vision Transformer
而一个典型CNN的搭建过程:
输入图片
↓
卷积层
↓
激活层
↓
池化层
↓
卷积层
↓
池化层
↓
全连接层
↓
分类结果
掌握典型CNN的搭建,不仅能够理解经典计算机视觉模型的设计思想,更能够为后续学习:
目标检测
图像分割
YOLO
ResNet
Vision Transformer
打下坚实基础。
可以说:
卷积层负责"看见",池化层负责"压缩",全连接层负责"决策"。而典型卷积神经网络的搭建过程,本质上就是让机器逐层学习从像素到语义的映射过程。