ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

机器学习课程资源怎么学:梯度下降、特征缩放与模型评估实战

机器学习课程资源怎么学:梯度下降、特征缩放与模型评估实战

简介:面向机器学习初学者与进阶学习者的斯坦福大学吴恩达机器学习课程资料包,系统覆盖监督学习、无监督学习及模型评估优化等主题,帮助读者梳理从线性回归、逻辑回归到神经网络、支持向量机、决策树、随机森林与集成方法的知识脉络,并理解梯度下降、聚类、降维、正则化、交叉验证、特征选择等实践要点,适合课程复习、算法入门和建模思路整理。压缩包共130个文件,以71份PDF讲义为主体,辅以20张JPG与14个GIF图示、9份TXT说明,以及ZIP、HTML、CSS等配套文件,整体约17.21MB;讲义便于对照章节复习公式推导与算法流程,图示有助于理解模型结构,目录清晰方便离线查阅。已有399人学习,可作为打牢机器学习基础、对照课程内容理解算法原理与模型评估方法的辅助资料。

1. 机器学习课程资源:先别急着点开第一集

很多人拿到一套机器学习课程资源,第一反应是从第一集顺序播放,结果看到第三周就被矩阵求导和梯度下降卡住,视频进度条成了心理安慰。这套机器学习课程资源最早来自某高校的公开课,价值不在“看完”,而在它把监督学习、无监督学习、模型评估和工程取舍串成了一条可复现的线。它适合两类人:一类是刚转算法、需要把散落公式重新排成知识地图的从业者;另一类是已经会调库、但说不清正则化为什么能压过拟合的熟手。课程里的编程作业是黑匣子最少的部分,照着复现一遍,比刷十遍视频更能看清参数怎么影响结果。下面按“先搭地图、再跑代码、最后排错”的顺序拆。

2. 把课程拆成四周路线:从代价函数到模型评估的依赖顺序

这套课程资源按周组织,但知识依赖不是线性的。很多人从第一周视频顺序播,到第三周被矩阵求导拦住,不是智力问题,是前置概念没闭环。我一般先画依赖图:矩阵乘法指向代价函数,代价函数指向梯度下降,特征缩放决定梯度下降能不能收敛,正则化决定验证集分数是否可信,模型评估决定什么时候该停。课程里的神经网络、SVM、聚类都挂在这条主线上,跳着看很容易把“会调库”误当成“学懂了”。选这个顺序的理由很实际:代价函数和梯度是后面所有模型的共同语言;特征缩放是梯度类算法的前置条件;正则化和评估是模型选择的两个支点。先修不够的,先补矩阵乘法和偏导,不要硬啃。

2.1 先画依赖图:四个不能跳的节点

节点为什么不能跳跳过后常见表现最小验证
代价函数与梯度后面所有模型的训练都靠它换个损失函数就不知道梯度怎么推手推线性回归均方误差梯度
特征缩放梯度下降对尺度敏感损失震荡、不降,学习率调半天打印每列均值和标准差
正则化决定模型在验证集上是否可信训练集很好,验证集掉点对比不同正则强度
模型评估决定调参方向和停止时机用测试集反复调参,换数据就崩训练/验证/测试三分

这四个节点不是课程目录里的章节名,是判断有没有学懂的检查点。比如特征缩放,课程作业通常要求先归一化,但很多人直接套公式,结果学习率从 0.1 调到 0.0001 还是不降。我一般要求自己用两百行合成数据跑一遍,看到损失前三轮快速下降才算过。模型评估更关键,课程里讲偏差方差,但真正落地是把训练集、验证集、测试集分开,测试集只在最后用一次。依赖图画在纸上就够:代价函数指向梯度下降,特征缩放指向梯度下降,正则化指向验证集,评估指向调参。不要画复杂,箭头超过十个就看不清了。

2.2 四周路线表:每周一个可验收产出

