AI 工程地基 25|逻辑回归:错得越狠,喊得越轻
还是预测,但这回要预测的东西只有两个值。肿瘤是恶性还是良性,考试是过还是挂。上一课的线性回归在这里直接翻车:拿直线去拟合 0 和 1,它给你的输出是 0.3、1.7、-0.5 这种数。1.7 是什么?非常恶性?-0.5 是非常良性?没人知道。分类要的是 0 到 1 之间的概率,外加一条清楚的线:线这边是一类,线那边是另一类。
逻辑回归的做法一句话讲完:线性部分照旧,算出 z = wx + b,再把这个 z 塞进一个叫 sigmoid 的函数。这个函数长得像拉长的字母 S,专门把任何数字压进 0 和 1 之间。z 是零时它输出 0.5,z 很大时趋近 1,z 很负时趋近 0。输出当成概率用,过 0.5 判成一类,不过判成另一类。名字里虽然带着「回归」,它是分类算法——名字来自它用的那个弯函数。
课从这里往下走,走到一半会遇到一个真问题。这个问题值得停下来多待一会儿。
换一把尺子的真正原因
训练需要一个损失函数:一把给预测打分的尺子。上一课用的是均方误差,预测值和真实值之差的平方再取平均。这一次不能接着用了。课本给的答案是:均方误差配上 sigmoid 会产生一个非凸的损失曲面,带很多局部极小,梯度下降会陷进去出不来。
这话是真的,而且比课本说的还要狠。
拿课里那个最小的例子实测:十个学生,学习时长 1 到 10 小时,前四个挂科后六个通过。模型就是一个 sigmoid。用均方误差训练它,随机选两百个起点各跑一遍——82 个起点,超过四成,永远停在同一个答案上:预测所有人挂科。损失正好 0.6(六个真通过的每人贡献一个 1 的平方,6 除以 10)。继续跑,五十万轮,纹丝不动。这不是模型笨,是它站在一块坡度恰好为零的平地上,梯度下降按定义不会挪动。
为什么偏偏是「全员挂科」这个答案陷住?因为均方误差对 sigmoid 求导,会带出一个 sigmoid 自身导数的因子。这个导数最陡的地方也只到 0.25,两端趋近零。而模型错得最狠的地方——真实是通过,模型却说概率几乎是零——恰恰是 sigmoid 最平的地方。错得越狠,梯度越小,喊得越轻。拿一个具体的点算:真实标签是 1、模型给出概率 0.000000002 的地方,交叉熵的梯度是均方误差的两亿多倍。均方误差在这里几乎失声。
交叉熵的公式看着凶,其实是对数在干活:sigmoid 的输出 p 取了负对数之后求导,对数的导数和 sigmoid 的导数正好相消,最后剩下 (p−y)x 这么一个干净的式子。y 是真实标签,p 是预测概率。差多少,梯度就多大:模型说 0.29 真实是 1,梯度就拽 0.71 那么用力;模型说 0.99,几乎不拽。课程提到这个式子和线性回归的梯度「长得一模一样」,确实像——但真正的重点是前面那步相消。换损失函数换的不是表面公式,是把「错得越狠越没声」这个毛病治掉。刚才那两百个起点换成交叉熵,从同一个饱和位置出发,两千轮就出来了,两百个起点全部汇进同一个谷底。
凸了,然后呢
交叉熵给逻辑回归一个凸的损失曲面:只有一个谷底,不会陷进别的坑里。课本说这保证了单一全局最小值。这句话在这份数据上成立——但「最小值存在」和「你走到了它跟前」是两回事。
课程的训练集 160 个点,其中有两个钉子户:一个真恶性的点落在边界另一侧,一个真良性的点贴着 0.5 站错半步。就这两个点,让最小值存在,但把它推到了很远的地方——剩下 158 个可分的点一路把权重往外推,两个钉子户当刹车,拉锯的结果是终点很远但有限。跑完课程设定的一千轮,损失 0.129;那个真正的谷底是 0.039,差着三倍多。用同样的步长接着跑,要到三十万轮才贴到最小值跟前。
上一课刚演过「程序跑完了,训练没跑完」,这一课换了个机制再演一遍:上次是特征没中心化把碗拉长,这次是数据几乎可分把谷底推远。更微妙的是,这次连准确率都帮不了你。测试集二十一个恶性、十九个良性,隔着一道宽沟,训练到一千轮就已经全部判对,之后再跑二十九万轮,一个判定都不会变。
但概率一直在变。拿 (3.5, 3.5) 这个点盯住:一千轮时模型说 0.54,三千轮 0.52,十万轮 0.60,三十万轮 0.62。判定早就锁死了,信心还在一路变陡。如果你只关心对错,早停无妨;如果你要用这组概率本身——风险定价、置信度、要不要复查——那「准确率满了」和「概率站稳了」就是两件事。顺带一个小发现:训练打印的第一行损失是 0.6289,而不是初始状态该有的 0.6931——代码是先更新一步才打印的,想对数的人会在这里愣一下。
还有一种更极端的情况值得一提。要是训练数据完全可分——连钉子户都没有——那个最小值就干脆不存在了:权重一路涨上天,损失无限趋近零但永远够不着。scikit-learn 的逻辑回归默认带一点正则化,兜的就是这件事。
记分牌上的空场比赛
课程最后说,你的从零实现和 scikit-learn 会给出同样的决策边界。实测了三方:手写版一千轮、scikit-learn 不加正则(同一条损失的理论最优)、scikit-learn 默认设置。三条边界的斜率分别是 -1.30、-1.21、-1.16,各不相同;把它们铺在同一张图上,有百分之一点四到百分之二点八的格子会给出相反的判定。它们在这份测试集上倒是都拿满分——但那是因为题太容易,不是殊途同归。
这也解释了为什么报告里 precision、recall、F1 全是 1.0000:二十一个对一个不错,十九个对一个不漏,记分牌上没有一场有输赢的比赛。整套指标的真正舞台在课程的阈值表里:阈值压到 0.3,两个良性被误报成恶性,precision 掉到 0.913;抬到 0.7,两个恶性被漏掉,recall 掉到 0.905。这张表才是本课真正的记分牌——precision 和 recall 此消彼长,阈值往哪边挪,取决于误报和漏报哪个更贵。垃圾邮件过滤怕误拦,往高调;癌症筛查怕漏诊,往低调。
从 0 扫到 1,算出个负数
课程练习三:对 0 到 1 之间的一百个阈值,分别算真阳率和假阳率,画 ROC 曲线,用梯形法算曲线下面积。照着字面做,会算出 -1.0。
不是算错,是方向反了。阈值从 0 涨到 1,假阳率从 1 降到 0——曲线是从右往左画的。梯形法跟着点的顺序走,面积就成了负的。把两个数组的顺序倒过来,答案就是正常的 +1.0:这份测试集上,真是良性的最高概率 0.311,真是恶性的最低概率 0.563,两组数中间隔着一道 0.25 宽的空档,阈值放在空档里任何位置,都是满分。ROC 曲线贴着左边界和上边界走出一个直角——这个直角有多圆满,两群分数的空档就有多宽。
讨论回复
加载中...正在加载回复...
推荐
智谱 GLM-5 已上线
我正在智谱大模型开放平台 BigModel.cn 上打造 AI 应用,智谱新一代旗舰模型 GLM-5 已上线,在推理、代码、智能体综合能力达到开源模型 SOTA 水平。