零基础入门深度学习:从ResNet开始,一步步带你理解神经网络
这是一篇写给深度学习新手的文章。如果你听说过"神经网络"、"卷积"这些词,但不知道它们是什么,这篇文章就是为你准备的。
一、什么是深度学习?(5分钟搞懂)
1.1 先从一个生活例子说起
假设你要教计算机识别猫和狗:
传统方法(机器学习):
你告诉计算机:
- 猫:尖耳朵、小脸、胡须
- 狗:垂耳朵、大脸、长嘴然后计算机按照这些规则判断
深度学习方法:
你给计算机看10万张猫和狗的照片
计算机自己学习区分猫和狗的特征
最后它能识别新的照片
核心区别:传统方法需要人工设计规则,深度学习让机器自己学习规则。
1.2 神经网络是什么?
神经网络模仿人脑的工作方式:
人脑:神经元 → 连接 → 传递信号 → 决策
神经网络:节点 → 连接 → 传递数据 → 预测
1.3 "深度"是什么意思?
"深度"指的是隐藏层的层数:
浅层网络(1-2层):只能学简单特征
深层网络(很多层):能学复杂特征例子:
第1层:学习边缘(横线、竖线)
第2层:学习形状(圆形、三角形)
第3层:学习部件(眼睛、耳朵)
第4层:学习整体(猫脸、狗脸)
层数越多,学习能力越强——理论上是这样。
二、为什么深度学习会"翻车"?(理解退化问题)
2.1 一个奇怪的现象
2015年,研究者们发现了一个反直觉的现象:
| 网络层数 | 训练效果 | 实际表现 |
|---|---|---|
| 18层 | 好 | 好 |
| 34层 | 变差了 | 变差了 |
等等,这不对啊!
如果只是"过拟合"(死记硬背),应该是:
- 训练效果好(背下来了)
- 实际表现差(不会举一反三)
但现在训练效果也变差了,说明模型连训练数据都没学好!
2.2 问题出在哪里?
想象你在教一个学生学习:
理想情况:
老师教 → 学生学 → 学会了
实际情况(深度网络):
老师教 → 学生学 → 信息在传递中丢失 → 没学会
这就是梯度消失问题:信息在传递过程中逐渐变小,最后消失了。
2.3 用一个比喻来理解
想象一条河流:
上游(输入)→ 中游(隐藏层)→ 下游(输出)
传统网络的问题:
水流(梯度)从下游向上游传递
每经过一个瀑布(网络层),水量减少一点
到了上游,水几乎没了
→ 上游的土壤(参数)得不到灌溉,无法更新
这就是为什么深层网络训练不好:梯度(学习信号)在传递中消失了。
2.4 之前的解决方案
研究者们尝试了很多方法:
| 方法 | 原理 | 效果 |
|---|---|---|
| 更好的初始化 | 让初始梯度更大 | 有限 |
| Batch Normalization | 规范化数据 | 有帮助 |
| 更好的激活函数 | 让梯度不消失 | 有限 |
但都没有彻底解决问题。
三、ResNet的天才想法:残差学习(核心创新)
3.1 何恺明的思考
何恺明(Kaiming He)在微软亚洲研究院工作时,思考了这个问题:
既然深层网络学不好,那能不能让它"至少不比浅层差"?
他的想法:
假设浅层网络已经学到了一些特征,深层网络应该在这个基础上继续学习。
但如果深层网络学不好,它至少应该能"什么都不做"——保持浅层网络的结果。
3.2 什么是"残差"?
残差 = 实际值 - 预期值
举个例子:
你预期考试得80分
实际考了85分
残差 = 85 - 80 = 5分(超出预期的部分)
在神经网络中:
输入 x = 浅层网络学到的特征
输出 H(x) = 深层网络应该学到的特征
残差 F(x) = H(x) - x = 深层网络需要额外学习的部分
3.3 为什么要学习残差?
关键洞察:学习残差比学习完整映射更容易!
比喻:
假设你要教学生背诵一首诗:
传统方法:
学生:从头到尾完整背诵
难点:整首诗都很难记
残差方法:
学生:先读一遍原文(x)
学生:只背诵需要修改的地方 F(x)
最后:原文 + 修改 = 完整背诵 H(x) = F(x) + x
为什么更容易:
- 如果整首诗都记不住,至少能读原文
- 只需要记住"差异"部分,负担更小
3.4 数学表达
传统网络:学习 H(x)
残差网络:学习 F(x) = H(x) - x,输出 F(x) + x
特殊情况:
如果最优解是"什么都不做"(H(x) = x):
- 传统网络:需要学习 H(x) = x(很难)
- 残差网络:只需要学习 F(x) = 0(很容易)
这就解决了"至少不比浅层差"的问题。
四、跳跃连接:残差学习的实现方式(详细图解)
4.1 什么是跳跃连接?
跳跃连接(Skip Connection)是实现残差学习的关键:
输入 x│↓
┌─────────────────┐
│ 网络层(学习F(x))│
└─────────────────┘│↓⊕ ← 加法操作↑│x (跳跃过来的输入)│↓
输出 = F(x) + x
"跳跃"的意思:输入 x 直接"跳过"中间的网络层,到达加法操作。
4.2 详细图解:基础残差块
输入 x (比如:64个通道的特征图)│├───────────────────────────────┐│ │↓ │ (跳跃连接)
┌─────────────────┐ │
│ 3×3 卷积 │ │
│ + BatchNorm │ │
│ + ReLU │ │
└─────────────────┘ ││ │↓ │
┌─────────────────┐ │
│ 3×3 卷积 │ │
│ + BatchNorm │ │
└─────────────────┘ ││ │↓ │⊕ ←────────────────────────────┘│↓
ReLU激活│↓
输出
4.3 为什么要加 BatchNorm 和 ReLU?
BatchNorm(批归一化):
想象一个班级的学生考试:
没有BatchNorm:
- 有的学生用百分制(0-100)
- 有的学生用十分制(0-10)
- 老师很难统一评判有BatchNorm:
- 所有学生的成绩都标准化到均值0、标准差1
- 老师评判更容易
在神经网络中:
# BatchNorm 的作用
原始数据: [100, 200, 300, 400, 500]
标准化后: [-1.41, -0.71, 0, 0.71, 1.41]# 好处:
# 1. 数据分布稳定,训练更快
# 2. 可以使用更大的学习率
# 3. 一定程度防止过拟合
ReLU(激活函数):
ReLU(x) = max(0, x)# 例子:
ReLU(5) = 5
ReLU(-3) = 0
ReLU(0) = 0
为什么用ReLU?
- 计算简单(只需要判断是否大于0)
- 缓解梯度消失(梯度要么是0,要么是1)
- 产生稀疏性(很多神经元输出0,提高效率)
4.4 完整的数据流动过程
让我们跟踪一个具体的数据流:
# 假设输入是 1×64×56×56 (batch×channels×height×width)输入 x: 1×64×56×56# 第一层卷积
conv1: 3×3卷积, 64个卷积核
输出: 1×64×56×56# BatchNorm
bn1: 规范化
输出: 1×64×56×56# ReLU
relu: 激活
输出: 1×64×56×56# 第二层卷积
conv2: 3×3卷积, 64个卷积核
输出: 1×64×56×56# BatchNorm
bn2: 规范化
输出: 1×64×56×56# 加法操作(残差连接)
output = bn2(conv2(relu(bn1(conv1(x))))) + x= 1×64×56×56 + 1×64×56×56= 1×64×56×56# 最终ReLU
final_output = ReLU(output)= 1×64×56×56
五、卷积操作详解(零基础也能懂)
5.1 什么是卷积?
卷积是CNN(卷积神经网络)的核心操作。
生活中的例子:
想象你用一个放大镜看照片:
- 放大镜在照片上滑动
- 每次只看一个小区域
- 提取这个区域的特征
卷积操作类似:
- 卷积核(filter)在图像上滑动
- 每次只处理一个小区域
- 提取这个区域的特征
5.2 图示卷积操作
输入图像(5×5) 卷积核(3×3) 输出特征图(3×3)┌───┬───┬───┬───┬───┐ ┌───┬───┬───┐ ┌───┬───┬───┐
│ 1 │ 0 │ 1 │ 0 │ 1 │ │ 1 │ 0 │ 1 │ │ 4 │ 3 │ 4 │
├───┼───┼───┼───┼───┤ ├───┼───┼───┤ ├───┼───┼───┤
│ 0 │ 1 │ 0 │ 1 │ 0 │ │ 0 │ 1 │ 0 │ → │ 3 │ 4 │ 3 │
├───┼───┼───┼───┼───┤ ├───┼───┼───┤ ├───┼───┼───┤
│ 1 │ 0 │ 1 │ 0 │ 1 │ │ 1 │ 0 │ 1 │ │ 4 │ 3 │ 4 │
├───┼───┼───┼───┼───┤ └───┴───┴───┘ └───┴───┴───┘
│ 0 │ 1 │ 0 │ 1 │ 0 │
├───┼───┼───┼───┼───┤
│ 1 │ 0 │ 1 │ 0 │ 1 │
└───┴───┴───┴───┴───┘
5.3 卷积的具体计算
让我们计算左上角的输出值(4):
输入区域(3×3) 卷积核(3×3) 乘积求和┌───┬───┬───┐ ┌───┬───┬───┐
│ 1 │ 0 │ 1 │ │ 1 │ 0 │ 1 │ 1×1 + 0×0 + 1×1
├───┼───┼───┤ × ├───┼───┼───┤ = + 0×0 + 1×1 + 0×0
│ 0 │ 1 │ 0 │ │ 0 │ 1 │ 0 │ + 1×1 + 0×0 + 1×1
├───┼───┼───┤ ├───┼───┼───┤ = 1 + 0 + 1 + 0 + 1 + 0 + 1 + 0 + 1
│ 1 │ 0 │ 1 │ │ 1 │ 0 │ 1 │ = 4
└───┴───┴───┘ └───┴───┴───┘
5.4 不同的卷积核提取不同的特征
# 边缘检测核
edge_kernel = [[-1, -1, -1],[-1, 8, -1],[-1, -1, -1]]# 模糊核
blur_kernel = [[1/9, 1/9, 1/9],[1/9, 1/9, 1/9],[1/9, 1/9, 1/9]]# 锐化核
sharpen_kernel = [[ 0, -1, 0],[-1, 5, -1],[ 0, -1, 0]]
在神经网络中:
- 卷积核的值是学习出来的,不是人工设计的
- 不同的卷积核学习检测不同的特征
- 第1层:学习边缘、纹理
- 第2层:学习形状、图案
- 更深层:学习更复杂的特征
5.5 关键概念
感受野(Receptive Field):
卷积核能看到的输入区域大小3×3卷积核:感受野是3×3
5×5卷积核:感受野是5×5堆叠多层小卷积核 vs 一层大卷积核:
3×3 + 3×3 = 感受野5×5(参数更少)
直接5×5 = 感受野5×5(参数更多)
特征图(Feature Map):
卷积后的输出
每个卷积核生成一个特征图
64个卷积核 → 64个特征图 → 64个通道
参数共享:
同一个卷积核在整个图像上滑动
大大减少参数数量
例如:3×3卷积核只有9个参数,不管图像多大
六、反向传播:神经网络如何学习?
6.1 神经网络的学习过程
神经网络的学习分为两步:
前向传播(Forward Pass):
输入 → 网络层 → 输出 → 计算损失
反向传播(Backward Pass):
损失 → 计算梯度 → 更新参数
6.2 什么是梯度?
梯度 = 导数 = 变化率
生活中的例子:
你站在山上,想找到下山的路
梯度告诉你:
- 方向:哪边是下坡
- 大小:坡度有多陡你应该朝着梯度的反方向走(下坡方向)
在神经网络中:
损失函数 L = 预测值与真实值的差距
梯度 ∂L/∂w = 参数w对损失的影响更新规则:
w_new = w_old - learning_rate × gradient如果梯度是正的:减小参数
如果梯度是负的:增大参数
6.3 梯度消失问题
问题:梯度在反向传播中逐渐变小
损失 L↓
层n:梯度 = 1.0↓
层n-1:梯度 = 0.9↓
层n-2:梯度 = 0.81↓
...↓
层1:梯度 = 0.9^100 ≈ 0.00003
为什么梯度会变小?
因为每经过一层,梯度要乘以该层的权重:
∂L/∂w1 = ∂L/∂y × ∂y/∂wn × ∂wn/∂wn-1 × ... × ∂w2/∂w1如果每层的梯度都小于1,乘积会越来越小
6.4 ResNet如何解决梯度消失?
跳跃连接让梯度有了"高速公路":
传统网络:
损失 → 层n → 层n-1 → ... → 层1
(梯度逐层衰减)ResNet:
损失 → ─────────────────────→ 层1↓ ↑层n → 层n-1 → ... → ──┘(梯度可以跳跃传递)
数学解释:
传统网络的梯度:
∂L/∂x = ∂L/∂y × ∂y/∂x = ∂L/∂y × F'(x)ResNet的梯度:
∂L/∂x = ∂L/∂y × (∂F(x)/∂x + 1)↑这个+1保证梯度至少为1
关键点:跳跃连接提供了一个"恒等梯度"(值为1),保证梯度不会消失。
七、常见问题解答(FAQ)
Q1: 为什么用3×3卷积核而不是更大的?
答:
两个3×3卷积的感受野 = 一个5×5卷积
但参数更少:2×(3×3) = 18 < 25 = 5×5三个3×3卷积的感受野 = 一个7×7卷积
但参数更少:3×(3×3) = 27 < 49 = 7×7结论:堆叠小卷积核更高效
Q2: BatchNorm放在ReLU前面还是后面?
答:
原论文:Conv → BN → ReLU
现在常用:Conv → BN → ReLU也有研究用:Conv → ReLU → BN
效果差异不大,但原论文的方式更常见
Q3: 为什么ResNet能训练152层而VGG只能16层?
答:
VGG:梯度必须逐层传递,容易消失
ResNet:梯度可以通过跳跃连接直接传递,不会消失关键:跳跃连接提供了梯度的"高速公路"
Q4: 残差块中的ReLU放在哪里?
答:
放在加法之后:Conv → BN → ReLU → Conv → BN↓+ ←───────────┘ (跳跃连接)↓ReLU ← 最后的激活
Q5: 如何选择ResNet的深度?
答:
ResNet-18:快速实验、移动端
ResNet-34:平衡性能和速度
ResNet-50:最常用,性价比最高
ResNet-101:需要更高精度
ResNet-152:追求极致性能
八、总结:ResNet的精髓
8.1 核心思想
- 残差学习:学习残差 F(x) 比学习完整映射 H(x) 更容易
- 跳跃连接:让梯度可以直接传递,解决梯度消失
- 恒等映射:保证深层网络至少不比浅层差
8.2 一句话总结
ResNet通过学习残差而不是完整映射,让深度网络真正"深"了起来。
附录:关键术语表
| 术语 | 英文 | 含义 |
|---|---|---|
| 残差 | Residual | 实际值与预期值的差异 |
| 跳跃连接 | Skip Connection | 跨层传递信息的连接 |
| 梯度 | Gradient | 损失函数对参数的导数 |
| 梯度消失 | Vanishing Gradient | 梯度在传递中逐渐变小 |
| 卷积 | Convolution | 提取局部特征的操作 |
| 批归一化 | Batch Normalization | 规范化每层的输出 |
| 激活函数 | Activation Function | 引入非线性 |
| 迁移学习 | Transfer Learning | 用预训练模型做新任务 |
作者:小探
首发:探物 AI
转载请注明出处
