DeeCamp 2018年人工智能训练营在线笔试第二套B卷——看到这个标题,经历过那个夏天的人应该会心一笑。DeeCamp是创新工场当年最有声量的人工智能人才训练营之一,面向高校学生开放,流程是网申、在线笔试、线下面试、拿到名额后参加为期数周的营地集训。我完整走过一遍这个流程,后来陆陆续续有学弟学妹问我:这套笔试到底考什么?难不难?说实话,单套卷子的原始题目不可能原封不动流出来,但考什么方向、怎么答题能拿分、哪些地方容易翻车,这些都是可以复盘的。这篇我就以第二套B卷为主线,把里面的考点、解法、以及我当时踩过的坑完整拆一遍,希望能给想冲这类AI训练营的人一点实打实的参考。
1. 第二套B卷到底考了什么:试卷结构与答题节奏复盘
1.1 这套卷子为什么值得单独拎出来复盘
标题里最关键的信息是"第二套B卷"。2018年DeeCamp的在线笔试并不是一份卷所有人共用,而是分多套题随机分配,A卷、B卷甚至可能还有别的版本,侧重点会有差异。我印象里B卷的特点是更偏算法推导和产品设计,而不是纯工程题。为什么?这跟训练营的定位有关——它不只是招会写代码的人,更想找"懂AI、能落地、有想法"的年轻人。
很多人备考时到处找题刷,但忽略了每套卷子背后的筛选逻辑。B卷之所以值得单独复盘,是因为它暴露了"会做课后题"和"能推理出答案"之间的区别。比如你背过“ReLU能缓解梯度消失”,但卷子会追问“网络第一层全是负输入时会发生什么”,这种追问恰恰能筛掉只背结论的人。
1.2 试卷结构的大致面貌
我答完之后给自己还原过一个结构表,不是官方口径,纯属个人记忆整理:
| 模块 | 大致题量 | 核心考点 | 建议用时 | | 数学与概率 | 8题左右 | 贝叶斯、期望、高维空间直觉 | 15分钟 | | 机器学习基础 | 10题左右 | 偏差方差、评估指标、集成学习 | 25分钟 | | 深度学习基础 | 6-8题 | 激活函数、BN、CNN参数变化 | 20分钟 | | 编程实现 | 2题 | 手写KNN、两层神经网络反向传播 | 35分钟 | | 开放简答 | 1-2题 | AI方案设计、技术选型和风险分析 | 15分钟 |
整套卷子做得快的同学可能40分钟就交卷了,但要做好并不容易。很多题不是考“记住结论”,而是考“为什么这个结论成立”。比如偏差方差那个章节,如果只记得"增加数据可以降低过拟合",遇到"哪些手段不能降低过拟合"这种题就容易翻车。
1.3 我当时的时间分配策略
先说一个反常识的结论:在线笔试不要按题目顺序做。我拿到卷子先扫了最后两道开放题,确认它们不依赖前面的具体选项,再决定答题顺序。我当时的顺序是:编程题先动脑但不立即写完整代码,开放题先写框架,再回头做选择和填空。
为什么这样安排?因为选择题做多了容易心态急躁,而开放题是最容易拿分的部分——只要框架清晰、逻辑完备,即使没有标准答案也能得分。编程题如果一开始就陷入细节,后面选择填空的时间会非常紧张。这个策略后来我在其他AI在线笔试里也反复用,基本稳。
2. 数学与概率题:看起来送分,实际上全是坑
2.1 贝叶斯:一道几乎所有AI笔试都有的经典题
B卷里有一道几乎是AI笔试"标配"的概率题:某检测算法在真实患病者中能检出99%,在健康人中有1%的概率误报,人群中患病率是1%。问检测报告是阳性的人,实际患病的概率是多少?
很多人一看"准确率99%"就直接填99%,这是最典型的错误。准确率描述的是"检测结果的可信度",但我们要求的是"在已知阳性结果下患病率",这是个后验概率,必须用贝叶斯公式:
P(患病|阳性) = P(阳性|患病) × P(患病) / [P(阳性|患病) × P(患病) + P(阳性|健康) × P(健康)]
代入数值:
= 0.99 × 0.01 / (0.99 × 0.01 + 0.01 × 0.99) = 0.5
也就是说,阳性报告的实际患病概率只有50%,因为健康人群基数太大,1%的误报率会产生大量假阳性。这个题考的不是公式记忆,而是"当你有一个看起来很准的模型时,先验类不平衡如何影响业务决策"——这恰恰是AI落地中最常见的问题,比单纯算一道题价值大得多。
2.2 期望值题:别靠直觉,要严格算
还有一道期望题,大意是:从[0,1]均匀分布中独立取两个数,取较大者的期望是多少。直觉上可能觉得是0.75,因为好像"两个数平均是0.5,取较大应该高一点";但严格算下来不是。
设X和Y独立同分布,Z = max(X,Y),则P(Z ≤ z) = P(X≤z)P(Y≤z) = z²,密度是2z,期望是∫₀¹ z·2z dz = 2/3。
我当年犯过的错误是用蒙特卡洛模拟去验证,但因为随机种子不好,前几轮算出0.67左右,我就开始怀疑自己算错了。后来意识到是样本量不够,模拟1e6次就稳定在0.6667。这个教训是:笔试时相信推导,不要被第一眼直觉带走,也不要被模拟结果带偏。这类题表面考概率,实际考的是你对"随机变量的变换"是不是真的会推。
2.3 高维距离和维度灾难的直觉
B卷有一道关于"高维空间中欧几里得距离意义"的判断题,问当维度升高时,任意两个样本点的距离变化趋势。答案是:在高维下,两两距离趋于集中,距离区分度变差,这就是"维度灾难"的直观体现。
这个知识点直接关联到为什么KNN在高维下性能会下降——最近邻距离和最远邻距离的差距会缩小,"近邻"和"远邻"变得难以区分。也关联到特征选择问题:当特征维度很高时,很多距离类算法都会失效,所以降维、特征筛选才有意义。我当年就是顺着这个思路快速选了答案,省下时间给后面的编程题。如果你能把一个知识点关联到三四个下游场景,笔试时就能形成"条件反射式"的判断。
3. 机器学习基础题:考点是"为什么",不是"是什么"
3.1 偏差方差与过拟合:一道送分却容易被绕晕的题
B卷里有一道很经典的单选题:下列哪项不能有效降低过拟合?
- A. 增加L2正则化
- B. 增加更多的训练数据
- C. 增加模型深度
- D. 引入Dropout
答案是C。很多同学会选B,理由是"训练数据不是越多越好吗?" 其实在真实场景里,数据量增加通常能缓解过拟合,但现实是数据不可能无限增加。增加模型深度则相反,会让假设空间变大,更容易过拟合。这道题如果只背"过拟合解决办法清单"很容易踩坑,因为清单里经常同时出现"增加数据"和"降低模型复杂度",但"增加模型深度"其实是增加复杂度,方向相反。
我想强调一个更容易混淆的点:交叉验证也不是直接降低过拟合的方法。交叉验证的作用是更可靠地估计模型在不同超参数下的泛化能力,然后帮你选到"没那么过拟合"的配置。它本身不会改变模型的复杂度,因此考卷上如果问"减少模型方差的手段",交叉验证不是第一选项。这类题就是典型的"看起来都会,细想才发现概念没扎牢"。
3.2 集成学习:随机森林和GBDT的底层逻辑差异
B卷的机器学习部分里,集成学习几乎稳定占2到3题。我记得有一个多选题问"随机森林中每棵树的多样性来源于哪些因素",正确选项是样本随机采样和特征随机采样。这是随机森林区别于简单Bagging的关键点:特征子采样让每棵树更"五花八门",从而降低树之间的相关性,最终降低整体方差。
而GBDT那一题,核心问的是"GBDT每一步迭代中新树拟合的目标是什么",正确答案是损失函数在当前模型下的负梯度方向,也就是通常说的残差。这里我用一个生活类比帮助记忆:随机森林像多个经验不同的老中医会诊,每个人独立看一遍病人,最后投票;GBDT像慢慢把一个有偏的估计一步步修正,每走一步都朝差最小的方向迈一步。
| 对比维度 | 随机森林 | GBDT |
|---|---|---|
| Bagging/Boosting | Bagging,样本和特征都采样 | Boosting,逐步拟合负梯度 |
| 主要降低 | 方差 | 偏差 |
| 对异常值敏感 | 较不敏感 | 较敏感 |
| 并行性 | 自然并行 | 串行 |
笔试里如果问到两者区别,千万不要只写"RF是Bagging,GBDT是Boosting",要能解释"为什么Bagging能降方差、Boosting能降偏差"。前者通过平均多个独立模型的预测来减少波动;后者通过逐步逼近残差来减少系统性误差。能把这个逻辑讲清楚,选择题和简答题都能拿分。
3.3 评估指标:AUC和PR曲线的调用场景
有一道题问"当正负样本极不平衡时,相比ROC-AUC,为什么PR曲线更适合评估分类器性能?" 这题的考点在于:ROC曲线的横纵坐标分别是FPR和TPR,横轴FPR以负样本数量为分母。负样本很多时,FPR即使小幅度变化也可能因为分母巨大而显得"很好看",导致AUC虚高。PR曲线的召回率是相对于真实正样本的,精确率直接反映预测为正样本的准确性,对类别不平衡更敏感。
顺便说一句,AUC = 0.8的正确解读是"随机抽一个正样本和一个负样本,模型给正样本打分更高的概率是0.8",而不是"模型有80%的准确率"。B卷明确有一道判断题就是这样挖坑的。我当时备考时把AUC的排列概率解释背得很熟,所以一眼就看穿了。这类评估指标题在训练营笔试、大厂算法岗笔试里出现频率极高,建议认真吃透。
4. 深度学习部分:不考背公式,考训练直觉
4.1 梯度消失推导:sigmoid为什么带不动深层网络
B卷深度学习第一题方向大概是:为什么sigmoid激活函数在深层网络中容易导致梯度消失。注意它不是让背结论,而是给了一个具体场景。我当时的推导方式是:sigmoid的导数最大值为 σ(x)(1-σ(x)) = 0.25。设网络层数为L,粗略估计反向传播时梯度会乘以 0.25^L,如果再多层,梯度会指数级缩小,深层网络几乎收不到有效更新信号。
对比ReLU:正区间导数为1,不会额外缩小梯度,但负区间导数为0,容易造成神经元死亡。Leaky ReLU和ELU的改进动机就在这里。笔试时如果能从导数的数值范围出发推导,比单纯背"ReLU比sigmod好"要有说服力得多。我当时用的套路是:先写激活函数导数表达式,再说导数最大值的影响,最后对比不同激活函数的梯度传播特性。这套框架放在任何"为什么模型不收敛"的面试题里也通用。
4.2 Batch Normalization 容易答错的点
Batch Normalization也是B卷常客。考点集中在三个方向:
- 它解决什么问题:减少内部协变量偏移,允许增大学习率,缓解对参数初始化的敏感度。
- 训练和推理有何不同:训练时用每个batch的均值和方差,推理时用全局滑动平均统计量。
- Batch size很小时会导致什么:统计量波动大,BN效果不稳定,甚至比不用BN更差。
这题我当年答得不好,因为我只记得BN是"让每层输入分布稳定",但没答到训练与推理的区别。现在回看,这个细节恰恰是笔试想筛选的:很多框架调用者并不知道训练和推理阶段的行为差异。即便不做框架源码级深挖,至少要知道BN层在训练和推理模式下统计量来源不同。如果你今后自己训练模型,遇到"训练指标正常、测试指标异常"的问题,第一反应就应该是检查训练和推理阶段的预处理一致性。
4.3 卷积输出尺寸计算:一个不能省的计算题
B卷有一道纯计算的送分题:输入是32×32的三通道图像,用5×5卷积、padding=2、stride=1,输出特征图边长是多少。
公式是:out = (in - kernel + 2×padding) / stride + 1 = (32 - 5 + 4) / 1 + 1 = 32。
也就是说padding=2保住了空间尺寸不变。这类题丢分很可惜,因为只要公式熟,10秒出结果。我给读者一个建议:考前把所有常见卷积、池化组合的输出尺寸计算都列成一张表,比如"输入224,7×7卷积stride=2,输出112",熟练了以后全靠肌肉记忆。卷子上不会专门考你"会不会查文档",它考的就是你在紧张状态下能不能稳定地做对基础计算。
4.4 把数据增强理解为一种正则化
还有一道题目是"下列哪些技术可以在训练阶段降低过拟合",其中包括数据增强、Dropout、权重衰减。数据增强本质上是在制造更多样的样本,等价于给模型引入一种平滑性先验。它能提高泛化能力,但它和随机种子不同,不该在测试阶段继续应用。这个理解对于后续项目很有用:很多人做图像分类时测试集没有做归一化或者没关掉增强,导致评估分偏低,就是因为没有把训练和推理的区别吃透。
我在备考时给自己建立了一个等价关系:数据增强≈正则化≈降低有效模型容量。这样在选择题里看到任何一个选项,都能快速和其他选项做类比。这个方法不是万能的,但应对训练营笔试足够了。
5. 编程实现题:手写KNN和两层神经网络反向传播
5.1 手写KNN:别再写三层循环了
B卷的编程题大体会给你一个简化的任务,比如"实现KNN分类器,输入训练集、测试集和k,输出预测标签"。我当时第一版是标准的三重循环,虽然能跑,但明显不是他们想看的。更好的写法是向量化距离计算。
import numpy as np def knn_predict(X_train, y_train, X_test, k=5): # X_train: (N, D), X_test: (M, D) diff = X_test[:, None, :] - X_train[None, :, :] # (M, N, D) dists = np.sqrt((diff ** 2).sum(axis=-1)) # (M, N) topk = np.argsort(dists, axis=1)[:, :k] preds = [] for row in topk: labels, counts = np.unique(y_train[row], return_counts=True) preds.append(labels[np.argmax(counts)]) return np.array(preds)这个版本的核心是numpy广播:X_test[:, None, :]和X_train[None, :, :]让两者自动展开成(M,N,D)的差矩阵。这样数据量大一点也能勉强扛住,三层循环可能直接卡死。
除了性能,KNN还有两个容易丢分的点。第一是k值选奇数,避免平票;第二是特征标准化,如果特征量纲差异大,距离计算会被大数值特征主导。笔试时哪怕题目没要求,也应该在答案里提到标准化步骤,这会让阅卷人觉得你有工程意识。
5.2 两层神经网络反向传播:维度分析是最好的debug手段
另一道编程题更像一个"推导+实现"组合:实现一个两层全连接网络的前向和反向更新,激活函数用sigmoid,损失用交叉熵或MSE。我快速写一个可运行的简化版本:
def sigmoid(x): return 1 / (1 + np.exp(-x)) def two_layer_net(X, y, hidden_dim=8, lr=0.1, epochs=200): np.random.seed(0) n, d = X.shape W1 = np.random.randn(d, hidden_dim) * 0.01 b1 = np.zeros(hidden_dim) W2 = np.random.randn(hidden_dim, 1) * 0.01 b2 = 0.0 for _ in range(epochs): # 前向 z1 = X @ W1 + b1 a1 = sigmoid(z1) z2 = a1 @ W2 + b2 a2 = sigmoid(z2) # 反向 loss_grad = (a2 - y) * a2 * (1 - a2) # 对z2的梯度,这里用MSE简化 # 实际若用交叉熵+sigmoid,z2梯度更简洁:a2 - y grad_W2 = a1.T @ loss_grad grad_b2 = loss_grad.sum() grad_a1 = loss_grad @ W2.T grad_z1 = grad_a1 * a1 * (1 - a1) grad_W1 = X.T @ grad_z1 grad_b1 = grad_z1.sum() # 更新 W1 -= lr * grad_W1 b1 -= lr * grad_b1 W2 -= lr * grad_W2 b2 -= lr * grad_b2 return W1, b1, W2, b2这里最大的坑是维度。反向传播过程中,每一步梯度的shape都必须和对应参数一致。我自己当年就在grad_W2那里翻过车,因为它来自a1.T @ loss_grad,少写一个转置,程序直接报维度错误。实践技巧是:写代码前先在纸上画一遍维度流转,前向是[d]→[hidden]→[1],反向就该倒着来,每层都检查括号。
另外提醒一句,题目如果指定了交叉熵损失,使用sigmoid输出时,对z2的梯度可以直接写a2-y,不需要额外乘sigmoid导数。这是很多推导题考察的"数值稳定性"意识。我上面代码为了减少复杂度用了MSE形式,应对通用推导时要注意题目具体设定。
5.3 在线笔试编程环境的三个细节
在线笔试的编程代码框通常没有本地IDE那么舒服,可能有缩进、自动补全差异。我给你三点实操建议:
第一,优先保证代码语义正确,不要纠结一行式花活。第二,把核心思路写在注释里,即使代码没完全跑通,阅卷人也能看到逻辑。第三,不要忘了处理边缘情况:比如测试集为空、k大于训练集大小、输入维度为0,这些是不会出现在标准测试用例里但能暴露工程素养的点。
我后来参加其他AI笔试时也用这套方法,哪怕代码没全部跑过,只要注释里写清楚思路,得分率明显比闷头只贴代码高。
6. 开放简答题:不堆名词,讲清楚为什么可行
6.1 一个典型的AI方案设计题
B卷最后的开放题基本上会给一个场景,要求设计一套AI解决方案。我印象很深的题目方向是"选一个垂直行业,说明AI如何提升效率,数据从哪里来,模型怎么选,落地有什么风险"。
这种题没有标准答案,但拿分的关键是框架。我当时选的是"建筑工地安全帽佩戴检测",因为它的数据来源清晰(摄像头监控画面)、错误代价不对称(漏检比误检严重)、且落地路径相对明确。
我的回答框架是:
- 问题定义:从监控视频流中实时检测工人是否佩戴安全帽,对未佩戴情况进行告警。
- 技术路线:先用目标检测模型定位画面中的人头区域,再对每个头部分类是否戴帽。
- 数据闭环:初始数据来自现场历史监控,利用已有告警记录做种子样本;通过人工修正增加难例;定期增量训练。
- 评估指标:漏检率、误检率、单帧延迟、是否能处理夜间和光线变化。
- 风险边界:检测到后背或侧面时帽子不可见会怎样?极端视角误判怎么办?模型在不同工地间的泛化能力如何?
我当时没有堆一大堆模型名,而是把边界条件写清楚。阅卷人大概率更看重你能否认识到"技术上可行"和"业务上可用"之间的差距。只用三句话讲模型选型,反而把大量篇幅花在数据、评估、风险上,这是我在其他同学高分答案里学到的套路。
6.2 为什么训练营笔试要考开放题
DeeCamp这类AI训练营的定位是培养"能解决实际问题的人",所以笔试刻意加入了开放题。这提醒我们:备考时不要只刷机器学习公式,还要训练"从业务问题到技术方案"的转化能力。
怎么练?我的方法是:每周挑一个行业场景,比如"某连锁咖啡店想预测单品销量""某物流公司想优化配送路径",然后在纸上写一份一页纸方案,限定时间20分钟。重点不是方案本身多完美,而是能不能稳定地在"问题定义、数据、模型、评估、风险"五个维度上自洽作答。练上一个月,你会发现自己写开放题的速度和条理性都有明显提升。
6.3 回答开放题时最容易犯的三个错
第一,只写模型名称,不写数据来源。没有数据,模型就是空中楼阁。第二,只谈理想情况,不谈失败模式。任何模型都有误报漏报,不谈边界等于默认模型100%准确,这在业务里是致命的。第三,不做成本估算。很多AI项目夭折在标注成本太高,笔试里能主动提"需要多少标注样本、人工复核成本如何",非常加分。
这道题拿分的关键不在于你的方案多"前沿",而在于你是不是一个能落地的人。训练营要的是未来能独立带项目的人,开放题就是提前模拟那个场景。
7. 考后复盘:这套题真正想筛选什么样的人
7.1 从B卷反推训练营的用人标准
整套B卷做下来,我的感受是:它不是在选"背过多少论文的人",而是在选"遇到陌生问题能不能自己拆解并推理的人"。单选题考推导,编程题考工程直觉,开放题考产品思维。三者合一,其实就是AI工程师日常工作的缩影。
所以如果你现在准备类似的AI训练营笔试,我不建议把重心押在刷题库上。更好的策略是:把机器学习、深度学习的核心概念从"背诵"升级为"推导"。偏差方差公式、反向传播维度、BN的统计量差异、AUC的排列概率含义,这些能推出来,选择题基本问题不大。编程题多练手写小网络和经典算法,不要依赖框架自动求导。开放题多练方案写作,逼自己在限定时间内把逻辑说圆。
7.2 一套可以复用的笔试复盘模板
笔试后的复盘比笔试前刷题更重要。我每次考完都会做一个三列表格:题目方向、我当时的答案、正确答案和解析。注意不要只写"做错了",还要写"错误的原因是什么"——是概念不清,是计算失误,还是读题太快?概念不清就翻教材找对应章节;计算失误就专门练计算复杂度控制;读题太快就训练先画关键词。
这套方法不仅适用于AI训练营笔试,也适用于很多技术招聘笔试。它逼着你去识别自己的系统性盲区,而不是零散地补知识点。拿B卷来说,我复盘后发现自己最大的盲区是BN的推理阶段统计量,后来复习时我专门把"训练/推理行为差异"列成一张checklist,再遇到类似题就再也没错过。
7.3 最后分享一点个人体会
老实说,我现在回看2018年这套B卷里的很多题,已经成了行业里的常识:贝叶斯、偏差方差、BN训练推理差异、KNN距离计算。但在当时,它们恰好区分出了"看过"和"真正动手想过"的人。DeeCamp最后给我的收获并不只是那几周集训,而是它从一开始就在用笔试筛选一批愿意把每一个公式落到计算、把每一个模型落到场景的人。这套思路,比任何一份答案都值钱。
如果你也在准备类似的AI训练营,我建议你像拆解这套B卷一样,把目标笔试的每个知识点当作一个"为什么"来准备,而不是一个"是什么"来背诵。这个习惯养成了,笔试和面试都会顺很多。