简介:面向正在学习吴恩达机器学习课程、需要课后编程练习与复盘对照的高校学生和自学者,这份压缩包把作业、答案、课堂讲义与中文笔记整合在一起,可解决练习缺参考答案、知识点分散、打印复习不便等问题。包内共 1028 个文件,以 623 个 .m 脚本、146 个 .txt 说明、103 个 .mat 数据、61 个 .ipynb 笔记本和 44 个 .pdf 文档为主,整体约 202.33MB,涵盖线性回归、逻辑回归、PCA 人脸数据处理、K-means 图像压缩及 Exercise7 等典型练习场景。作业分无答案与有答案两版,其中有答案又细分为三版,并附可直接打印的题目合并版 PDF;课堂讲义与中文个人笔记同样支持打印,便于边做题边查漏补缺。已有 2538 人学习下载,适合按课程章节推进、对照多版答案理解实现差异,并借助 .mat 数据与 Notebook 复现实验过程。
1. 一份双版本作业,考的是你能不能把公式写成代码
很多人拿到这套机器学习作业,第一反应是先翻有答案版,从头看到尾,看懂每一行,然后觉得自己会了。真到面试现场,面试官让你手写一段带正则化的代价函数,或者随口问一句「你的 theta 是几维」,立刻就露馅。这份资源的价值恰恰在双版本:无答案版逼你把公式变成能跑的代码,有答案版给你一次逐行对照的机会,个人笔记则是把对照出来的差异沉淀成自己的东西。它适合三类人:正在系统过一遍机器学习基础的自学者、准备算法岗或数据岗面试的应届生、以及带项目但要补理论底子的开发者。拿分的逻辑很简单——形状写对、公式写对、指标选对,三件事占掉大部分分数。
2. 考点分布:八次作业对应四类面试题
先把这张地图记住。作业本身是练习,但每一份作业背后都对应一类面试题,知道自己正在练的是哪一类,比闷头写完八份更值钱。
| 作业 | 主题 | 对应面试考点 | 出现频率 |
|---|---|---|---|
| 1 | 单变量与多变量线性回归 | 梯度下降、正规方程、特征缩放 | 高 |
| 2 | 逻辑回归与正则化 | sigmoid、交叉熵、决策边界、lambda 取值 | 极高 |
| 3 | 多分类与前向传播 | one-vs-all、softmax、维度检查 | 高 |
| 4 | 神经网络反向传播 | 链式法则、梯度检验、参数初始化 | 极高 |
| 5 | 正则化回归与偏差方差 | 学习曲线、欠拟合与过拟合、lambda 调参 | 极高 |
| 6 | SVM 与文本分类 | 核函数、C 与 sigma、精确率与召回率 | 中高 |
| 7 | K-means 与 PCA | 初始化、肘部法、方差保留率 | 中 |
| 8 | 异常检测与协同过滤 | 高斯阈值、F1 选阈值、矩阵分解 | 中 |
把这张表按面试分值折算一下:基础推导类大约占两成,场景选择类占四成,调参排错类占四成。也就是说,八份作业里真正拉开差距的不是「能不能推导出梯度」,而是「给你一个不收敛的模型,你从哪儿开始查」。作业 5 和作业 8 看着不起眼,反而是排错类问题的主要素材来源,别跳过。
2.1 四类题型的答题骨架
第一类是手写推导,比如「写出带正则化的逻辑回归代价函数并对 theta_j 求偏导」。这类题面试官只看两件事:正则项有没有跳过偏置、除以 m 的位置对不对。第二类是形状题,「X 是 m×n 还是 m×(n+1)」「theta 几维」「反向传播里 delta 的维度和哪一层对齐」,答错基本就结束了,因为它说明你从没自己跑通过一遍。第三类是排错题,给你一段损失不下降的代码让你找 bug。第四类是场景题,比如「样本正负比 1:99,你用准确率评估合适吗」。
2.2 无答案版怎么练:三次跑不通原则
无答案版不是让你从零发明算法,而是让你在不偷看的情况下把公式落到代码里。建议同一份作业写三遍:第一遍只照着讲义公式写,允许报错,把报错信息抄进笔记;第二遍打印每个中间变量的形状和前三行数值,确认矩阵乘法的顺序没反;第三遍拿一个只有三四条样本的极小数据集,手工算一遍代价和梯度,和代码输出对照,差在小数点后第三位以内才算过。
这三遍的意义在于逼你暴露「以为懂了其实没懂」的地方。血泪经验是:绝大多数人的卡点不在数学,而在X @ theta和theta @ X的先后、以及求和轴选错。这类错误只有自己撞过一次才记得住。
2.3 有答案版怎么核:对照三层,不要通读
有答案版最忌讳通读。通读会产生强烈的「我会了」的错觉,但那是理解别人的代码,不是自己能写。正确的用法是拿自己的版本和答案做三层对照:形状层看每个变量的维度是否一致;数值层在同一个初始点上比较第一次迭代后的代价,差距大就说明公式里少了一项或者多除了一次 m;写法层看对方有没有做向量化,把 for 循环改成矩阵运算的部分抄进笔记并写一句「为什么能这么改」。
对照完不要立刻删掉自己的版本,把它留在旁边。等过两周再回来重写一遍,如果还是卡在同一个地方,那个地方就是你的真实短板,面试前重点补它。
3. 高频考点:回归与正则化的作答模板
回归是整条链路的地基,正则化是面试官最爱追问的钩子。这一章的内容在作业 1、2、5 里反复出现,练透一次能覆盖三份作业。
3.1 形状先对齐:theta、X、y 的约定
先把约定固定下来:X 是 m×(n+1),第一列全为 1 的偏置列;y 是长度为 m 的向量;theta 是长度为 n+1 的向量。所有公式都建立在这个约定上,一旦换约定,写法全变,所以面试时最好先声明一句「我这里 X 的第一列是偏置列」,面试官会觉得你写过真代码。
被问到「为什么要单独加一列 1」时,答法不是「方便」,而是「把偏置项 b 吸收进参数向量,使假设函数统一写成内积形式,梯度也能一次性用矩阵乘法算完,省掉一个独立的更新分支」。这个回答同时解释了向量化的动机,比背定义有效。
3.2 正则化:为什么偏置项不进求和
这是最高频的一个追问。标准答法分两层:从数学上看,偏置只控制曲线的平移,不控制弯曲程度,惩罚它对降低模型复杂度没有帮助;从优化结果上看,如果真的惩罚偏置,模型会倾向于用放大某个特征权重的方式来补偿被压小的平移量,反而让解更不稳定。所以求和从 j=1 开始,theta_0 单独放行。
代码里怎么体现这一点,看下面这段。
import numpy as np def cost_reg(theta, X, y, lam): # theta: (n+1,), X: (m, n+1) 第一列是全 1 的偏置列, y: (m,) m = y.size h = X @ theta # (m,) 一次算完所有样本的预测 err = h - y # 正则项从 theta[1:] 开始,跳过偏置 reg = lam / (2 * m) * np.sum(theta[1:] ** 2) return (err @ err) / (2 * m) + reg def grad_reg(theta, X, y, lam): m = y.size err = X @ theta - y g = (X.T @ err) / m # (n+1,) 未加正则的梯度 # 用 0 占位拼回 n+1 维,保证偏置项不被惩罚 reg_vec = np.r_[0.0, theta[1:]] * (lam / m) return g + reg_vecX.T @ err这一步是把「对每个参数 j 求和所有样本的误差乘特征」压成一次矩阵乘法,结果形状正好是 (n+1,),和 theta 对齐,可以直接做theta - alpha * g。np.r_的作用是在前面补一个 0,让正则向量和 theta 维度一致,如果不补,直接加会报维度错误。注意正则项的系数是lam / m而不是lam,因为原始代价里已经有 1/(2m),求导后剩 1/m。
逻辑回归只需要把X @ theta换成sigmoid(X @ theta),其余结构完全不变。这一点在面试里值得主动说出来,等于告诉对方你理解的是框架而不是死记。
3.3 真题演练:损失不下降,从哪儿开始查
题目:一段梯度下降代码跑了 500 轮,代价一直在 0.69 附近抖动。给出你的排查顺序。
答题思路按四步走,每步都要说出「为什么先查这个」。第一步查学习率,把 alpha 缩小十倍再跑,如果代价开始单调下降,说明步子迈大了;第二步查特征缩放,如果不同特征的量级差了几个数量级,等高线会被拉成细长椭圆,同一个学习率对某个维度过大、对另一个过小,这是作业 1 里最经典的坑;第三步查更新是否同步,也就是有没有在算完新 theta 之前就把它用到下一个参数的更新里;第四步才是查公式本身,比如正则项多除了一个 m、或者梯度符号写反。
面试官最想听的是第一步和第二步的顺序,因为这说明你有工程直觉而不是只会背公式。补一句「如果四步都排除,我会用数值梯度做一次梯度检验」基本就收尾了。
3.4 特征缩放为什么能救命
被问到「为什么归一化之后收敛快」,不要只说「数据在同一量级」,要说「梯度下降的收敛速度取决于 Hessian 的条件数,特征量级差异会让条件数变大,等高线变成狭长的椭圆,梯度方向几乎垂直于最优方向,于是在峡谷两侧来回震荡」。这句话说完整,比你贴十行代码有用。
实践中常用的两种做法:均值归一化(x - mean) / (max - min),以及标准化(x - mean) / std。作业里多用前者,工程上多用后者,因为标准化对异常值没那么敏感。回答时补一句「训练集算出的均值和方差要保存下来,预测时用同一组参数」,这是面试官常埋的追问点。
4. 高频考点:从反向传播到无监督的选择题
如果说前一章考的是「会不会写」,这一章考的是「知不知道什么时候用哪个」。作业 3 到作业 8 的内容基本都在这条线上。
4.1 前向传播:维度检查表
神经网络的题,一半的分数在维度上。养成一个习惯:每写一层就写出它的输入输出形状。假设第 l 层有 s_l 个单元,那么权重矩阵 W 的形状是 (s_l, s_{l-1}),偏置 b 是 (s_l, 1),激活值 a 是 (s_l, 1)。注意这里 W 是「后一维在前」,和很多人直觉相反,但只有这样W @ a_prev才能成立。
面试里常见的追问是「样本按列排还是按行排」。两种都行,但必须前后一致:按行排时一次前向是A_prev @ W.T + b.T,按列排时是W @ A_prev + b。答错这个不会有人怪你,但前后不一致会被认为没真正跑通过代码。
4.2 反向传播:链式法则的答题模板
反向传播的题,面试官一般不要你推完整套,只要你说清「误差怎么从输出层往回传」。模板是三句话:先算输出层的误差 delta,它等于预测减真值再乘激活函数的导数;再把这一层的 delta 用转置后的权重传回前一层,逐元素乘上前一层激活的导数;最后用「前一层的激活值乘以本层 delta」得到权重梯度。
def backprop_grad(params, X, y, sizes, lam): # sizes = [输入维, 隐藏层维, 输出维],示例为三层网络 W1, b1, W2, b2 = unpack(params, sizes) m = X.shape[0] # 前向:保留中间激活,反向时要用 A1 = sigmoid(X @ W1.T + b1) # (m, h) A2 = sigmoid(A1 @ W2.T + b2) # (m, out) # 输出层误差:多分类用 softmax+cross entropy 时可简化为 A2 - Y d2 = (A2 - y) / m # (m, out) # 传回隐藏层:d2 @ W2 得 (m, h),再乘本层激活的导数 d1 = (d2 @ W2) * A1 * (1 - A1) # sigmoid 导数 = a*(1-a) gW2 = d1.T @ A1 if False else d2.T @ A1 # (out, h) gb2 = d2.sum(axis=0, keepdims=True) gW1 = d1.T @ X # (h, in) gb1 = d1.sum(axis=0, keepdims=True) # 只对权重加正则,偏置同样跳过 gW2 += lam / m * W2 gW1 += lam / m * W1 return pack(gW1, gb1, gW2, gb2)关键在三处注释:A1 * (1 - A1)是 sigmoid 的导数,用激活值本身就能算,不必重新过一遍函数;d1.T @ X之所以能把所有样本的梯度一次算完,是因为它对样本维度做了求和;sum(axis=0, keepdims=True)里的keepdims不能省,否则偏置梯度会掉成一位数组,和参数形状对不上。最后那两行正则只加在权重上,和上一章的逻辑一致。
提示:面试现场写这段时,先把 shapes 用注释标出来再写式子。写错一个转置很常见,但形状标了却写错,说明是理解问题;形状没标写错,至少还能解释成笔误。
4.3 偏差与方差:学习曲线的四种读法
作业 5 的核心是判断模型处于高偏差还是高方差,以及对应的补救动作。四种典型形态记牢:训练误差高、验证误差也高且两者接近,是高偏差,加特征或加多项式项;训练误差低、验证误差明显高,是高方差,加样本或加正则;训练误差高、验证误差更高但差距不大,是偏差为主,先加复杂度;两者都低且接近,是刚好,可以停手。
这道题的高分点在于补一句「如果加样本之后验证误差降得很慢,说明模型已经接近高偏差区间,继续加数据性价比很低」。这句话体现的是成本意识,比单纯背四条结论更打动人。
4.4 SVM 与无监督:四个小问的答法
SVM 的常考题是「C 和 sigma 各自调大调小会发生什么」。答法:C 是惩罚系数,C 大意味着不容忍误分类,间隔变窄,容易过拟合;C 小则容忍更多错分,间隔宽,更偏向欠拟合。sigma 是高斯核的带宽,sigma 大核函数平缓,模型简单;sigma 小核函数尖锐,边界贴着样本走,容易过拟合。两句话说完,再补一句「实际调参时先固定一个,扫另一个」就够了。
K-means 的常考题是「为什么结果不稳定」。答法是初始化敏感,可能落入局部最优,解决办法是多次随机初始化取代价最小的那次;再补一句 K 的选择可以用肘部法,但肘部法只是启发式,最终还是要看业务上可解释的簇数。
PCA 的常考题是「PCA 和特征选择的区别」。答法:特征选择是保留原特征的一个子集,可解释性还在;PCA 是把原特征线性组合成新的正交方向,降维更彻底但失去了物理含义。追问答「怎么定主成分个数」,答累计方差贡献率达到 95% 或 99%,或者看碎石图的拐点。
异常检测的常考题是「阈值怎么定」。标准答法是不要用准确率,因为异常样本极少;用验证集上的 F1 扫一遍 epsilon,取最大值。作业 8 里专门练过这个流程,面试时把「为什么不用准确率」讲清楚,比报出 F1 具体数值重要。
5. 易错点:五个最容易在面试现场翻车的点
这些坑几乎每一届都有人踩,而且踩的时候往往不自知。
5.1 把正则化加到了偏置上
错在哪:代码里直接写theta * lam / m整列相加。
为什么错:偏置只控制平移,惩罚它会让模型用放大特征权重的方式补偿,反而削弱正则效果。面试官问这一句,本质是在确认你知不知道正则化惩罚的是什么。
怎么答对:写公式时明确从 j=1 开始,写代码时用np.r_[0.0, theta[1:]]占位;同时补一句「有些实现为了方便会把偏置也正则,影响很小,但默认约定是不加」。
5.2 用准确率评价偏斜数据集
错在哪:正负样本 1:99 的分类任务,模型全预测成负类,准确率 99%,答「模型效果很好」。
为什么错:准确率在类别极不均衡时被多数类主导,完全反映不出少数类的识别能力。
怎么答对:改口说用精确率和召回率,并解释二者的取舍:精确率高意味着误报少,召回率高意味着漏报少;如果两者都要兼顾,用 F1。再补一句「阈值不是固定的 0.5,要按业务代价调」,这一句是加分项。
5.3 把 PCA 当成特征选择
错在哪:说「PCA 是从原特征里挑出最重要的几个」。
为什么错:PCA 得到的是原特征的线性组合,新维度和原特征不是一对一关系,可解释性已经丢了。
怎么答对:明确区分三件事——特征选择保留子集、PCA 做线性变换降维、自编码器做非线性降维。答完再补一句「如果下游需要解释每个特征的影响,我不会用 PCA」。
5.4 反向传播里漏掉梯度检验,也漏掉除以 m
错在哪:手写反向传播时代价用了 1/(2m),梯度却忘了除 m,导致梯度大了一个数量级,训练直接炸。
为什么错:代价和梯度的缩放系数必须匹配,这是纯代数一致性,不是调参能救的。
怎么答对:写完先做一次数值梯度检验,(J(theta+eps) - J(theta-eps)) / (2*eps)和解析梯度逐个比,相对误差小于 1e-7 才算对。面试时主动提梯度检验,等于告诉对方你调试过真实的网络。
5.5 学习曲线的横轴理解反了
错在哪:被问「加更多训练样本会怎样」时,答「训练误差会下降」。
为什么错:样本变多,模型更难拟合全部数据,训练误差通常是上升的,验证误差则下降并逐渐逼近训练误差。
怎么答对:先说两条曲线的走向,再说「如果两条曲线很快就贴在一起且都停在较高位置,说明是高偏差,加样本没用,得加特征」。这个结论比走势本身更值钱。
6. 答题技巧:把八份作业压成三张答题卡
练到最后你会发现,八份作业真正需要背下来的东西并不多。我的做法是把它们压缩成三张答题卡,每张只写「触发条件 + 三句回答 + 一个代码锚点」。
第一张是形状卡。触发条件是任何涉及矩阵运算的题,三句话是:X 的形状、theta 的形状、中间结果的形状;代码锚点是X.T @ err那一行。第二张是指标卡。触发条件是「效果怎么评估」,三句话是:类别是否均衡、选精确率还是召回率还是 F1、阈值怎么定;代码锚点是扫 epsilon 取最大 F1 的那个循环。第三张是排错卡。触发条件是「模型不收敛或效果差」,三句话是:先看学习率、再看特征量级、最后看偏差方差;代码锚点是数值梯度检验。
| 答题卡 | 触发条件 | 三句回答的关键词 | 代码锚点 |
|---|---|---|---|
| 形状卡 | 涉及矩阵运算 | X 形状、theta 形状、中间结果形状 | X.T @ err |
| 指标卡 | 效果怎么评估 | 类别均衡、P/R/F1、阈值 | 扫 epsilon 取最大 F1 |
| 排错卡 | 不收敛或效果差 | 学习率、特征量级、偏差方差 | 数值梯度检验 |
押题方向上,有五组连环追问最值得准备。第一组从「写一下逻辑回归的代价函数」追到「为什么不用平方误差」,答案是平方误差配合 sigmoid 会得到非凸函数,容易陷入局部最优。第二组从「什么是正则化」追到「lambda 取多大」,答案是用验证集扫,lambda 过大导致欠拟合,表现为训练误差和验证误差同时偏高。第三组从「神经网络为什么需要非线性激活」追到「全用线性会怎样」,答案是多层线性叠加等价于单层线性,深度失去意义。第四组从「SVM 为什么能用核函数」追到「核函数的选择」,答案是核函数把样本映射到高维而不显式计算映射,高斯核适合边界复杂但样本量中等的场景。第五组从「异常检测和 supervised 分类有什么区别」追到「什么时候用哪个」,答案是异常样本极少且形态多变时用异常检测,有充足标注且异常类型固定时用分类。
从那以后我每次准备这类面试,都强制走一遍「先闭卷写代码,再对答案,最后压成卡片」的流程,不允许自己只看不写。看得懂和写得出之间隔着一整个太平洋,而无答案版存在的意义就是让你提前在那片海里呛几口水。希望帮到你。
本文还有配套的精品资源,点击获取