Day 7: 神经网络基础 - 深度学习的敲门砖
导读:欢迎来到“60天算法工程师”计划的第二个板块——深度学习基础。在结束了数学基础与传统机器学习的学习后,从今天开始,我们将正式进入深度学习的世界。
深度学习(Deep Learning)的核心在于使用多层神经网络来从数据中自动学习表示(Representation)。今天作为深度学习的第一天,我们将剥开复杂的网络结构外衣,回归本源,探讨神经网络最基础的构建模块:感知机、多层网络、激活函数、损失函数以及支撑这一切训练的基石——反向传播算法。
1. 从感知机到多层网络 (Perceptron to MLP)
1.1 感知机 (Perceptron)
感知机是神经网络的鼻祖,由 Frank Rosenblatt 在 1957 年提出。它是一个简单的线性二分类模型。
数学公式非常直观:
y=f(wTx+b) y = f(\mathbf{w}^T \mathbf{x} + b)y=f(wTx+b)
其中fff是阶跃函数(Step Function)。
局限性:感知机最大的问题是无法解决线性不可分问题,最著名的例子就是“异或”(XOR)问题。这导致了神经网络研究的第一次寒冬。
1.2 多层感知机 (Multi-Layer Perceptron, MLP)
为了解决非线性问题,引入了隐藏层(Hidden Layer)和非线性激活函数。
- 隐藏层:将输入空间映射到高维特征空间,使其线性可分。
- 非线性:如果只有多层线性变换,无论多少层叠加,最终等效于单层线性变换(矩阵乘法的结合律)。激活函数是赋予神经网络非线性能力的关键。
万能逼近定理 (Universal Approximation Theorem):
一个包含足够多神经元的单隐层前馈神经网络,可以以任意精度逼近任意连续函数。
2. 激活函数 (Activation Functions)
激活函数决定了神经元是否被“激活”。现代深度学习对激活函数的选择非常考究。
2.1 传统派:Sigmoid 与 Tanh
- Sigmoid:σ(x)=11+e−x\sigma(x) = \frac{1}{1+e^{-x}}σ(x)=1+e−x1,输出(0,1)(0, 1)(0,1)。
- 缺点:易导致梯度消失(导数最大值仅0.25);输出不是零中心(Zero-centered);指数计算昂贵。
- Tanh:tanh(x)=ex−e−xex+e−x\tanh(x) = \frac{e^x - e^{-x}}{e^x + e^{-x}}tanh(x)=ex+e−xex−e−x,输出(−1,1)(-1, 1)(−1,1)。
- 优点:零中心。
- 缺点:依然存在梯度消失问题。
2.2 现代派:ReLU 家族
- ReLU (Rectified Linear Unit):f(x)=max(0,x)f(x) = \max(0, x)f(x)=max(0,x)
- 优点:计算简单;正区间梯度为1,缓解梯度消失;带来稀疏性。
- 缺点:Dead ReLU问题(负区间梯度为0,神经元可能永久“死亡”)。
- Leaky ReLU / PReLU: 在负区间给予一个小的斜率(如 0.01),解决 Dead ReLU。
2.3 前沿派:GELU 与 Swish
现代大模型(如 BERT, GPT, EfficientNet)常用的激活函数。
- Swish:f(x)=x⋅σ(βx)f(x) = x \cdot \sigma(\beta x)f(x)=x⋅σ(βx)
- 由 Google 搜索得出,具有平滑、非单调特性。
- GELU (Gaussian Error Linear Unit):xΦ(x)x \Phi(x)xΦ(x)
- 在 BERT 中被普及。它不仅仅是激活,还包含随机正则化的思想(Dropout 的期望)。
- 特点:在x=0x=0x=0附近平滑弯曲,允许小的负值。
| 激活函数 | 适用场景 | 备注 |
|---|---|---|
| Sigmoid | 二分类输出层 | 隐藏层基本不用 |
| ReLU | CNN, 浅层 MLP | 默认首选,高效 |
| GELU | Transformer (BERT/GPT) | 大模型标配,性能更优 |
3. 损失函数设计 (Loss Functions)
损失函数衡量模型预测值与真实值之间的差距,是优化的“指路明灯”。
3.1 回归任务
- MSE (L2 Loss):1N∑(y−y^)2\frac{1}{N}\sum (y - \hat{y})^2N1∑(y−y^)2。对异常值敏感。
- MAE (L1 Loss):1N∑∣y−y^∣\frac{1}{N}\sum |y - \hat{y}|N1∑∣y−y^∣。鲁棒性强,但零点不可导。
- Huber Loss: 结合了 MSE 和 MAE 的优点。
3.2 分类任务
- 交叉熵损失 (Cross Entropy Loss):
L=−∑iyilog(y^i) L = - \sum_{i} y_i \log(\hat{y}_i)L=−i∑yilog(y^i)
本质是衡量两个概率分布(真实分布与预测分布)之间的差异(KL散度)。- 二分类:Binary Cross Entropy (BCE)。
- 多分类:Categorical Cross Entropy。
3.3 特殊场景
- Focal Loss: 用于解决类别极度不平衡问题(如目标检测)。通过降低易分类样本的权重,让模型专注于难分类样本。
FL(pt)=−αt(1−pt)γlog(pt) FL(p_t) = -\alpha_t (1-p_t)^\gamma \log(p_t)FL(pt)=−αt(1−pt)γlog(pt)
4. 反向传播与计算图 (Backpropagation & Computational Graph)
这是深度学习能够训练的核心机制。
4.1 计算图 (Computational Graph)
将神经网络的计算过程表示为有向无环图(DAG)。
- 节点:操作(加法、乘法、激活函数)。
- 边:数据(Tensor)。
4.2 链式法则 (Chain Rule)
反向传播本质上就是链式法则的递归应用。
假设y=f(u),u=g(x)y = f(u), u = g(x)y=f(u),u=g(x),则:
∂y∂x=∂y∂u⋅∂u∂x \frac{\partial y}{\partial x} = \frac{\partial y}{\partial u} \cdot \frac{\partial u}{\partial x}∂x∂y=∂u∂y⋅∂x∂u
4.3 自动微分 (Autograd)
现代框架(PyTorch/TensorFlow)不需要手动推导梯度。
- 前向传播 (Forward):计算输出,并建立计算图,缓存中间变量。
- 反向传播 (Backward):从 Loss 出发,沿着图反向遍历,计算每个节点的梯度。
5. 代码实践:PyTorch 实现一个简单的 MLP
我们用 PyTorch 实现一个简单的 MLP 来拟合非线性数据(模拟 XOR 问题或简单的函数拟合)。
importtorchimporttorch.nnasnnimporttorch.optimasoptimimportmatplotlib.pyplotasplt# 1. 准备数据 (模拟一个非线性关系 y = x^2)x=torch.unsqueeze(torch.linspace(-1,1,200),dim=1)# shape=(200, 1)y=x.pow(2)+0.1*torch.normal(torch.zeros(*x.size()))# 加入噪声# 2. 定义 MLP 网络classMLP(nn.Module):def__init__(self):super(MLP,self).__init__()# 隐藏层:输入1维 -> 隐藏10维self.hidden=nn.Linear(1,10)# 激活函数:使用 ReLUself.act=nn.ReLU()# 输出层:隐藏10维 -> 输出1维self.output=nn.Linear(10,1)defforward(self,x):x=self.hidden(x)x=self.act(x)x=self.output(x)returnx net=MLP()print(net)# 3. 定义损失函数和优化器criterion=nn.MSELoss()optimizer=optim.SGD(net.parameters(),lr=0.1)# 4. 训练循环fortinrange(2000):prediction=net(x)# 前向传播loss=criterion(prediction,y)# 计算 Lossoptimizer.zero_grad()# 梯度清零loss.backward()# 反向传播 (计算梯度)optimizer.step()# 更新参数ift%200==0:print(f'Step{t}, Loss:{loss.item():.4f}')# 5. 简单验证 (不可视化模式下)print(f"Final Loss:{loss.item():.4f}")# 我们可以看到 Loss 随着训练逐步下降,说明网络学到了 y=x^2 的非线性关系关键点解析:
nn.Module: 所有网络的基类。zero_grad(): 必须步骤。因为 PyTorch 默认会累积梯度(便于 RNN 等操作),所以在每一轮更新前需清空。backward(): 自动微分的魔法入口。
6. 总结与下期预告
今天我们通过 MLP、激活函数和反向传播,推开了深度学习的大门。神经网络不再是神秘的黑盒,而是一堆线性变换与非线性激活的组合,在微积分的指导下不断优化。
核心考点总结:
- 为什么需要非线性激活函数?(为了逼近复杂函数)
- Sigmoid 为什么会梯度消失?(导数最大值小且两端饱和)
- GELU 相比 ReLU 好在哪里?(平滑性,概率解释)
- 交叉熵与 MSE 的区别?(分类 vs 回归,概率分布匹配 vs 距离度量)
下期预告:
模型建好了,怎么训练得又快又好?Day 8 我们将深入探讨优化器(SGD, AdamW)与 训练技巧(BatchNorm, Dropout, LR Schedule),这些是炼丹师必备的调参内功。