1. 神经网络训练中的已知量与未知量
在神经网络训练过程中,我们需要明确区分哪些要素是预先设定的,哪些是需要通过训练确定的。训练数据(包括输入特征和对应的标签)是已知的,它们构成了模型学习的依据。网络架构(如层数、神经元数量)、激活函数类型(如ReLU、sigmoid)、损失函数(如交叉熵、均方误差)以及超参数(如初始学习率、批量大小)也都是预先设定的。
而需要通过学习确定的参数主要包括:
- 权重矩阵(W):连接各层神经元的参数
- 偏置向量(b):每个神经元的偏移量
关键理解:训练过程本质上是通过调整W和b,使得网络对输入数据的处理结果逐渐接近期望输出。这个过程就像教小孩认图卡 - 我们提供图片(输入)和正确答案(标签),孩子通过不断调整自己的判断方式(参数),最终能够独立正确识别新图片。
2. 单层感知机的局限性解析
2.1 线性可分问题的本质
单层感知机之所以只能解决线性可分问题,源于其数学本质。考虑一个二维案例,单层感知机的决策函数可表示为:
code复制y = sign(w1x1 + w2x2 + b)
这实际上是在特征空间中用一条直线(高维时为超平面)划分数据。以逻辑门为例:
- AND(与门):可用直线分开(0,0)和(1,1)
- OR(或门):同样可用直线分开
- XOR(异或门):需要两条直线才能正确划分
2.2 几何视角的局限性
在特征空间中,单层感知机构建的决策边界始终是线性的。对于XOR这类问题,无论怎样调整w和b,都无法找到一条直线能正确分类所有样本。这就像试图用一根木棍分开地上的两堆沙子 - 当沙子呈现交叉分布时,单根木棍永远无法完美分隔。
3. 非线性激活函数的关键作用
3.1 从数学角度理解
假设我们有一个两层网络但使用线性激活函数:
code复制h = W2(W1x + b1) + b2 = W'x + b'
这等效于单层线性变换,失去了深度网络的优势。引入非线性激活函数σ后:
code复制h = σ(W2σ(W1x + b1) + b2)
此时网络可以表示更复杂的函数。常用的非线性激活函数包括:
- ReLU:max(0,x) (缓解梯度消失)
- Sigmoid:1/(1+e^-x) (输出0-1)
- Tanh:(e^x-e^-x)/(e^x+e^-x) (输出-1到1)
3.2 实际应用中的选择
在图像处理中,ReLU及其变种(如Leaky ReLU)通常是隐藏层的首选,因为:
- 计算简单,加速训练
- 缓解梯度消失问题
- 产生稀疏激活(约50%神经元激活)
而输出层根据任务选择:
- 二分类:Sigmoid
- 多分类:Softmax
- 回归:线性(无激活)
4. 前向传播的数学本质
4.1 逐层计算过程
以一个三层的全连接网络为例:
code复制输入x → 隐藏层h1 = σ1(W1x + b1) → 隐藏层h2 = σ2(W2h1 + b2) → 输出y = σ3(W3h2 + b3)
其中:
- W1 ∈ R^(d×h1), W2 ∈ R^(h1×h2), W3 ∈ R^(h2×k)
- σ表示激活函数
- d为输入维度,k为输出维度
4.2 计算示例
假设处理MNIST手写数字(28×28=784像素),网络结构为:
- 输入层:784维
- 隐藏层1:512个神经元(ReLU)
- 隐藏层2:256个神经元(ReLU)
- 输出层:10个神经元(Softmax)
前向传播时:
- 将图像展平为784维向量
- 计算h1 = ReLU(W1x + b1),W1 ∈ R^(512×784)
- 计算h2 = ReLU(W2h1 + b2),W2 ∈ R^(256×512)
- 计算输出y = Softmax(W3h2 + b3),W3 ∈ R^(10×256)
5. Softmax在分类任务中的作用
5.1 数学表达式
对于K类分类问题,Softmax函数定义为:
code复制P(y=k|x) = e^(z_k) / ∑_{j=1}^K e^(z_j)
其中z_k是第k个输出神经元的原始得分。
5.2 实际应用特点
- 输出归一化:所有类别概率和为1
- 概率解释:可直接作为置信度
- 梯度友好:便于反向传播
- 数值稳定实现:
python复制def softmax(z):
z_exp = np.exp(z - np.max(z)) # 防止数值溢出
return z_exp / np.sum(z_exp)
注意事项:在实践中,我们通常将Softmax与交叉熵损失结合使用,这样能获得更稳定的梯度计算。单独实现时要注意数值溢出问题,常见的处理方式是减去最大值。
6. 损失函数的核心价值
6.1 准确率的局限性
准确率(Accuracy)作为评估指标存在三个主要问题:
- 不可微:无法直接用于梯度下降
- 信息稀疏:对接近决策边界的样本不敏感
- 类别不平衡时误导性
6.2 常用损失函数对比
| 任务类型 | 损失函数 | 公式 | 特点 |
|---|---|---|---|
| 二分类 | 二元交叉熵 | -[y*log(p)+(1-y)*log(1-p)] | 适用于概率输出 |
| 多分类 | 分类交叉熵 | -∑ y_i*log(p_i) | 配合Softmax使用 |
| 回归 | 均方误差 | (y_true - y_pred)^2 | 对异常值敏感 |
| 回归 | 平均绝对误差 | y_true - y_pred |
6.3 梯度下降的数学基础
考虑参数θ和损失L(θ),泰勒展开:
code复制L(θ+Δθ) ≈ L(θ) + ∇L(θ)^T Δθ
要使L减小最快,应取Δθ = -η∇L(θ),其中η为学习率。
7. 梯度下降的几何理解
7.1 梯度方向的意义
梯度∇f指向函数f增长最快的方向。在优化中,我们希望最小化损失函数,因此沿负梯度方向更新参数。在二维情况下,这相当于沿着最陡的下坡方向前进。
7.2 学习率的影响
学习率η控制参数更新步长:
- 太大(如η=1.0):可能越过最优解,甚至发散
- 太小(如η=1e-6):收敛极慢,可能卡在局部极小
自适应方法示例:
python复制# Adam优化器参数更新
m = β1*m + (1-β1)*grad
v = β2*v + (1-β2)*grad^2
m_hat = m / (1-β1^t)
v_hat = v / (1-β2^t)
param = param - η*m_hat/(sqrt(v_hat)+ε)
8. 实践中的优化技巧
8.1 学习率调度策略
- 阶梯下降:每N个epoch将η乘以γ
- 余弦退火:η = η_min + 0.5*(η_max-η_min)(1+cos(t/Tπ))
- 热启动:训练中断后恢复时暂时提高η
8.2 梯度问题处理
- 梯度消失:使用ReLU、残差连接、批归一化
- 梯度爆炸:梯度裁剪(如|g| > 5 → g = 5*g/|g|)
- 鞍点问题:使用动量(如β=0.9)
8.3 批处理注意事项
- 批量大小影响:
- 大批量:更稳定的梯度估计,但需要更大内存
- 小批量:更多噪声,可能帮助逃离局部极小
- 常见配置:
- 计算机视觉:32-256
- NLP:16-64
- 强化学习:1-32
在实际项目中,我通常会先用小批量(如32)快速验证模型可行性,然后根据GPU内存逐步增加批量大小。同时配合学习率预热(前500步线性增加η)能显著提升训练稳定性。对于深层网络,加入批归一化层可以使学习率设置更加鲁棒。
