# 04. 损失函数与优化器 > 五步骨架里的第 3 步(算loss)和第 5 步(更新)到底有哪些选择? > 这一篇把 loss 和 optimizer 讲清楚。 --- ## 一、损失函数(Loss):衡量"预测错多少" Loss 越小 = 预测越准。不同任务用不同 loss。 ### 回归任务(输出连续值) | Loss | 公式 | 特点 | |---|---|---| | **MSE**(均方误差)| $\frac{1}{N}\sum(\hat y-y)^2$ | 最常用;对离群点敏感(平方放大)| | **MAE**(绝对误差)| $\frac{1}{N}\sum\|\hat y-y\|$ | 抗离群点;但0点不可导 | | **SmoothL1**(Huber) | 小误差像MSE,大误差像MAE | 两者折中,目标检测常用 | 实测(pred=[2.5,0,2], target=[3,0,1]): ``` MSE : 0.4167 = mean((pred-target)^2) MAE : 0.5 = mean(|pred-target|) SmoothL1: 0.2083 小误差平滑、大误差线性 ``` ### 分类任务(输出类别) **CrossEntropyLoss(交叉熵)** —— 多分类标配,**内部自带 softmax**: $$L = -\log p_{\text{正确类}}, \quad p_i=\frac{e^{z_i}}{\sum_j e^{z_j}}$$ 实测(logits=[2.0,0.5,0.1],正确类=0): ``` softmax概率: [0.728, 0.163, 0.109] CrossEntropy: 0.3168 = -log(0.728) ✓ ``` > ⚠️ 模型最后一层**别加softmax**,CrossEntropyLoss 已经包含了。 > 二分类也可用 `BCEWithLogitsLoss`(含sigmoid)。 --- ## 二、优化器(Optimizer):决定"参数怎么更新" 所有优化器都基于梯度下降,区别在"步子怎么走"。 ### ① SGD(随机梯度下降)—— 最基础 $$w \leftarrow w - \text{lr}\cdot g$$ 直接沿梯度反方向走。简单,但容易在峡谷里震荡、陷局部最优。 ### ② SGD + Momentum(动量)—— 加惯性 $$v \leftarrow \beta v + g,\quad w \leftarrow w - \text{lr}\cdot v$$ 像小球滚下山带惯性,能冲过小坑、减少震荡,收敛更稳。 ### ③ Adam —— 自适应学习率(最常用) 结合动量 + 每个参数自适应步长(RMSProp思想)。 **默认首选**,对学习率不敏感,开箱即用。 ### 实测对比(拟合 y=3x+2,100步) ``` SGD (lr=0.1) loss = 0.000002 Momentum (lr=0.1) loss = 0.000017 Adam (lr=0.1) loss = 0.000187 ``` > 注:简单凸问题上 SGD 反而最快收敛。但在**深度网络/复杂loss面**上, > Adam 通常更稳更省心——所以实践默认用 Adam。 --- ## 三、学习率(lr):最重要的超参数 $$w \leftarrow w - \underbrace{\text{lr}}_{\text{步子大小}}\cdot g$$ 实测 lr 的影响(SGD,100步): ``` lr=0.001 -> loss=4.18 太小,学得慢(没收敛) lr=0.05 -> loss=0.003 合适 lr=0.5 -> loss=0.000 合适 lr=1.5 -> loss=inf 太大,直接发散! ``` | lr | 现象 | |---|---| | 太小 | 收敛极慢,半天学不动 | | 合适 | 稳步下降 | | 太大 | 震荡甚至 **发散到 inf/nan** | **经验起点**:Adam 用 `1e-3`,SGD 用 `1e-2`~`1e-1`。 --- ## 四、学习率调度(进阶) 训练后期把 lr 调小,能更精细收敛: ```python scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=30, gamma=0.1) # 每30轮 lr 乘0.1 for epoch in range(100): train_one_epoch() scheduler.step() # 更新学习率 ``` 常用:StepLR、CosineAnnealingLR、ReduceLROnPlateau。 --- ## 五、小结:怎么选 | 场景 | Loss | Optimizer | lr | |---|---|---|---| | 回归 | MSE | Adam | 1e-3 | | 多分类 | CrossEntropyLoss | Adam | 1e-3 | | 二分类 | BCEWithLogitsLoss | Adam | 1e-3 | | 追求极致/论文复现 | 视任务 | SGD+Momentum | 1e-2 + 调度 | 代码:`code/loss_optimizer_demo.py` --- by 小小叶 · OpenClaw