分类模型可以说是深度学习面试的敲门砖。我前前后后帮好几个准备跳槽的同事模拟过面试,又整理了这一两年真实面试里撞到的高频题,发现一个规律:面试官问分类模型,几乎从来不按教科书目录来,而是从“给你一个分类任务,你打算怎么做”这种开放题切入,然后一路往下深挖,挖到你答不上来为止。
这篇文章把这些题整理成一份面经底稿,核心覆盖输出层设计、损失函数选型、评估指标选择、过拟合处理和实战训练技巧。不管你是刚开始准备算法岗面试的应届生,还是想查漏补缺的工程师,照着这条线把每个问题问自己一遍,比刷十道LeetCode有用。这期是“(一)”,先把分类模型的骨架过一遍,下一期再补Transformer分类和多标签方向。
1. 分类模型面试题的整体考察逻辑
1.1 面试官抛出分类题到底想验证什么
几乎所有面试官问分类模型,表面上问的是“你熟不熟悉基础”,实际在考察三件事:第一,你的知识是不是成体系的;第二,你是真调过模型还是只跑过开源代码;第三,遇到边界情况你慌不慌。
比如最常见的“给你一个二分类任务,你怎么设计模型”,这就是个典型的开放题。新手会答“用CNN提取特征,后面接全连接和sigmoid”,听起来没问题,但面试官紧接着会问“为什么用sigmoid不用softmax”“输入图像多大合适”“数据不平衡怎么办”“评价用什么指标”。这一串追问,才是真正打分的地方。前一个回答只能证明你知道有这些东西,后面这些追问才是证明你理解它们之间关系的关键。
所以复习分类模型,不要想着背题。你要把自己带入到一个真实项目里,从数据到模型到评估到调优,每一步都问自己“为什么这么做”,面试的时候才接得住连环问。
1.2 分类任务相关的技术点怎么排优先级
按照面试官追问的习惯,我把分类模型相关的知识点排了一条复习主线,这条线也是本文的展开顺序:
- 输出层设计:sigmoid、softmax、多标签场景怎么选;
- 损失函数:交叉熵为什么是默认选择,MSE为什么不行,focal loss解决什么问题;
- 评估指标:准确率、精确率、召回率、F1、AUC、PR曲线,各自适用的场景和坑;
- 训练优化:过拟合、欠拟合判断,正则化、数据增强、标签平滑的具体用法;
- 工程细节:学习率策略、预训练选择、类别不平衡的实操手段。
这个顺序就是一条“模型怎么完成一次分类”的推理链。你先知道模型输出是什么,才知道用什么损失度量误差,才知道用什么指标评价效果,最后才知道怎么调。面试官问任何一环,你都能往前和往后串联,这正是他们最想看到的“体系感”。
2. 输出层设计:从sigmoid到softmax,再到多标签分类
2.1 二分类用sigmoid、多分类用softmax的底层逻辑
二分类问题,网络最后一层通常只输出一个神经元,经过sigmoid映射到(0,1)区间,表示正类的概率p,负类概率自然就是1-p。单个神经元加sigmoid实际上是二项分布的概率建模。
多分类问题,输出层有K个神经元,经过softmax把K个实数转换成概率分布,并且所有类别的输出加起来等于1。softmax公式长这样:
- softmax(z_i) = exp(z_i) / sum_j exp(z_j)
关键在于,softmax其实可以看作sigmoid在多类情形下的推广。当K=2时,只对其中一个类计算概率,另一个类用1减掉,结果和sigmoid是等价的。面试时把这个关系说清楚,会显得你真的理解两者而不只是记住结论。
我实际项目里还踩过一个小坑:如果多分类的类别数很多(比如上万类的商品分类),标准softmax要遍历所有类别计算归一化项,内存和时间开销都很大,于是就有了sampled softmax或者候选采样这类变体,面试中聊到大规模分类时,这算是加分的扩展点。
2.2 多标签分类能不能用softmax?这个问题常被问懵
面试官经常拿“多标签”来试探你对输出层的理解。多标签分类里一个样本同时属于多个类别,比如一张图片里既有猫又有狗,这时候用softmax就错了,因为softmax强制所有概率加起来等于1,等于逼模型在猫和狗之间二选一。
正确做法是每个类别单独做一个二分类,输出层每个神经元过sigmoid,损失函数用多个二分类交叉熵求和。多个sigmoid之间是完全独立的,所以模型可以同时判定猫和狗。
这里有一个更深入的追问:每个sigmoid是一个二分类器,那和单独训练多个二分类模型有区别吗?区别在于共享的特征提取层。多标签场景通常让所有标签共享底层的特征提取器,只是最后分叉成多个二分类头,这样既省计算量,又能让不同标签互相利用共性特征。你在实际做多标签模型时,可以对比一下“共享底层+多头输出”和“每个标签独立模型”的指标差距,通常前者在数据量不太大的时候更稳。
提示:遇到“多标签任务怎么设计输出层”这种题,先把“softmax是互斥、sigmoid是独立”这个对比讲清楚,再说共享特征和损失函数设计,基本就能稳住。
3. 损失函数选型:交叉熵为什么成为默认答案
3.1 从极大似然的角度理解交叉熵
面试官问损失函数,最常问的是“为什么分类任务默认用交叉熵,而不是回归的MSE”。这个问题看起来基础,很多人的回答却只停留在“大家都这么用”的层面。
要真正答好,先从极大似然的角度看。分类任务的本质是估计条件概率P(y|x),对于二分类,模型输出的是概率p,那么单个样本的极大似然就是要最大化 p^y * (1-p)^(1-y)。对这个似然取负对数,就等于交叉熵损失:
- L = -[y * log(p) + (1-y) * log(1-p)]
你最大化似然,本质上就是在最小化交叉熵。这从概率上说明了为什么交叉熵是配概率输出的天然选择。多分类同理,负对数似然就是对所有类别的one-hot标签和模型概率分布做交叉熵。
交叉熵还有一个信息论上的解释:它是真实分布P和模型预测分布Q之间的KL散度去掉一个常数项,所以最小化交叉熵就等于让模型预测分布尽量靠近真实分布。
3.2 分类问题不用MSE,根源在梯度
面试到这里,通常接着问“那如果我用MSE呢,会发生什么”。答案是还能跑,但收敛很慢,而且容易卡在局部最优。问题出在梯度。
拿二分类的sigmoid输出举例,MSE的梯度里会多乘一项sigmoid的导数σ'(z)。而sigmoid的导数在输入绝对值大时趋近于0,也就是饱和区。一旦模型输出到了饱和区,梯度几乎消失,参数就不再更新了。交叉熵和sigmoid结合之后,梯度化简完是(p - y)的形式,理论上的表达式里没有σ'(z),误差大时梯度也大,训练自然稳定得多。
关于“交叉熵梯度不含sigmoid导数”这个点,我建议你自己动手推一遍,别只看结论。推导过程就是链式法则加softmax的雅可比矩阵,推通了以后再遇到变体问题,比如把softmax换成其他归一化方式、或者改进损失函数,你都能自己判断梯度行为。
3.3 focal loss:当类别极端不平衡时的补丁
样本不平衡是分类面试的钉子户。面试官除了问“你会怎么处理”,还会问“你有没有用过专门设计的损失函数”。focal loss就是标准答案之一:
- FL(p_t) = -alpha_t * (1 - p_t)^gamma * log(p_t)
其中p_t是模型对真实类别的预测概率。这个公式里有两个关键调节项,一个是gamma,一个是alpha。
gamma的作用是调节难易样本的权重。当模型对某个样本已经预测得很准,p_t接近1时,(1-p_t)^gamma趋近于0,这个样本的loss被压得很低;而预测错的难样本p_t小,权重接近1,loss被保留下来。这样一来,模型不再被大量易分类的负样本淹没,而是集中火力学习难分样本。gamma通常设为2。
alpha是类别权重,一般取正样本比例或者用交叉验证调,作用是平衡正负样本的绝对数量差。这两个参数配合使用时,focal loss既能压低易分样本的贡献,又能从数量上补偿少数类。
我在一个长尾分布的图像分类任务里试过标准交叉熵、加权交叉熵和focal loss。加权交叉熵在只有数量不平衡时很管用,但一旦样本内部还有难易差异,加权会让模型对那些“数量多但本来就难分”的样本更加头疼。focal loss在两个维度上都有调节能力,效果更稳。不过它多了一个gamma要调,如果你的训练集本来就很均衡,没必要硬上。
4. 评估指标选择:准确率之外的真实战场
4.1 混淆矩阵、精确率、召回率和F1的关系
分类模型的评估,面试官最喜欢从“你的测试准确率是95%,这能说明模型好吗”这个陷阱题开始。准确率只在类别均衡时才有参考价值。当负样本占99%时,模型全预测负类也能有99%的准确率,可是这个模型一点用都没有。
要完整描述分类效果,必须先列混淆矩阵:真正例TP、假正例FP、假负例FN、真负例TN。基于这四个数,精确率 = TP/(TP+FP),表示预测为正类的样本里到底有多少是真的正类;召回率 = TP/(TP+FN),表示所有真实正类里面模型找回了多少。
精确率和召回率是矛盾的,类似“宁可错杀一千,不可放过一个”和“宁可漏掉一千,也不冤枉一个”之间的对立。F1就是精确率和召回率的调和平均,用来在两者之间找一个平衡点。面试如果深入,还会让你解释为什么F1用调和平均而不是算术平均——因为调和平均更受小值影响,不会让某一项特别高就掩盖另一项的低水平。
实际业务里的取舍比教科书更复杂。拿“垃圾内容识别”举例,精确率高了意味着误伤正常内容少,但会漏掉一部分违规内容;召回率高了则能把违规内容揪得更全,但普通用户被误伤的概率也高了。面试时如果能结合自己项目的场景讲清楚你选了哪个方向、为什么,会非常加分。
4.2 为什么AUC对类别不平衡不敏感
ROC曲线和AUC几乎是必考的进阶指标。ROC曲线的横轴是假正例率FPR = FP/(FP+TN),纵轴是真正例率TPR = TP/(TP+FN)。注意这两个值都是比率,分别在正类和负类内部做了归一化,所以正负样本的整体比例变化,并不会明显改变ROC曲线的形状。这就是AUC对类别不平衡相对不敏感的数学原因。
PR曲线就不一样,它的横轴是召回率,纵轴是精确率,精确率的分母里包含预测为正类的总数,这个数量会随着负样本变多而剧烈变化。所以当正样本极度稀少,或者你更关心“模型找出来的正类有多可靠”时,PR曲线比ROC更敏感、更有区分度。
面试遇到选择题“类别不平衡应该看ROC还是PR”,我建议这么答:如果正负比例为严重倾斜,类别数量差距大,主要看PR曲线;如果只想评估模型的排序能力、不关心具体阈值,或者正负样本采样方式变化比较大,则看AUC。最好再加一句“通常两个都放出来一起看”,显得更老练。
4.3 业务指标和技术指标怎么对齐
还有一个容易被面试官抓住的问题:线上看CTR或者GMV,线下怎么评估模型?本质上是技术指标到业务指标的映射。二分类模型里,模型阈值决定了精确率和召回率之间的取舍。你可以根据业务成本来定阈值:如果误伤一个用户损失很大,阈值调高一点;如果漏掉一个违规内容代价很高,阈值就调低。
我之前的经验是,把测试集按模型预测得分分桶,统计每个桶里的真实正样本占比,就能画出“模型校准曲线”,再结合业务成本公式选择阈值,这种做法比随便用0.5做决策靠谱得多。
5. 训练阶段的高频问题:过拟合、欠拟合与正则化
5.1 一张loss曲线判断当前状态
面试官经常给出一个训练场景,让你当场判断模型是过拟合还是欠拟合。最常见的情况是这样的:训练集loss持续下降,但验证集loss先降后升,这就是标准的过拟合信号。模型把训练集里的噪声都记住了,却没有学到可以泛化的模式。
反过来,如果训练集loss本身就降不下来,验证集loss也跟着居高不下,说明模型容量不够或者优化过程出了问题,这就是欠拟合。有些同学一看到验证集指标差就直接上正则化,结果训练集loss更低、验证集还是一样差,其实这时候该做的恰恰是让模型更“能打”,比如增大网络容量、降低正则强度、补特征,而不是继续压泛化。
训练过程里有个常见的隐性过拟合:验证集参与调参太多次,验证集本身也会被“过拟合”。我现在的做法通常是先划分一个训练集和一个验证集来做常规实验,最后再用一个完全没有参与过任何调参的测试集做一次终极评估,这样才能确定模型是否真的可信。
5.2 L1/L2正则、Dropout和数据增强怎么选
面试问到过拟合解法,一般先问思路,再问具体手段。L2正则化是首选答案,它的本质是在损失函数里加一个权重的平方和惩罚项,优化时会倾向于让权重整体变小。
为什么权重变小能缓解过拟合?因为权重小意味着模型对输入变化的响应更平缓。你可以把模型的决策函数想象成一条曲线,权重越大曲线越曲折,能精确绕过每一个训练样本;权重小了曲线就更平滑,不容易被个别噪声点带偏。这就是“平滑性先验”。
Dropout也是高频考点。它每轮训练随机丢弃一部分神经元,相当于让多个子网络共享参数做集成,测试时再按保留概率缩放权重。它和L2不是互斥的,可以同时用。
实际选哪种,我的经验是:先把数据增强做足,再考虑L2,最后才加Dropout或标签平滑。因为数据增强是从源头增加训练样本的多样性,是最本质的解法。如果一个项目里训练数据只有几千张图,加再多的Dropout也不如做翻转、裁剪、颜色扰动来得实在。顺序反过来容易让模型欠拟合,反而更麻烦。
注意:深度学习平台的L2正则作用点非常关键。有些框架里L2是加在权重上的,有些是加在偏置上的。一般只对权重加正则化,对偏置(bias)加正则化意义不大,实际效果反而可能拖累模型。如果面试官追问实现细节,这个点很能体现工程能力。
5.3 标签平滑:一类容易被忽略的“软”正则
标签平滑(label smoothing)是这两年分类模型训练里被问得越来越多的技巧。它把hard label的one-hot向量,比如[0, 0, 1, 0],变成带一点“模糊”的软标签,比如[0.03, 0.03, 0.88, 0.03]。epsilon一般取0.1左右,就是把概率挪一点给所有错误类别。
为什么要这么做?因为one-hot标签会让模型把真实类别的logit推到无穷大,出现过置信问题。模型分数一旦过于自信,很容易把训练集的噪声也死死记住。标签平滑等于告诉模型“真实类别的概率并不是100%,你对别的类也得保留一点余地”,这样学出来的特征更松散,泛化更好。
我在一个细粒度分类任务里读过一排实验,不加标签平滑时验证准确率会在某个数值附近抖动,加了0.1的标签平滑后,验证集loss明显更平滑,准确率也涨了一个点左右。代价是训练集的准确率略微下降,这是正常的,训练集准确率下降换验证集指标上升,说明没有过拟合。
6. 实操细节:学习率策略、迁移学习与工程落地
6.1 warmup和cosine学习率什么时候用得上
学习率策略是面试里比较“实战向”的题。很多人只会说“学习率不能太大也不能太小”,但具体到分类模型训练,warmup和cosine decay是两个绕不开的策略。
warmup的逻辑是在训练初期让学习率从小变大。比如先用一个很小的学习率跑几个epoch,再线性升到目标值,原因是模型刚初始化时参数还很乱,梯度方向噪声很大,如果直接用大学习率,可能一步就把参数带到沟里。先小步走几步,梯度方向稳定了再提速,后面训练会更稳。
cosine decay则是把学习率在总epoch数内按余弦曲线从峰值降到接近0。它的好处是训练初期下降得慢,中期下降得快,末期又趋于平缓,更符合模型收敛的自然过程。现在很多预训练模型微调任务,尤其是有大批次的训练,往往都会配合warmup加cosine的组合。
我实际用的时候是这么定的:微调预训练模型,总epoch不到30,就只做线性衰减甚至固定学习率都行;如果是从头训练分类模型,或者用大batch训上百个epoch,就上warmup加cosine。面试时能说出这个判断依据,说明你真的调过参。
6.2 分类任务怎么选模型和预训练权重
面试开放题问“给你一个图像分类任务,你怎么做”,模型选型一定是要回答的一环。现在一般不会从零训练,而是选一个预训练模型做迁移学习。选型关键看三点:数据集大小、算力限制、线上延迟要求。
数据量不大(几千到几万张),直接用ImageNet预训练的残差网络,比如ResNet50,或者EfficientNet系列,把最后全连接层换成自己的分类头,用较小的学习率微调。算力和延迟有要求,就上轻量网络如MobileNet系列;如果数据量大、算力充裕,再考虑更大规模或带Transformer结构的模型。注意回答里要主动提到“通过迁移学习加载预训练权重”这个动作,面试官很看重。
小模型难收敛的问题也很常见。我记得有次数据量只有两三千张,微调大模型反而验证集指标不如用轻量级模型,原因就是数据太少,大模型参数多,微调时整体更新容易过拟合。解决方案是只解冻最后几层,或者把其他层直接冻结成特征提取器,这样既能借用预训练特征,又不至于在小数据上跑飞。
6.3 类别不平衡在工程里的综合解法
类别不平衡这个问题,面试官考察的不只是你会不会用focal loss,更看你有没有完整的应对链路。我在多个项目里的处理顺序是这样的:
第一步,先看数据能不能重新采样。正样本少就做数据增强、过采样(对少数类做更强的增强),或者对多数类做欠采样。增强方式不限于简单的翻转旋转,还可以用cutout、mixup这类更现代的方法,在分类任务里能显著提升困难样本的鲁棒性。
第二步,调损失或样本权重。用加权的交叉熵给定少类别更大权重,或者直接用focal loss,具体看问题是单纯数量不平衡还是难易样本同时存在。
第三步,调阈值。模型输出概率分布本身就带有bias,直接用0.5做阈值往往不是最优的。我在二分类里习惯先在验证集上画PR曲线或ROC曲线,再结合业务成本找到最佳阈值。
这三步做完还不行,再考虑合成新的少数类样本或者换更复杂的模型。面试时把这个完整链路讲出来,比只说一个focal loss要强得多。
7. 面经里的答题技巧与个人体会
7.1 答题时先讲结论,再展开细节
面试和写文档不一样,没有时间让你从背景慢慢铺开。被问到分类模型的任何问题,我都建议用“总分总”的结构:先一句话给结论,比如“二分类用sigmoid,多分类用softmax,因为它们分别对应二项分布和类别分布”,然后给出两三点推导或实验依据,最后再补一句适用边界。
这样做的目的有两个。一是面试官能快速判断你的思路在不在点子上,二是即便你展开的部分啰嗦了,面试官也已经get到了核心。我模拟面试的时候遇到过很多同学,问一个细节可以从数据预处理讲到部署,每个环节都沾一点但每个点都不深入,这样反而失分。把广度收一收,把深度拿出来。
7.2 用手里的真实案例应对开放题
几乎每家公司的面试都会有开放题,比如“你之前做过的分类项目里,最大的难点是什么”。很多人习惯把项目讲得很顺利,全程都是“我用了什么方法效果很好”,这反而显得不真实。
更好讲的方式是找一个真实的痛点:比如某次噪声标签很多,模型训练半天验证集指标上不去;后来做了置信学习法筛选错误标注,重新清洗了一部分数据,指标才恢复正常。这种故事听起来可信,而且自然就带出了你对数据质量的重视。
我个人的体会是,面试官最后给你的评价,往往不是看你记住了多少知识点,而是看你遇到一个没见过的场景时,能不能快速理清思路、选择方法、判断风险。分类模型这些基础题,说到底就是用来考察这套思维能力的载体。所以不要只背公式,每学一个方法都问自己“如果我手里有一批数据,这个步骤排在第几位”,知识才真正变成你的判断力。
最后分享一个小习惯:每次面试回来,把没答上来的分类题记到备忘录里,当天晚上就查资料补齐。这个系列里的很多题目,就是这样一点点攒出来的。下一期我准备把多标签分类、小样本分类和Transformer做分类这些衍生方向单独成文,到时候我们接着聊。