
又到刷题时间。这个系列我自己都想吐槽说好每周更新一次结果硬是拖成了不定期更新。好在前三次的内容都是实打实的第一次把Python工具链和NumPy广播机制过了一遍第二次集中刷了逻辑回归、决策树这些经典算法的推导第三次用PyTorch完整搭了一个手写数字分类网络。如果你是从第一篇跟到现在的基础部分基本稳了如果是中途进来的直接做第四次这套综合练习遇到不懂的再回头翻前面的文章补课效率反而更高。AI入试这个词我按最宽泛的理解来用人工智能方向的入学复试、企业算法岗笔试、以及各类AI能力认证考试都算。这类考核有个共同点就是特别爱考看起来基础、实际上容易翻车的问题而且经常把数学推导、代码实现和概念判断揉在同一道题里。第四次练习我就故意把这种综合题挑出来做成了带详细解析的练习合集适合正在备考、或者想检验自己是否真正掌握AI基础的人。整套题不追求偏难怪而是追求问到你平时忽略的为什么。1. 第四次练习的整体定位与选题思路1.1 前三次练习留下的地基先简单交代一下系列进度。第一次我带着大家把Python的列表推导式、NumPy的广播机制、矩阵乘法练到闭着眼能写第二次重点讲逻辑回归和决策树的公式推导以及它们在真实数据上的表现第三次主要是用PyTorch搭建全连接网络把数据加载、模型定义、训练循环完整走了一遍。三轮下来你会发现一个尴尬的事实单个知识点做题都会一旦混在一起脑子就容易卡壳。于是第四次我换了一种玩法不再按知识点为单位出题而是按题型为单位出题——同一个考点用选择题、推导题、编程题轮番轰炸看看自己是不是真懂了。这也是我备考AI入试最真实的需求考试不会只问什么是过拟合它一定会让你判断这个现象是不是过拟合或者让你想办法减轻过拟合。所以这次练习每一类题我都尽量做成概念推导场景的复合结构而不是孤立的记忆题。做题时你可以先独立完成一遍再看后面的解析这样效果比直接阅读答案好得多。1.2 为什么这轮选题主打综合手推认真研究过几套相关笔试和复试题目之后我发现出题人有一个共同偏好希望筛选出真懂原理而不是背住结论的人。所以概念题后面往往跟着一个为什么计算题又要求你写出中间步骤。给我的启发是平时刷题不能只盯着答案对错而是要练推导速度和表达的严谨性。第四次的四类题型我是这样规划的题型考察能力本次题量建议用时概念辨析题是否真正理解核心术语3道每题3分钟手推计算题能否独立完成公式推导2道每题8分钟公式应用题能否把数学知识落到场景3道每题5分钟编程实现题能否把算法转成代码1道12分钟选择题检验你知不知道简答题检验你能不能讲清楚计算题检验你敢不敢动手算编程题检验能不能把公式变成可执行代码。四类都过一遍才算真正掌握一个考点。这套思路你在准备任何技术考核时都可以复用。2. 机器学习基础概念题与易错点复盘2.1 类别不平衡下指标选择是个送命题先上这道选择题它在我刷过的题目里出现频率极高。题目在一个二分类任务中正样本仅占1%你觉得哪个评估指标最不靠谱A. AccuracyB. F1-ScoreC. AUCD. Recall正确答案是A。原因很简单如果模型把所有样本都预测为负类Accuracy能到99%可这个模型一点用都没有。用生活化的话说就像天气预报天天报不下雨一个月里虽然只错了两三回但我们想要的从来不是这种平均正确率。在正负样本严重失衡的业务场景里准确率会被多数类主导完全掩盖少数类上的表现。F1-Score是精确率和召回率的调和平均在这种场景下能反映模型对少数类是否真的捕捉到了AUC看的是正负样本排序能力受不平衡影响相对较小Recall则直接关心真正的正样本我捞回来多少。所以看到类别不平衡五个字第一反应应该是排除Accuracy优先考虑F1、AUC、PRC。这里特别提醒PRC在正样本极少时比ROC更敏感很多参考答案不提这一点但你答出来会是加分项。再补一道延伸思考如果业务场景是识别交易欺诈正样本就是欺诈交易非常稀少你会更看重Precision还是Recall答案取决于代价。如果一次误判会把正常用户冻住损失很大那就往Precision偏如果要尽可能抓住所有欺诈不管误伤就主攻Recall。所以考试里不要只背指标公式还要学会结合场景说取舍。2.2 偏差-方差分解简答题这样答才能拿全分第二道高频简答题请用偏差-方差分解解释过拟合与欠拟合。我的建议答题框架分四步。第一步直接写公式泛化误差 偏差^2 方差 噪声。第二步说清偏差和高低欠拟合模型太简单对训练数据都拟合不好属于高偏差、低方差过拟合模型把训练数据里的噪声都学进去了属于低偏差、高方差。第三步举一个具体例子佐证比如用线性模型去拟合二次函数偏差很大、方差不大用九次多项式拟合少量点偏差小、方差极大。第四步给对策高偏差时增加模型复杂度、加特征、减少正则化高方差时增加训练数据、降低模型复杂度、加正则化、做交叉验证。四步说完基本就是个小满分答案。我在批改自己练习时发现一个常见错误很多同学把偏差理解成预测值和真实值的差这没错但在机器学习语境下偏差描述的是模型在大量不同训练集上的平均预测与真实值的差异方差描述的是模型在不同训练集上的变动程度。这两个概念一定要从多次采样训练集的角度理解否则一旦被追问为什么增加数据能减小方差就会卡住。事实上数据增多时模型见过的样本分布更接近真实分布它对训练集具体样本的依赖变小方差自然下降。2.3 梯度下降的变体们别只记名字这种题通常以填空或选择形式出现。比如比较批量梯度下降BGD、随机梯度下降SGD和小批量梯度下降Mini-batch GD的优缺点。批量梯度下降每次用全量数据计算梯度方向最准但数据量大时速度慢而且容易停在局部极小随机梯度下降每次用一个样本更新快但震荡剧烈带噪声反而有机会跳出局部极小小批量梯度下降折中每次用一小批兼顾稳定与速度是实际深度学习训练最常用的方式。答题时最好补一句现代框架里的SGD默认指小批量随机梯度下降而不是严格意义上的单样本更新。这种抠定义的小细节很容易让阅卷人觉得你确实动过手。这里再补充一个常被追问的点学习率怎么设。学习率太大损失曲线会震荡甚至发散太小又收敛慢。常见的做法是用余弦退火或warmup加动态衰减初始学习率一般取0.01到0.001之间再根据验证集损失做调整。回答这类问题时只要把控制更新步长这个本质讲明白再给出一个具体量级和调整方向会显得很有实操感。3. 深度学习与神经网络手推反向传播3.1 从零手推一个神经元不再怕链式法则AI入试里手推反向传播基本是必考项。很多同学一看公式就头大其实只用记住一句话梯度是损失对参数的偏导链式法则就是逐层求导再相乘。我们来看经典的最小例子。设输入 x2目标 y0.5初始参数 w1.0b0.5激活函数是Sigmoid损失函数是均方误差MSE。前向传播的计算为z wx b 1.0 × 2 0.5 2.5 a sigmoid(z) 1 / (1 e^(-2.5)) ≈ 0.924 L 0.5 × (a - y)^2 0.5 × (0.924 - 0.5)^2 ≈ 0.0899反向计算 dL/dw 时按照链式法则拆成三段dL/da a - y ≈ 0.424 da/dz a(1 - a) ≈ 0.924 × 0.076 ≈ 0.0702 dz/dw x 2相乘得到 dL/dw ≈ 0.424 × 0.0702 × 2 ≈ 0.0595。偏置的梯度是 dL/db ≈ 0.424 × 0.0702 ≈ 0.0298。如果学习率设为0.1参数更新为 w_new ≈ 1.0 - 0.1 × 0.0595 0.99405b_new ≈ 0.5 - 0.1 × 0.0298 0.49702。手推这种题有几个坑。第一个是搞混损失对输出的导数交叉熵配合Sigmoid时推导会简洁很多但这里用的是MSE必须老老实实算。第二个是参数更新的方向梯度下降是减去梯度方向别反。第三个是Sigmoid在z较大时梯度接近0这就是梯度消失的雏形手推题里如果激活输出接近1或0梯度值会非常小要能意识到并说明。我的习惯是前向把 z 和 a 分别存成中间变量反向直接取用这样既快又少出错。备考时建议把用乘法链写清每一步偏导当成固定书写格式阅卷人看着清晰自己也容易发现错误。3.2 特征图尺寸与感受野别再被padding和stride绕晕这个知识点几乎每次笔试都会出现考法通常是给输入尺寸、卷积核大小、padding和stride让你算输出特征图尺寸或者反过来求某个参数。通用公式是输出尺寸 floor((W 2P - F) / S) 1其中W是输入边长P是padding单边填充数F是卷积核大小S是stride步长。为什么加2P因为padding是在左右两侧都填充。为什么最后加1因为卷积核要覆盖到最后一个可行位置类似从0开始的计数。用floor还是ceil取决于框架PyTorch默认是floor手算结果和机器结果一致。比如输入32x323x3卷积padding1stride2先算32 2×1 - 3 31除以2得到15.5向下取整15再加1得到16输出是16x16。再堆一层同样参数16 2 - 3 15除以2得7.5取整7加1得8输出8x8。很多同学在15.5这里直接四舍五入成16然后忘记再加1得出17这是最常见的错误。我建议用直觉检查stride为2时输出尺寸大致接近输入的一半。32变成16符合直觉如果算出来是17或33大概率是取整和加1的顺序错了。池化层公式通常是 floor((W - F) / S) 1没有padding。比如14x14输入2x2池化stride2输出是7x7因为(14-2)/217。真题里还喜欢让你比较最大池化和平均池化在梯度传播上的差异最大池化梯度只会回传到前向中选中的那个位置平均池化则把梯度均匀分配到各位置。这些小点都答上说明你不是只会算尺寸。3.3 用感受野解释为什么CNN喜欢堆小卷积核再补充一道简答题感受野是什么意思怎么理解为什么很多网络堆好几层3x3卷积而不是直接用一个大卷积核感受野指某层特征图上每个像素对应原图区域的尺寸。两个3x3卷积堆叠特征图上的一个点其实可以看到原图5x5的区域参数量却是2×(3×3×C×C)18C^2而一个5x5卷积的参数是25C^2。所以小卷积核堆叠在相同感受野下更省参数还引入了更多非线性层表达能力更强。计算参数量时注意不要漏掉输入输出通道单个卷积核的参数量是F×F×C_in×C_out有偏置还要加C_out。以上就是这类简答题的完整答法先给定义再给参数对比最后说非线性带来的收益。4. 数学基础与编程实战从推导到实现4.1 特征值特征向量PCA的前置考点矩阵特征值是线性代数部分的重头戏考法很直白给你一个2x2矩阵求特征值和对应的特征向量。例题A [[2,1],[1,2]]。先写特征方程 det(A - λI) 0(2-λ)(2-λ) - 1×1 0 化简得 (2-λ)^2 - 1 0 解得 λ 1 或 λ 3。λ1时代入 A - I [[1,1],[1,1]]解方程 (A-I)v0 得到 x1 x2 0所以取一个特征向量 v [1,-1]单位化就是 [1/√2, -1/√2]。λ3时代入 A - 3I [[-1,1],[1,-1]]解方程得到 x1 - x2 0取 v [1,1]单位化 [1/√2, 1/√2]。这一题在考试里往往只是起点后续会问用特征值大小说明矩阵性质。最大特征值3对应方差最大的方向如果把这个矩阵当成某个数据的协方差矩阵主成分方向就是 [1,1] 方向它解释了总方差的 3/(31)75%。这就是PCA的底层逻辑找到协方差矩阵特征值最大的几个方向实现降维。我备考时总结的答题模板是写特征方程、求λ、逐个代回求特征向量、说明几何含义。千万不要只求λ就完事特征向量才是后续问题的关键。另外注意特征向量可以乘任意非零常数写一个特征向量为...也可乘以任意非零常数既严谨又能避免和标准答案有出入。4.2 信息熵与基尼指数决策树计算题怎么拿分决策树计算题在AI入试中属于送分题前提是公式记熟并能手算。给一个常见考法给定划分前后的纯度指标判断哪个特征更好。假设一个二分类数据集有15个样本其中正例9个、负例6个。某个特征把数据划分为两个子节点第一个子节点包含6个样本正负各3个第二个子节点包含9个样本正例6个、负例3个。请计算基尼指数。先算划分前的基尼指数Gini(D) 1 - (9/15)^2 - (6/15)^2 1 - 0.36 - 0.16 0.48划分后按样本量加权Gini(D1) 1 - (3/6)^2 - (3/6)^2 0.5 Gini(D2) 1 - (6/9)^2 - (3/9)^2 1 - 4/9 - 1/9 ≈ 0.444 Gini_after (6/15)×0.5 (9/15)×0.444 ≈ 0.467基尼系数下降量 0.48 - 0.467 0.013。做特征选择时应该选让基尼系数下降量最大的特征。同样如果题里用信息熵就是用信息增益表示下降量。这两种指标本质都衡量划分前后不确定性减少多少。这类题最容易出错的地方有两个一是忘记按样本数量加权直接把两个子节点的纯度做平均二是把基尼指数最小和基尼指数下降量最大搞混。决策树在CART里建树时是遍历特征和阈值选择下降量最大的切分点所以如果问哪个特征更好比的是下降量不是节点纯度的绝对值。我在实际练习中会把这类题写在错题本上重点标记加权平均四个字。4.3 朴素贝叶斯一个条件概率的应用题朴素贝叶斯高频考点集中在贝叶斯公式和朴素的由来。例题已知 P(A|B)0.8P(B)0.3P(A|非B)0.2求 P(B|A)。根据贝叶斯公式P(B|A) [P(A|B)P(B)] / [P(A|B)P(B) P(A|非B)P(非B)] (0.8×0.3) / (0.8×0.3 0.2×0.7) 0.24 / 0.38 ≈ 0.6316这道题考的不只是公式还考分母是否写全。分母里必须包含互补条件下的全概率项也就是 P(A|非B)P(非B)很多同学会漏掉这一项。另一个常考的点是朴素二字的含义即特征之间条件独立的假设P(x1,x2|y)P(x1|y)P(x2|y)。回答时说明这个假设简化了联合概率计算虽然实际很难完全满足但很多场景下效果依然不错所以被称为朴素。4.4 编程题手写K折交叉验证不调库最后是一道代码题。我选了K折交叉验证因为它在笔试里出现频率高而且手写能检验你对数据切片、随机种子、循环流程是否真正理解。用NumPy手写一个简单的切分函数import numpy as np def kfold_split(n_samples, k, shuffleTrue, seed42): index np.arange(n_samples) if shuffle: rng np.random.default_rng(seed) rng.shuffle(index) # 每折至少 n_samples // k 个样本余数从第一折开始分配 fold_sizes np.full(k, n_samples // k, dtypeint) fold_sizes[: n_samples % k] 1 folds [] current 0 for fold_size in fold_sizes: folds.append(index[current:current fold_size]) current fold_size return folds使用逻辑很简单。n_samples20、k5时每折大小是4n_samples23时前3折大小为5后2折大小为4。训练循环里把验证折以外的所有索引拼成训练集folds kfold_split(23, 5) for i in range(5): val_idx folds[i] train_idx np.concatenate([folds[j] for j in range(5) if j ! i]) # 在这里训练模型用 train_idx 训练用 val_idx 验证注意 np.concatenate 传入的是一个列表列表里每个元素是一个数组不要用列表相加否则会变成嵌套而不是扁平化。实践里最常见的错误是忘记shuffle导致有序数据直接按类别块切分验证集就会全是同一类评估结果虚高或虚低。另一个细节是使用 np.random.default_rng(seed) 而不是 np.random.seed np.random.shuffle这样可以避免污染全局随机状态在多次重复实验时尤其重要。如果笔试要求的是严格的Stratified KFold还需要按类别比例逐层分配样本手写复杂度会高很多先写出基础版并说明若要保证类别比例还需分层抽样已经能拿到大部分分数。5. 易错点与应试策略踩坑记录5.1 AI入试笔试最常见的三个丢分位置根据我自己的练习记录和身边备考者的反馈丢分往往不在难题而在基础题三个位置。第一个是概念混淆Bagging和Boosting搞反、L1和L2正则化说不清、归一化和标准化用错场景。解决方法是画一张对比表把相似概念的区别写清楚考前只看这张表。第二个是计算粗心特征图尺寸公式里漏了padding的2倍、特征值方程展开错符号、基尼指数忘记加权。解决方法是每道计算题都先写公式再带入不要跳步。第三个是代码细节手写交叉验证时忘记shuffle梯度下降里把梯度和参数更新方向搞反。这些坑在平时刷题时发现比考试时丢分更值钱。我建议把错题按概念型/计算型/代码型分类记录考前只看错误原因栏效率极高。5.2 我的答题顺序与时间分配建议AI入试这类综合性笔试时间通常比较紧。我的习惯是先用2分钟扫一遍所有题目标记哪些是需要长时间计算的、哪些是概念题。做题顺序上先做计算题和编程题因为它们需要大脑在高唤醒状态下手算越做到后面越容易疲劳和粗心概念简答题放中间用来调剂节奏最后留10分钟检查计算题的符号和公式。单题时间控制上选择题不超过3分钟简答题5分钟左右计算题可以放到8分钟编程题最多15分钟。如果一道题卡了超过预计时间的一半果断先跳过后面有时间再补。这套节奏在多次模拟练习里让我保持了较高完成度推荐你也试试。你可以根据自己强弱项微调顺序但核心原则是不要在低分值的难题上耗尽脑力影响后面更多基础题的得分。5.3 如何把错题变成真正属于自己的东西我不太建议反复刷同一套题那会产生假性记忆。更有效的做法是把做错的题改造成变体比如把K折交叉验证里n_samples从23改成100要求写出每折样本数把特征图尺寸里的padding改成0重新算一遍。这样比再做一次原题更能检验你是否真的掌握。我也习惯在题干旁边写一句话标记这道题在真实项目中对应什么场景。比如特征图尺寸计算对应改网络结构时确认维度是否匹配反向传播手推对应调参时理解梯度异常来自哪里。备考不是任务而是把知识内化成工具。带着这个心态AI入试的题目会越做越顺而且工作里遇到类似问题你也更容易想到用哪个知识点去解。第四次练习到这里就结束了。说实话每次整理这些题我自己也能复习一遍尤其是手推反向传播和交叉验证哪怕写过很多遍偶尔还是会踩到符号和维度的坑。所以我的个人建议是题不在多把每一道综合题真正手推、手写一遍比泛泛刷十道题更有用。下次第五次我打算加入Transformer的Self-Attention手推和常见激活函数对比如果你已经把这次的内容消化完我们下一步见。