周次核心内容必须手推代码产出验收标准
第一周线性回归、梯度下降、多元线性回归均方误差对权重和偏置的梯度从零梯度下降 + 库实现对照损失单调下降,系数接近真值
第二周逻辑回归、正则化、偏差方差、评估指标交叉熵梯度、正则项梯度C 值对比、混淆矩阵、阈值扫描验证集 AUC 高于基线,阈值能解释
第三周神经网络前向传播、SVM一层网络的链式法则小网络训练、SVM 粗网格训练/验证差距能说清原因
第四周聚类、降维、异常检测或推荐系统选学距离度量、PCA 方差解释轮廓系数、PCA 解释方差图簇数或主成分数选择有依据

四周不是硬性期限,是四个验收节点。每周的代码产出必须能独立跑,不要等全部学完再补。课程里的推荐系统和大规模机器学习可以选学,先把主干跑通。每周结束写一段实验记录:数据怎么切、参数怎么设、指标多少、失败样本长什么样。这个记录比笔记本里的输出更有用,因为下周你会忘记为什么设了那个学习率。表格里的“必须手推”不是背公式,是能在纸上写出维度变化,比如线性回归里X是(n,d),梯度是X.T @ err / n,写不出来就说明还没吃透。

2.3 用最小数据集卡住理解

不要一上来跑课程大作业。我一般先用合成数据:线性回归用两百行三特征,分类用一千行左右的生成数据,聚类用三个高斯团。这样做的好处是真实标签已知,参数错了能立刻看出来。步骤不复杂:先写公式,再写循环,然后对照库实现,最后记录差异。线性回归手写梯度下降得到权重,和库的系数对比,差异大就检查归一化和学习率;分类任务先看混淆矩阵,不要只看准确率;聚类先画散点图,再看轮廓系数。

合成数据不能代替真实数据,但它能把“维度对不上”“学习率太大”这类低级错误提前暴露。最小数据集跑通后再换课程作业数据,排错成本低很多。踩过的坑:有人直接跑大作业,损失不降,花了三天以为是算法理解错,最后发现是标签列被当成特征。先小后大不是偷懒,是省时间。第一周只要看到损失曲线正常下降、权重接近真值,就可以进入分类任务;第二周看到验证集指标和训练集指标差距可解释,再碰神经网络。

3. 用 Python 复现课程作业:环境、数据切分与第一个梯度下降

课程原生作业环境常见是矩阵式脚本环境,但日常工程和排错我更愿意用 Python 复现。理由很直接:调试器、版本管理、和库实现对照都方便。复现不是把作业翻译一遍,而是把每个公式落到可检查的变量上。环境不要追求最新,先把虚拟环境、随机种子、库版本记录做起来。下面从最小闭环开始,代码可以直接抄,参数按你的数据改。

3.1 环境最小闭环

python -m venv .venv source .venv/bin/activate # 激活命令按你的终端类型调整 pip install numpy pandas matplotlib scikit-learn python -c "import numpy, sklearn; print(numpy.__version__, sklearn.__version__)"

这段命令先创建隔离环境,避免不同课程作业的库版本互相污染;然后安装四个常用库;最后打印版本,写进实验记录。参数说明:.venv是环境目录名,可以改成项目名;激活命令在 bash 下是source,其他终端按对应方式调整;版本号不写死,因为课程作业对版本不敏感,但记录版本能在出问题时复现环境。包源按团队规范配置,不要随手改全局环境。

目录建议:data放原始数据,notebooks放探索,src放可复用函数,reports放图表和实验记录。不要把大文件塞进代码目录,后面换数据会乱。每次跑实验前先设置随机种子,numpy和分类器各设一次,不然切分和初始化都会变。

3.2 从零实现线性回归并对照库实现

import numpy as np rng = np.random.default_rng(42) X = rng.normal(size=(200, 3)) true_w = np.array([2.0, -1.0, 0.5]) true_b = 0.7 y = X @ true_w + true_b + rng.normal(scale=0.3, size=200) # 标准化:梯度下降对特征尺度敏感 mu, sigma = X.mean(axis=0), X.std(axis=0) X_norm = (X - mu) / sigma def gradient_descent(X, y, lr=0.1, epochs=500): n, d = X.shape w = np.zeros(d) b = 0.0 losses = [] for _ in range(epochs): y_hat = X @ w + b err = y_hat - y loss = np.mean(err ** 2) / 2 losses.append(loss) dw = X.T @ err / n db = err.mean() w -= lr * dw b -= lr * db return w, b, losses w, b, losses = gradient_descent(X_norm, y, lr=0.1, epochs=500) print("w:", w, "b:", b) print("first/last loss:", losses[0], losses[-1])

