AI 工程地基 24|线性回归:程序跑完了,训练没跑完
机器学习的正片从一条直线开始。给一百个点——房子面积和成交价——画一条最贴合的直线,再用这条直线报新房价。听起来不像「学习」,但这个例子把训练循环的四个动作第一次完整摆了出来:定模型、定损失、算梯度、改参数。以后每个算法,从决策树到深度网络,都是这四步换皮。这一课把它们在显微镜下过一遍。
AI 工程地基 24|线性回归:程序跑完了,训练没跑完
机器学习的正片从一条直线开始。给一百个点——房子面积和成交价——画一条最贴合的直线,再用这条直线报新房价。听起来不像「学习」,但这个例子把训练循环的四个动作第一次完整摆了出来:定模型、定损失、算梯度、改参数。以后每个算法,从决策树到深度网络,都是这四步换皮。这一课把它们在显微镜下过一遍。
模型本身两行字:y = wx + b。w 是斜率,面积每多一平米价格涨多少;b 是截距,面积为零时的底价。难的不是写模型,是回答两个问题:多贴合算贴合?怎么找到最贴合的那对 w 和 b?
一千步之后
课程用均方误差当「贴合尺」:每个点预测价和真实价的差,平方,加起来取平均。选平方有两个理由:大错挨的罚远超小错(差 10 的罚是差 1 的一百倍,不是十倍),以及平方处处光滑,能求导。
有了尺子,就可以往下走。梯度下降:算出当前 w 和 b 处误差上升最快的方向,朝反方向挪一小步,重复。误差曲面在这个问题里是一个碗,走得够久就到碗底。课程的代码从零写了全套,一百行不到,跑一千轮。
结果:学出 y = 3.14x + 6.54,真值是 3.0x + 7.0。看着挺像回事。
同一页往下翻,还有第二条路。线性回归有个一步到位的公式,直接解出最优权重,不用迭代。跑它:y = 3.076x + 6.985。
两条路给的答案不一样。差多少?看误差:梯度下降一千轮后是 3.698,公式的最优值是 3.644。也就是说,梯度下降还没走到碗底——截距 6.54 对 6.99,最后那 6% 的路没走完。程序跑完了,训练没跑完,而代码里没有任何一行能告诉你这件事。
慢的原因不神秘。这份 x 数据取值在 0 到 10 之间,没有减去均值。就这么一个细节,把误差碗从圆形拉成一个窄长的椭圆:斜率方向陡峭,截距方向近乎平地,两个方向的陡峭程度差了 121 倍。每一步在平的方向上只挪一点点,一千步不够。把 x 减去均值再跑,同样一千步,直接走到公式解跟前。
有意思的地方在这。课程把「特征要先标准化」写在了后面多元回归那一节,当作新知识讲。而它自己的一维示例已经先挨了这一刀,只是挨得轻:参数都「差不多对」,没有报错,没有警告,没人喊疼。特征没缩放时,代价不是崩,是悄悄走不完。这在真实项目里更难发现——课程的数据小,等得起一万轮;真实训练跑一天,你等不起第二次。
谁来当裁判
那信哪个:3.14,还是 3.08?
真值是 3.0,公式解 3.076,梯度下降 3.143。离真值近的是公式解。但这个评分你看不到——现实里没有真值,造数据的人才看得到 3.0。所以判断「跑够了没有」,只有两条可靠的路:误差曲线是否走平,或者和一个能一步到位的解比一比。这份样本上,公式解的误差 3.644,梯度下降停在 3.698。差距看着不大,但没合上——没合上,就是没到底。
有人会说,差这么点也无所谓吧?单看这一题确实无妨。但「差一点」的原因值得记住:不是梯度下降不行,是它没走完。同样的代码,同样的步长,跑一万轮,六个小数位和公式完全一致。方法没问题,停早了。这类「停早了」在真实项目里不会自己暴露——程序正常退出,数字看着正常,没有报错。
课程结尾有一句话:你的从零实现和 scikit-learn 会产出相同的结果。严格说,这句话在这里还不成立。同一份数据上,scikit-learn 给 3.0756 和 6.9853,梯度下降版给 3.1433 和 6.5432。小数点后第二位就分道。「相同」的前提是「跑够」——真正和库精确到六位一致的,是那个一步公式。跑够了是同一个解,是数学;跑出来一样,是工程——得先跑够。
一步到位的公式,和它的两个前提
一步公式看着优雅:小数据集直接解,不用调学习率。课程的描述是「对小数据集完美工作」。这句话背后站着两个没写出来的前提。
第一个前提:特征之间不能长得太像。构造一个极端案例:两个特征几乎相同——第二列就是第一列加上一点小数点后十位的抖动。真实权重是 2 和 3。跑公式,解出来是四亿五千万和负四亿五千万。两个几乎一样的特征,模型无法分辨功劳归谁,最优解在一条长长的山脊上,数值求解会走到山脊的远端——权重爆掉,预测却还能看。第十五课讲线性系统时见过同一个病:矩阵的条件数冲到天文数字,解就不可信。药方也一样:在求解时给对角线加一点微小的压制,lambda 取百万分之一,解立刻回到 2.53 和 2.53,稳定。这就是 Ridge 回归的雏形——它买的不是更好的拟合,是一个值得相信的解。
第二个前提:算得动。课程说,大数据集该用梯度下降,因为矩阵求逆是立方量级。这句话有个容易记错的地方——立方项数的是特征数,不是行数。实测一下:一千万行、五个特征,算完所有内积只要 0.7 秒,解五乘五的方程瞬间完成。行数翻倍,时间只是跟着翻倍。反过来,特征两千个时求解 0.35 秒,特征四千个时 1.98 秒——特征翻倍,时间接近翻八倍。立方项在这里。课程的随课技能文件把这个写反了:它说「数据集大到几百万行,正规方程因为立方复杂度太慢」。按行数算,百万行小意思;真正的分水岭是特征数多到求解变贵,或者数据大到单机装不下。
系数一万,不算最大
多元回归把直线换成超平面,三个特征一起上:面积、卧室数、房龄。课程先做标准化,再训练,打印权重。这里埋着本课最实用的一课。
如果没有标准化,直接训练会得到权重约 54、10145、-1008(面积每平米 54 元,卧室每间一万,房龄每年折一千)。直觉马上说:卧室最重要,系数一万呢。
这是单位在骗人。面积动一格是几百上千,卧室动一格是一间,房龄动一格是一年——三把不同的尺子,系数没法直接比大小。标准化之后,权重变成 0.77、0.28、-0.27:面积才是压倒性的老大,卧室和房龄是小角色。把每个特征换成「偏离均值几个标准差」的通用单位,权重才第一次可以同台比较。
课程的学习目标里写着「解释学到的权重」,正文到了这一步只打印了数字,没有解释。补上这句解释,标准化才露出它的第二重价值:不只是让训练走得快,还让权重变得能读。读模型的人拿到 0.77 和 0.28,可以直接说出「面积动一格,顶卧室动两格还多」这种能落地的结论。
弯的路,直的车
关系是弯的怎么办?造新特征:把 x 的平方、立方当普通特征喂进去,模型仍然是「对权重线性」的线性回归。课程跑了二次和五次两档对比,打印结论「五次在训练数据上稍好,但在新数据上有风险」。
这句话值得多看两眼。首先,两个对比数字本身都在半路。x、x 的平方、x 的立方,这些特征在 0 到 1 区间上彼此长得太像,误差碗的最平方向坡度只有最陡方向的四百多万分之一——两千轮下来,那个方向几乎没动。用一步公式直接求解,二次到 0.678,五次到 0.711,这才是两个模型各自的底。其次,「有风险」这半句没有任何数据支撑——课程没有切开数据。这句话要自己动手才能看见,也就是练习二。
练习二我跑了。三次曲线加噪声,四十个点,随机切四分之一当考试。一次多项式:训练 0.41,考试 0.26。三次:训练 0.94,考试 0.95,学到了真东西。十次:训练 0.96,考试从 0.95 掉到 0.69——训练分还往上蹭了一点,考试塌了。训练分数是模型的自述,考试分数才是外部世界对它的评价,两者的裂缝就是过拟合。裂缝在三次和十次之间出现。
课程还留了练习三当钩子:Lasso 用绝对值惩罚,会把不重要的权重压到整整的零;Ridge 用平方惩罚,只能压小、压不死。为什么一个能压死一个不能?把两种惩罚函数在坐标轴上画出来,一个带尖角一个圆润,答案就藏在那个尖角里。想明白这个,后面看正则化的展开会顺很多。