本节摘要:神经网络训练是从"调参数让损失尽可能小"展开的迭代过程。本节讲清优化问题的三要素——参数、目标函数、求解策略,解释为什么深度学习必须靠迭代逼近,并动手跑一个一维示例,为后面区分激活、损失、优化器铺底。
回到那一台天平上。我们真正想做的,是去找一组能让损失最小的参数,这听起来像一句话能说完,做起却比想象麻烦得多。本节先把"优化到底在解什么"拆开,再看它难在哪儿,最后用玩具代码把"迭代逼近"跑给你看。
任何一个训练过程,都能压缩成三句话:
把这三句话叠起来,就是一个标准的无约束优化问题:给定一个目标函数,在参数空间里找使目标最小的那组参数。听完这句话你可能觉得:找最小值还不容易?可难点就藏在"参数空间太大、目标函数太复杂"这件事里。
学生时代我们求一元函数最小值,靠的是求导置零解方程。但神经网络的损失函数对参数基本不可能写出闭式解——参数量百万级,函数关系层层嵌套还混着非线性(这就是为什么要有激活函数,下一节讲),解方程这条路当场堵死。
于是所有人退回到同一条路:迭代逼近。从一个随机的起点出发,每一步都让损失降一点点,多走几步,逼近一个还不错的解。这像给天平一点点调节配重,而不是要求一次就调到水平。
我们把损失记作 L,参数记作 w,那么"更新参数"这件事通常写成这样:
# 概念代码:一次最简单可行的参数更新 def step(loss_func, w_old, grad, lr): # grad 是损失对参数 w 的梯度,粗略理解成"上升最快的方向" # 我们要下降,就走反方向,所以前面是负号 w_new = w_old - lr * grad return w_new
这里 lr 叫学习率,决定一步走多远。lr 太小,走到猴年马月;太大,可能一脚踩过头,在天平上来回晃。这只是最简单的一版,第 4 章会看到无数聪明的改进。但注意:无论后来优化器多花哨,骨架始终是这句"减去学习率乘梯度"。
光看公式不容易有体感。我们来解一个真实的玩具问题:找到让下面这个多项式最小的 x。
import math def f(x): # 故意做成有一个极小值的简单函数,方便肉眼验证 return (x - 3.0) ** 2 + 5.0 def df(x): # 它的导数,梯度在这里就退化成导数 return 2.0 * (x - 3.0) x = 10.0 # 随机起点 lr = 0.1 for t in range(60): x = x - lr * df(x) print(f"迭代后 x = {x:.3f}, 目标值 = {f(x):.3f}") # 期望输出:迭代后 x 约等于 3.0,目标值约等于 5.0
从这个例子能读出三个结论,也是全书反复使用的观察:
lr=0.1 在 60 步内就落到 3.0;把它改成 lr=1.9,你会看到它在最优点附近剧烈震荡,改到 2.1 甚至直接发散——同一套逻辑,常数一变,结果天差地别。这就是优化的第一课:解本身不神秘,难的是决定每一步走多远、怎么把步子走稳。
看懂了迭代,就能理解为什么要反复强调"平衡"。
第一个张力是拟合与泛化。只管把训练集上的损失压到极低,可能只是死记硬背,遇到新数据就露馅(过拟合);完全不顾损失,又什么都学不会。损失函数在这里设了标尺,正则化(第 5 章)则在旁边按住别让天平过分倾斜。
第二个张力是快与稳。步子迈大收敛快,却容易震荡或发散;步子迈小稳定,却慢得让实践者发狂。优化器大部分花样,本质都是在"快"与"稳"之间找平衡点。
💡 关键直觉:整个教程的"天平桌"意象不是比喻玩票——激活函数、损失函数、优化器,恰好就对应天平上的表达力砝码、刻度尺、和搬砝码的手。看清这一点,后面每一章都是在往这张桌上补齐称量的细节。
很多人第一次听说梯度下降,脑子里缺一张"地形图"。我们用一个二维山丘来建立直觉:把参数当成横纵坐标,把损失当成高度,那么训练就是在一张连绵起伏的地形图上找最低的洼地。
这张图记不住没关系,但请你记住三个会反复出现的地形名词:
深度学习里真正的麻烦不是"守着一个局部最优永远出不来",而是"在鞍点和高原上浪费时间"。这个认知会在第 4 章 4.6 节被用到,但现在先把它种下。
如果你只想要"现在能开始训网络"的操作感,把下面这份清单记住即可,细节后续各章展开:
这份清单是第 5 章"实战调试"的序曲。现在把它放在案头,等读到第 5 章的时候,它会与你手中的所有细节串成一套完整打法。
下一节把这台天平正式展开,看激活、损失、优化器三个砝码各自称量什么。