这段代码先用合成数据固定真值,方便验证;然后标准化,因为梯度下降对尺度敏感;损失用均方误差的一半,梯度公式是X.T @ err / n;权重和偏置分开更新,偏置是标量。参数说明:lr=0.1是归一化后的常见起点,epochs=500够看趋势;scale=0.3控制噪声,太大则损失下不去,太小则看起来“太完美”。如果损失震荡,先把学习率降到 0.01;如果损失几乎不降,检查归一化和学习率。

from sklearn.linear_model import LinearRegression model = LinearRegression().fit(X_norm, y) print("coef:", model.coef_, "intercept:", model.intercept_)

库实现的系数对应标准化后的权重,截距对应偏置。对比时不要直接和真实权重比,因为标准化改变了尺度;要么对比预测值,要么把系数换回原始尺度。常见误用是不标准化直接跑,然后怪学习率;或者把偏置也放进正则化;还有只看最后损失不看曲线。曲线比最后一个数字更能说明问题。

3.3 特征归一化与学习率的手动检查

print("mean:", X.mean(axis=0)) print("std:", X.std(axis=0)) for i, loss in enumerate(losses[:5]): print(i, loss)

均值接近 0、标准差接近 1 才算归一化到位;前三到五轮损失应该明显下降,然后趋缓。如果第一轮就出现nan,学习率太大或数据里有缺失值;如果损失下降很慢,学习率太小或没归一化。关键顺序是:先切分训练/验证/测试,再用训练集拟合归一化器,最后变换验证和测试。不要用全量数据算均值和方差,那是数据泄漏。

血泪经验:先归一化再切分,验证集分数会虚高,换数据就翻车。检查完再跑长训练。

提示:把每次实验的学习率、轮数、归一化方式写在同一行记录里,后面调参才不会乱。

4. 逻辑回归、正则化与 SVM:把参数表钉在实验记录里

课程讲算法推导很清楚,但工程落地常卡在参数。逻辑回归的C、SVM 的C和gamma、学习曲线的train_sizes,这些参数不是玄学,每个都有明确作用方向。我一般把实验写成一行:数据版本、切分方式、参数、指标、备注。不要只留一个笔记本,过两天你就不记得哪个单元格对应哪次实验。下面三个小节分别处理分类阈值、边界参数和模型诊断。

4.1 逻辑回归的阈值与正则化强度

逻辑回归用 sigmoid 输出概率,交叉熵损失,C是正则化强度的倒数,C越小正则越强。阈值 0.5 只是默认,业务上漏判和误判代价不同,阈值要扫。先看代码:

from sklearn.datasets import make_classification from sklearn.linear_model import LogisticRegression from sklearn.model_selection import train_test_split from sklearn.metrics import roc_auc_score, precision_score, recall_score X, y = make_classification(n_samples=1200, n_features=8, n_informative=5, random_state=42) X_train, X_test, y_train, y_test = train_test_split( X, y, test_size=0.25, random_state=42, stratify=y ) for C in [0.01, 0.1, 1, 10]: clf = LogisticRegression(C=C, max_iter=1000) clf.fit(X_train, y_train) proba = clf.predict_proba(X_test)[:, 1] pred = (proba >= 0.5).astype(int) print(C, round(roc_auc_score(y_test, proba), 4), round(precision_score(y_test, pred), 4), round(recall_score(y_test, pred), 4))

这段代码生成可复现的分类数据,分层切分保持类别比例,遍历C看 AUC、精确率和召回率。参数说明:C从 0.01 到 10 是数量级扫描,不是精确搜索;max_iter调到 1000 避免不收敛警告;阈值 0.5 只是基线,后面可以按业务代价在 0.2 到 0.8 之间扫。AUC 看排序能力,精确率和召回率看阈值后的取舍。不要用测试集反复选C,应该用验证集或交叉验证。

参数调整现象动作
C调大正则减弱,训练集拟合更强验证集掉点就回调

本文还有配套的精品资源,点击获取

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进