前段时间帮一个做产线质检的朋友看模型,他手上攒了三万多张产品图,真正人工标过的只有八百多张,剩下的全躺在硬盘里吃灰。他上来就问:我这种情况是不是该上半监督学习?我没接话,反问了三件事——这八百张覆盖了几个缺陷类别、每个类别分到多少张、没标的那批图和标过的图是不是同一批设备同一批光照拍出来的。他一个都答不上来。这个场景我见过太多次了:半监督学习、监督学习、无监督学习三者的选择,被简化成了一个"标签够不够"的算术题,而真正决定成败的那些前提,反而没人去查。这篇就聊透一件事:在什么条件下,半监督学习是那个正确答案,什么条件下它只是个看起来很美、实际会让你倒退回监督学习甚至更差的选项。适合已经跑通过监督学习基线、手里有大量未标注数据、正在纠结要不要换路线的同学,也适合刚接触这块、想建立一套判断直觉的读者。
1. 三种范式的分水岭,其实不是算法而是"标签预算"
1.1 把问题重新表述成"每个标签值多少钱"
教科书上讲三种范式的区别,标准说法是有没有标签:全有是监督,全无是无监督,介于两者之间是半监督。这个定义没错,但在工程上几乎没用,因为它没有告诉你什么时候该选哪个。我更愿意换一个角度:这三种范式对应的是三份不同的预算表,预算表的核心科目不是算力,是标签。
算一笔很实在的账。假设你的标注团队一个工时能处理一百条短文本分类,或者二十张需要精细框选的图像。如果你的业务目标要求十万条训练样本,全标就是五万张图的工作量,按每人每天两百张算,光标注就要两百多个人日。这时候你自然会想:能不能只标五千张,剩下九万五千张让模型自己消化?这个念头一出来,你其实已经在问半监督的问题了。
但这里有个陷阱:标注成本不是线性的。标前一千张,你会很认真地写标注规范、做双人交叉校验;标到第五万张,边际质量一定下降,一致性会掉。也就是说,标注量翻十倍,有效信息量可能只翻了三倍。这个折扣率是很多人算漏的,它恰恰是半监督能吃到的那部分红利来源。
1.2 监督、无监督、半监督回答的其实是三个不同的问题
监督学习回答的是"给定输入,输出是什么",前提是你事先知道答案空间有多大、有哪些类别、边界大概长什么样。它的强项在于目标明确,弱项在于它对你没标到的区域一无所知,模型在训练分布之外的表现完全不可控。
无监督学习回答的是另一个问题:"这批数据自己长什么样"。聚类、降维、密度估计、异常检测都属于这一类,它不关心你心里的类别,只关心数据自身的结构。很多人把无监督当成"没有标签时的退路",其实它更适合的场景是探索和发现——你连有几类都不知道的时候,聚类能给你一个初步答案。
半监督学习回答的是第三个问题,而且这个问题最微妙:"能不能用大量没答案的数据,把少量有答案的数据的价值放大"。注意措辞,不是"替代",是"放大"。它本质上是把一个弱信号(少量标签)和一个强结构信号(大量无标签数据的分布形态)做加权融合。融合得好,收益明显;融合得不好,弱信号被强信号淹没,模型会学成一个伪装成分类器的聚类器。
1.3 一个被大量误判的中间地带
实际操作中最常见的错误,是把一堆本来不属于半监督的问题塞进半监督的筐里。举几个典型的混淆项。
如果你手上那批"标签"是用规则、关键词或者远程知识库自动生成的,噪声很大但覆盖面广,那是弱监督,不是半监督。弱监督的关键工作是去噪和重新加权,而不是去研究一致性正则。如果你有一大堆无标签数据,先拿它做自监督预训练,再用少量标签微调,这套流程在工程上常被口头叫成"半监督",但它的本质是迁移学习,收益主要来自预训练任务和数据规模,跟半监督那套分布假设关系不大。
还有一类是主动学习:不是被动接受现有标注,而是让模型挑出最值得标的样本去问人。它和半监督是天然搭档,但解决的问题方向相反——半监督想着怎么少标,主动学习想着怎么标得更值。把这三者混为一谈,最直接的后果是选错技术路线,闷头调了两个月的一致性损失权重,最后发现瓶颈其实在标注噪声上。
2. 出现这几种信号时,半监督才真正划算
2.1 采集几乎免费、标注极其昂贵,且两者比例悬殊
这是半监督最经典也最可靠的适用条件。判断标准不是"有没有无标签数据",而是无标签数据和有标签数据的比例有多悬殊。我的经验阈值是:标注数据占总数据量的比例低于百分之五,且无标签数据量至少是标注量的二十倍以上,半监督才有明显的收益空间。
为什么要求这么高?因为半监督的增益是渐进的,它的本质是让决策边界在无标签数据密集的区域被"推"到低密度处。无标签数据太少,这个推力就微不足道,你还额外背上了一堆超参,收益抵不过复杂度。如果无标签数据只有标注数据的两三倍,老老实实多标一点,往往比调半监督更划算——标注两千张图的时间,可能比你调两周阈值和增强强度要短。
举个例子。某团队做工业零件表面缺陷分类,人工标一张图平均要二十五分钟(缺陷区域小、需要放大看),但他们每天产线自动采集的图有八千张。这个比例是典型的半监督沃土:采集成本趋近于零,标注成本极高,比例轻松过百倍。反过来的例子是医疗影像,采集本身就要成本、要合规流程,无标签数据的获取也不便宜,那半监督的经济账就没那么好算了。
2.2 数据在特征空间里有清晰的簇结构
半监督最核心的赌注是一句话:相似的样本应该有相似的标签。学术上叫平滑假设和聚类假设。这个赌注成立,半监督就有效;不成立,你喂多少无标签数据都是在给模型灌噪声。
怎么在动手之前就知道这个赌注成不成立?有个很便宜的验证办法:拿你现有的标注集,在特征空间里做一次 k 近邻检索,统计每个样本的最近邻标签和它自己一致的比例,也就是 kNN 一致率。如果各类别平均下来一致率能到百分之九十以上,说明特征空间和标签空间是对齐的,半监督大概率能吃到肉;如果一致率只有百分之六十,说明相似的样本标签本来就五花八门,半监督的核心假设直接破了。
这个检查我强烈建议做成流程里的固定环节,因为它只要十几行代码,却能省掉你几周的无效实验。特征从哪来?用一个在标注集上训好的小模型取倒数第二层输出就行,不需要额外开销。
2.3 未标注数据与标注数据必须同源
这是最容易被忽略、翻车后果最严重的一条。所谓同源,指的是采集设备、采集环境、时间跨度、预处理流程都要一致。现实中最常见的翻车剧本是这样:标注的两千张图是某个批次、某台相机、某种光照条件下拍的,未标注的八万张是全年不同季节、不同车间、不同设备拍的。模型用前者训练、用后者做半监督,学出来的东西会往哪个方向偏,谁也说不清。
动手之前先做一次分布检验。最省事的办法是训一个二分类器去区分"这批是标注数据"还是"这批是无标签数据",看它的 AUC。如果 AUC 明显高于零点五(比如零点七以上),说明两批数据在特征上是可分的,来源不一致,这时候必须先做域对齐或者重新采样,别急着上模型。AUC 在零点五到零点六之间,基本可以认为同源。
注意:这个域分类器的特征最好用通用特征(比如预训练模型的输出),不要用你正在训的任务模型特征。任务模型本身就会把两批数据往不同方向拉,用它做检验会自我印证,测出假阴性。
2.4 冷启动、长尾和漂移场景下的特殊价值
有三类场景,即使比例没那么悬殊,半监督也值得一试。
冷启动:新业务刚上线,历史标注几乎为零,但线上每天源源不断产生无标签数据。这时候半监督的价值不在于榨干现有标注,而在于防止模型只在几百条样本上学到一个过拟合的边界。
长尾分布:头部类别标签充足,尾部类别只有个位数。半监督在尾部类上的理论收益最大——因为尾部类缺的不是特征、是标签,无标签数据里其实躺着大量尾部类样本,只是没人标。但反过来它在这类场景也最容易崩,原因后面细说。
分布漂移:模型上线三个月后效果下滑,因为数据分布变了。这时候重新标一批新数据成本高,用新采集的无标签数据配合少量新标注做半监督自适应,是一种折中方案。这条路线在工程上比推倒重来友好得多,但要盯着漂移速度——如果三个月就漂一次,那套半监督流程本身得足够自动化才跑得动。
3. 分布假设一旦破了,半监督会比监督更差
这是我认为最需要摆到台面上的部分,因为绝大多数介绍半监督的材料都在讲它能带来多少提升,很少讲它什么时候会让你的指标倒挂。我踩过,也见过别人踩过。
3.1 平滑假设失效:邻域内标签本来就不一致
平滑假设说,特征空间里挨得近的样本,标签应该一样。但有一类任务的标签是由局部细节决定的,全局语义再像也没用。情感分类里的转折句式是最典型的例子——"东西是不错,可惜三天就坏了"和"东西一般,但便宜到离谱"这两句在句向量空间里可能挨得非常近,因为前半段都在铺垫,但极性完全相反。
这种数据上做半监督,模型会不断把两类样本往中间拉,最后决策边界被磨平,两类都分不清。更麻烦的是这个失败是静默的:训练损失看起来很漂亮,因为没有标签的样本被强行赋予了一个自洽的伪标签,模型自我感觉良好。
3.2 聚类假设失效:一个簇里混着多个类
聚类假设说,同一簇里的样本属于同一类。这在粗粒度任务上成立得很好,猫和狗在通用视觉特征里分得很开。但细粒度任务就是它的天敌。比如区分两种外观极像的工业零件,或者区分几种只在某个特定部位有差异的产品型号,它们在通用特征空间里挤成一团,聚类算法给出的簇可能横跨好几个真实类别。
这种情况下,半监督会把这些混在一起的样本统一推向同一类,等于人为制造了系统性偏差。判断方法还是那个 kNN 一致率检验,如果一致率在细粒度类别上明显偏低,就说明聚类假设不适用于你的特征空间。
3.3 确认偏差:伪标签怎么把自己越喂越错
具体说说自训练这条路线为什么会自噬。流程是这样的:用有标签数据训一个初始模型,拿它给无标签数据打伪标签,把置信度高的挑出来,混进训练集再训一轮,反复迭代。问题出在"置信度高的"这个筛选条件上。
模型在初始阶段一定会在某些区域判错。这些错误判断里,有一部分置信度很高——神经网络的置信度和正确率从来不是一回事,尤其在没有充分训练的区域。这些高置信度的错误伪标签进入训练集后,模型在下一轮会更加自信地重复这个错误,然后筛出更多同类错误。迭代几轮下来,模型在某个子区域上的偏差被固化,再也纠不回来。
这个过程的可怕之处在于它不会报错。验证集如果来自同一个有偏的分布,指标甚至还会上升。等你上线才发现某些类别整个塌掉了,回头查已经很难定位是哪一轮引入的。
3.4 类别不平衡下伪标签的"多数类吞并"
不平衡数据加半监督,是最容易出事的组合。假设你的数据里百分之九十是正常样本、百分之十是异常样本,模型对正常样本的置信度天然就高,因为训练样本多。伪标签筛选时,百分之九十九选出来的都会是正常样本,异常样本几乎全军覆没。
结果就是训练集进一步向多数类倾斜,模型对少数类的判别能力持续退化。这个正反馈跑起来,几轮之后模型会退化成一个"快速判别正常样本"的单类分类器,指标上看整体准确率还有九十几,但异常召回率可能掉到零点一以下。
对策不是没有:按类别配额挑选伪标签,让每个类别挑固定的数量,即使某个类的平均置信度低也照样挑;或者对每个类的伪标签做置信度分位数截断,只取各类前百分之多少。这些做法都会牺牲一点平均置信度,但能保住类别平衡。我在不平衡场景上试过,配额策略能把少数类的召回率拉回来七八个点,代价是整体准确率掉一两个点,这个交换在绝大多数业务上是划算的。
3.5 隐性成本:调参预算翻倍与结果不可复现
还有个不太被提及、但在真实项目里非常致命的问题:半监督引入的超参数远多于监督学习。伪标签置信度阈值、每类配额、无监督损失的权重、增强强度、教师模型的 EMA 衰减率、预热轮数……每一个都对结果敏感,而且彼此耦合。你调好了阈值,增强强度的最优值就变了。
这意味着你的实验预算至少翻两倍。更要命的是复现性下降——同一套配置在不同随机种子下波动可能有三到五个点,比监督学习的两倍还多。如果你的项目有上线时间压力,这笔隐性成本必须提前算进去。我见过因为反复调不出来而中途放弃半监督、回头老老实实补标注的案例,白烧了六周人力。
4. 落到工程上:一套可执行的决策流程
前面讲了那么多判断标准,怎么把它们组织成一条能跑的流程?我通常按下面这套顺序走,每一步都有明确的"停"或"继续"的判据。
4.1 先把监督基线的学习曲线摸出来
任何时候都别跳过这一步。只用人有标签的数据训一个基线,然后做一次学习曲线实验:分别用百分之十、百分之三十、百分之五十、百分之一百的标注数据各训一次(每次从总量里分层抽样,保证类别比例一致),把指标画成关于标注量的曲线。
这条曲线会告诉你三件关键的事。第一,在百分之百标注量下的指标就是你的监督上限,半监督的目标是逼近甚至超过它。第二,曲线在哪个点开始饱和——如果在百分之五十处就基本走平,说明瓶颈不在标注量,而可能在特征表达、标注质量或者类别本身的可分性,这时候上十倍的半监督也不会有什么起色。第三,曲线的斜率告诉你每增加一个百分点的标注能换来多少指标,这个数值就是半监督需要打败的对手。
4.2 增量式喂入未标注数据的实验协议
确认了曲线没饱和,开始做半监督实验,但一定要做增量对照,别一次全喂进去。我的协议是固定标注集不动,把无标签数据量按 1 倍、5 倍、20 倍、50 倍四档逐步加入,每档跑三次不同随机种子,记录指标均值和方差。
这个设计的目的不是找到最优点,而是观察指标随无标签量的变化趋势。如果趋势单调上升然后趋于平缓,说明假设成立,可以放心加大投入。如果先升后降,说明在某个量级上假设破了——降的那一点就是分布不一致或者确认偏差开始起作用的信号,这时候要么检查数据同源性,要么调严伪标签筛选。如果从头到尾基本平着,那半监督对你的数据不奏效,收手。
4.3 验证集怎么切才不会被污染
这是实验设计里最容易犯的错,很多看起来"半监督提升五个点"的结果,问题都出在这里。
第一条铁律:验证集和测试集必须全部来自人工标注,且绝不能出现在无标签池里。我见过把无标签数据随机切一部分当验证集的做法,这相当于用模型自己产生的伪标签去评估模型自己,指标虚高是必然的。
第二条:验证集要按真实业务分布切,不能只保留头部类别。很多人的标注集本身就偏,全标的是典型样本,验证集跟着也偏,最后模型在尾部类上的灾难完全评估不出来。
第三条:如果做的是时序相关任务,验证集必须按时间切,不能随机打乱。随机切会让同一时期的样本同时出现在训练和验证里,指标虚高。
4.4 五个问题走完,答案基本就出来了
把前面所有判据浓缩成一张表,实际决策时按顺序问下来,基本能在半小时内定方向。
| 顺序 | 要问的问题 | 判据 | 结论 |
|---|---|---|---|
| 1 | 监督学习曲线的瓶颈是标注量吗 | 百分之五十标注即饱和 | 不是,先查特征和标注质量,别上半监督 |
| 2 | 无标签数据量与标注量比例 | 低于 5 倍 | 优先补标注,性价比更高 |
| 3 | kNN 标签一致率 | 低于 0.85 | 平滑假设不成立,半监督风险极高 |
| 4 | 域分类器 AUC(标注 vs 未标注) | 高于 0.65 | 分布不同源,先做对齐或重采样 |
| 5 | 类别是否严重不平衡 | 头部类占比超过 85% | 可以上,但必须配类别配额策略 |
五个问题里如果有三个以上落在"危险区",我的建议是回到监督学习,用主动学习的方式挑样本补标注,这条路慢但确定性高。只有前两个问题明确合格、后三个问题至多一个落在危险区,才值得投入半监督。
5. 方法选型:不同数据形态配不同的半监督
确定要上半监督之后,下一个岔路口是选哪一类方法。这里没有万能解,选错了方法比不选还糟。
5.1 自训练与伪标签:门槛最低,翻车率最高
这是最容易实现的一类,几十行代码就能跑起来,适合做第一轮可行性验证。核心循环大概是这个形状:
for epoch in range(num_rounds): pseudo = [] for batch in unlabeled_loader: logits = teacher(batch) probs = softmax(logits, dim=-1) conf, pred = probs.max(dim=-1) # 置信度阈值 + 每类配额双重筛选 mask = conf > threshold pseudo.append((batch[mask], pred[mask])) # 混入有标签数据一起训练学生模型 train_one_epoch(student, labeled_loader, pseudo) # EMA 更新教师模型 update_ema(teacher, student, alpha=0.999)关键在于筛选策略,前面讲过的两个坑都出在这里。单纯用置信度阈值,在不平衡数据上必然崩;加上每类配额能救回来,但配额本身也需要按类别分布设定,不能一刀切。
我的建议是自训练只用来做可行性验证,确认这条路上有收益之后,再换更稳的方法。原因很简单:自训练的稳定性高度依赖初始模型质量,初始模型在哪些区域判错,后面就一路错下去。
5.2 一致性正则:图像类任务的主力
一致性正则的思路完全不同,它不直接信任伪标签,而是要求模型对同一张图的不同扰动版本给出一致的预测。这个约束比伪标签温和得多,因为它不指定答案是什么,只要求答案稳定。
这一类里比较有代表性的做法是给输入加强扰动、给模型参数加噪声、给中间特征加对抗扰动,几种思路可以叠加。实际用下来,图像任务上这类方法的性价比最高,尤其是在标注量极少(每类只有几十张)的时候,比纯自训练稳定得多。
但这类方法对增强策略极其敏感。增强太弱,模型学不到不变性;增强太强,把语义破坏了,模型被迫学一些无意义的对应关系。有一个实用的经验:增强之后人眼还能认出类别的,才算合格的增强。如果连你自己都看不出这是猫还是狗了,那这个强度就过头了。
5.3 图方法与标签传播:关系型数据的天然选择
如果你的数据天然带图结构——用户之间的社交关系、商品之间的共现关系、文档之间的引用关系——那标签传播这类方法是首选。它的逻辑很朴素:标签会沿着图的边扩散,连接紧密的节点应该共享标签。
这类方法在数据量不大时表现很好,因为不需要训练神经网络,纯靠图上的迭代计算就能出结果,可解释性也强。数据规模一上来就撑不住,几十万节点还行,上百万就得考虑采样或者换其他方案。
用这类方法要特别注意图的质量。边建得不对(比如把弱关系当强关系),标签会沿着错误的边扩散,污染范围比伪标签还大。建图时的相似度阈值、邻居数量这些参数,值得单独花时间调。
5.4 传统半监督 SVM 和生成式方法还值得看吗
半监督 SVM 这类方法现在用得少了,但在数据量很小的场景(几百到几千条)下仍有参考价值,主要是它的理论边界清楚,能给你一个"在这个假设下最优解长什么样"的参照。生成式方法(比如用生成模型补样本、或者用对抗框架做半监督)在图像上还能见到,但训练不稳定是个老大难,除非你有明确的理由,否则不建议作为首选。
5.5 预训练时代,半监督的边界正在被重画
这是近两年最值得注意的变化。当你有条件用一个在大规模无标签数据上预训练好的模型作为起点时,很多原本需要半监督来解决的问题,直接用"预训练加少量微调"就解决了,而且过程稳定得多。
这不代表半监督没价值了,而是它的定位变了:从"标注不够时的救命稻草",变成"在预训练基础上进一步压榨剩余无标签数据的增量手段"。判断标准也要跟着调整——如果预训练模型直接在少量标注上微调就能达到业务要求,那就没必要再上半监督,多出来的复杂度换不来对应的收益。只有当微调之后仍然离目标有差距,且这个差距确实来自标注量不足时,半监督才是下一步该考虑的事。
6. 几个场景的推演与反例
理论讲完,落到具体场景上会更有感觉。下面几个都是我在实际项目里遇到过的类型,人物和背景做了处理。
6.1 缺陷检测:一张图要标半小时的那种
这是半监督最舒服的场景,也是最容易做出效果的。特点是标注成本极高(缺陷区域小,要放大、要对照工艺文档、要有经验的老师傅确认),采集成本极低(产线相机全自动),比例轻松过百倍。同时缺陷类型是有限枚举的,类别边界清楚,平滑假设成立。
这类场景我通常先做两件事:一是用正常样本(无缺陷的,数量巨大)做一次自监督预训练,得到一个对正常形态敏感的编码器;二是把标注的缺陷图做 kNN 一致率检验,确认同类缺陷在特征空间里确实聚在一起。两件事都通过,再上半监督,收益通常比较稳。
真正要小心的是缺陷的"新型号"——产线换了模具之后,缺陷形态可能完全不同,而这时候你手里只有旧型号的标注。这时候半监督会把新型号缺陷强行归到旧类别里,比不用还糟。
6.2 文本审核冷启动:先有鸡还是先有蛋
新业务上线,违规样本几乎为零,正常样本一大堆。这时候如果不做任何处理直接训,模型会把所有样本判成正常。上无监督做异常检测是个选项,但异常检测的误报率通常高得业务方接受不了。
比较务实的路线是把三者叠起来用:先用无监督方法(比如密度估计或者重构误差)从海量无标签数据里筛出一批疑似违规的样本,人工确认其中一小部分作为初始标注;然后用这批标注加大量无标签数据做半监督;上线之后用主动学习持续挑边界样本请人标。这套组合拳的落地成本比死磕单一方法低得多。
6.3 序列标注:半监督最难啃的骨头
命名实体识别、词性标注这类任务的半监督难度明显高于分类任务,原因是伪标签的粒度问题。分类任务里一张图一个标签,错了就是错一个;序列标注里一句话有几十个标签,其中错一个就影响整句的损失计算,而且错误位置往往集中在边界上——模型对实体的起始和结束位置判断最不确定。
我在这类任务上的经验是:不要对整个序列做伪标签,而是只对模型高度确信的片段做局部伪标签,其余位置用掩码屏蔽掉损失。这个改动看起来小,实际效果差别很大,因为它避免了边界位置的错误在整个序列上传播。
6.4 什么时候该干脆放弃半监督
说了这么多,最后必须给一个反向的结论,这也是我这些年最想强调的一点:半监督不是技术能力的证明,它只是一个工具,而且是个对前提条件很挑剔的工具。
如果出现下面这些情况,我的建议是果断放弃:一是 kNN 一致率检验过不了,说明特征空间本身就没把类别分开,这时候该做的是换特征、换预训练模型,而不是在半监督上想办法;二是监督学习曲线在百分之三十标注量处就饱和了,说明瓶颈根本不在标签量;三是业务对结果稳定性要求极高、容不得随机种子级别的波动;四是标注成本其实没那么高——真的,有些团队只是懒得标,这种情况下多雇两个人比调三个月模型划算得多。
我在实际项目里的体会是,半监督真正能带来明显收益的场景,大约只占所有"标注不够"场景的三分之一。剩下的三分之二里,一半是特征和标注质量的问题,另一半是任务本身就不适合。所以每次有人问我"要不要上半监督",我的第一反应永远是:先把监督基线的学习曲线画出来,把 kNN 一致率算出来,把域分类器的 AUC 测出来。这三个数字拿到手,答案往往自己就浮出来了,根本不需要纠结。