一、写在前面:一张图看懂全文
flowchart TD
A[结构化表格] -->|FNN| B[评分预测]
C[图片] -->|CNN| D[菜品识别]
E[订单时序] -->|LSTM| F[未来1h单量]
G[用户长句] -->|Transformer| H[智能客服]
下面,我们按图索骥,把每一个"黑盒"拆成"乐高"。
二、前馈网络 FNN:最老实的流水线工人
1. 通俗比喻
把 784 个像素扔进一条只进不退 的流水线:
输入层 → 隐藏工人 → 输出成品。
没有回头路,所以叫"前馈"。
2. 专业公式(一行)
y = σ(Wx + b)
- W:权重,工人手里的扳手
- b:偏置,螺丝松紧的"出厂设置"
- σ:激活函数,后文第三节送它 C 位出道
3. 代码实录(含碎碎念)
python
class FNN(nn.Module):
def __init__(self):
super().__init__()
self.fc1 = nn.Linear(784, 128) # 扳手 1:784 → 128
self.fc2 = nn.Linear(128, 10) # 扳手 2:128 → 10
def forward(self, x):
x = torch.relu(self.fc1(x)) # 给工人喝咖啡,提神(非线性)
return self.fc2(x) # 成品出库
三、反向传播:工人如何"背锅"与"改错"
1. 四步口诀
- 算损失(差评)
- 链式法则(逐级甩锅)
- 得梯度(责任报告)
- 优化器(扣工资 or 发奖金)
2. 公式(别怕,就两行)
ΔW = −η · ∂Loss/∂W
∂Loss/∂W = ∂Loss/∂y · ∂y/∂h · ∂h/∂W
翻译:损失对权重的偏导 = 一条"甩锅链"。
3. 代码仪式(缺一不可)
python
optimizer.zero_grad() # 先清空旧账
loss = criterion(out, label)
loss.backward() # 反向甩锅
optimizer.step() # 按梯度发奖金/扣工资
四、激活函数:给工人装一个"决策开关"
函数 | 公式 | 一句话点评 | 场景 |
---|---|---|---|
Sigmoid | 1/(1+e^(−x)) | 把输出压成概率,但两端"梯度消失" | 二分类输出层 |
ReLU | max(0,x) | 计算快、梯度硬,但负数"直接猝死" | 隐藏层默认 |
LeakyReLU | max(0.01x,x) | 给负数留口气,防止"神经元死亡" | 深层网络急救 |
可视化一行命令
plt.plot(x, torch.relu(x), label='ReLU')
其余同理,图一贴,读者秒懂。
五、CNN:给流水线装上"放大镜"与"滑窗"
1. 通俗比喻
卷积核 = 放大镜,在图片上滑动扫描
参数共享 = 一把放大镜走遍全图,省钱又抗平移
2. 核心套路
Conv → ReLU → Pool → Flatten → FNN
翻译:提特征 → 激活 → 降采样 → 拉直 → 分类
3. 代码(注释比代码长)
python
self.conv1 = nn.Conv2d(3, 16, 3) # 3通道→16核,核大小3×3
self.pool = nn.MaxPool2d(2, 2) # 2×2窗口, stride=2
x = self.pool(F.relu(self.conv1(x))) # 一步完成"卷+活+池"
六、RNN/LSTM:给工人加一块"记事板"
1. 通俗比喻
RNN:每来一个新词,先看上一秒的记事板 ,再写新的
LSTM:记事板升级三阀门------遗忘、输入、输出,长依赖不爆炸
2. 公式(只记一个)
ht = tanh(Whh·h(t−1) + Wxh·xt)
翻译:新记忆 = 旧记忆 + 新输入,过激活函数
3. 代码(PyTorch 一行切换)
python
rnn = nn.RNN(input_size, hidden_size, num_layers)
lstm = nn.LSTM(input_size, hidden_size, num_layers) # 多一个细胞状态 C
七、Transformer:扔掉记事板,全员开"圆桌会议"
1. 通俗比喻
不再挨个记,一句话所有人同时上桌投票
自注意力 = 给每个词发一张"谁对我最重要"的选票
2. 公式(只记骨架)
Attention(Q,K,V)=softmax(QK^T/√dk)V
翻译:选票归一化后,按权重对信息加权求和
3. 代码(多头注意力,注释版)
python
class MultiHeadAttention(nn.Module):
def __init__(self, d_model=512, n_heads=8):
super().__init__()
self.d_k = d_model // n_heads
self.W_q = nn.Linear(d_model, d_model)
self.W_k = nn.Linear(d_model, d_model)
self.W_v = nn.Linear(d_model, d_model)
self.out = nn.Linear(d_model, d_model)
def forward(self, x):
Q = self.W_q(x) # 造查询
K = self.W_k(x) # 造键
V = self.W_v(x) # 造值
# 分头、转置、缩放点积、softmax、加权求和
scores = torch.matmul(Q, K.transpose(-2, -1)) / math.sqrt(self.d_k)
attn = F.softmax(scores, dim=-1)
out = torch.matmul(attn, V)
return self.out(out) # 合并头 + 线性输出
八、架构选型" cheat sheet "(收藏级)
模型 | 数据特点 | 核心杀器 | 美团实战举例 |
---|---|---|---|
FNN | 表格/结构化 | 简单暴力 | 用户评分预测 |
CNN | 图像/网格 | 局部+共享 | 菜品图片识别 |
RNN/LSTM | 时序/可变长 | 记忆板 | 未来1h订单预测 |
Transformer | 长序列/全局依赖 | 圆桌投票 | 智能客服意图识别 |
九、彩蛋:如何继续" deepen learning "
- 把本文代码丢进 Colab,跑一次 MNIST 手写数字 → 成就感 +10086
- 把 ReLU 换成 LeakyReLU,观察验证集准确率 → 体会"调参玄学"
- 用 LSTM 预测股票(或外卖订单)→ 体验"序列魔法"
- 读原论文:LeNet-5 → AlexNet → ResNet → Transformer,一路打怪升级
十、结语
深度学习没有"黑魔法",只有乐高积木 + 数学公式 + 大量数据 。
希望这篇"漫游指南"能让你在掘金、知乎、GitHub 上游刃有余地继续" deepen learning "。
愿你的 loss 一降再降,acc 一飞冲天!