
深度学习任务到底分几类这个问题别看简单我面试过不少候选人、也带过不少新人发现大部分人对任务分类的理解都停留在“分类和回归”这两个词上。真到做项目的时候丢过来一个任务连该用哪条技术路线、该定什么损失函数、该拿什么指标去评估都拎不清最后模型是训出来了但业务上根本不适用。这篇系列文章我就是想把深度学习任务这件事拆开了揉碎了讲一遍。第一篇先把大框架搭起来把最主流、最常见的几类任务讲清楚每一类都给到可复现的示例和核心代码保证你读完能直接对应到自己手头的问题上。这个系列适合正在入门深度学习、或者已经跑通了一些基础模型但缺乏全局视角的读者也适合准备面试、需要系统梳理知识体系的同学。我不堆公式不贴大段论文全部以实际工程视角来讲。先说说为什么要把“任务分类”单独拿出来讲。深度学习的本质是“用神经网络去拟合一个从输入到输出的映射”但“映射”这件事有无数种形态。输入可以是一张图、一段文本、一条时序数据、一组结构化特征甚至多个模态的混合输出可以是一个离散的类别标签、一个连续的数值、一个序列、一个概率分布、或者一张生成的图像。不同的输入输出形态直接决定了你用什么网络结构、什么损失函数、什么评价指标。任务分类真正决定的是后面所有技术选型。1. 深度学习任务的总体分类框架所谓的“任务分类”最主要的分水岭在“训练时有没有标签”。有标签的走监督学习路线没标签的走无监督或自监督路线还有夹在中间的弱监督和半监督。在落地场景中绝大多数业务问题都能被归入某个具体的任务类别只是有时候需要把业务问题“翻译”成技术任务。我给一个自己常用的分类框架这个框架在带新人和做技术方案评审时反复用过大类子类输入形态输出形态典型应用监督学习分类图像、文本、特征向量离散类别图像识别、垃圾邮件过滤、医疗诊断监督学习回归图像、文本、特征向量连续数值房价预测、销量预估、年龄估计监督学习序列标注序列数据标签序列命名实体识别、词性标注、语音识别对齐监督学习序列生成序列数据目标序列机器翻译、文本摘要、语音合成无监督学习聚类特征向量簇标签用户分群、异常检测、数据探索无监督学习降维/表征学习高维数据低维向量可视化、特征压缩、预训练无监督学习生成噪声/条件向量新样本AIGC图片生成、数据增强、风格迁移自监督学习对比学习无标签样本表征向量预训练、小样本场景下的特征提取自监督学习掩码重建部分遮蔽样本重建完整样本大模型预训练文本、图像、语音强化学习决策控制状态观测动作输出游戏AI、机器人控制、自动驾驶决策这个表看起来很基础但真到了实际项目里很多人会犯一个低级错误拿分类任务的思路去做回归任务拿生成任务的评估方式去衡量分类模型。之所以出现这种问题是因为对任务本质的理解没到位。举个例子给一组皮肤镜图像判断是良性还是恶性这是个二分类问题但很多人上来就搭一个回归模型去预测“恶性概率数值”然后再拿个阈值去卡。虽然行为上看起来差不多但在损失函数设计和评估指标上完全不同效果往往也会差不少。如果按“技术框架的复杂度”再排一档最核心、应用最广的是监督学习中的分类与回归这是整个深度学习的基石。本文先从这两类讲透再往前沿的序列任务和自监督任务展开。分类和回归拿捏住了后面学任何其他任务都有底气。而且从实际工作来看80%以上的深度学习落地场景最终的输出不是类别就是数值这两类任务理解到位了已经能应付大多数需求。2. 监督学习核心之一分类任务全解析分类任务的目标是给定一个输入样本预测它属于哪个预定义的类别。听起来很简单但里面隐藏了三个关键问题类别之间是否互斥样本是否只有一个标签类别数量是多少这三个问题的答案不同对应的技术方案就不同这一点极其重要。2.1 二分类、多分类、多标签三个容易混淆的方向先看一组我经常拿来给新人区分的例子二分类判断一封邮件是垃圾邮件还是正常邮件。输出只有一个类别且两个类别互斥。输出层只需要一个神经元经过Sigmoid激活输出一个0到1之间的概率值以0.5为分界线。多分类判断一张图片里的物体是猫、狗还是鸟类别数量大于2且一个样本只能属于其中一个类别。输出层使用Softmax激活函数输出一个概率分布所有类别的概率之和为1取最大概率对应的类别作为预测结果。多标签分类判断一张图片里同时包含哪些物体比如一张照片里同时有一只猫和一只狗。对于一个样本多个标签可以同时为1不能用Softmax而是每个输出节点独立使用Sigmoid各自输出0到1之间的概率每个维度独立进行二分类。这里有一个非常经典的技术误区值得单独强调做多标签分类时不要用Softmax。Softmax强制所有类别概率之和为1这等于默认“一个样本只能属于一个类别”在多标签场景下会把低概率的类别强行压下去。我之前遇到过一个人做医学影像的多标签分类三种病变可能同时存在他用了Softmax结果模型只会输出单标签后期发现这个bug排查了很久。换成独立Sigmoid之后效果立刻恢复正常了。2.2 分类任务的损失函数为什么交叉熵是首选分类任务最常用的损失函数是交叉熵Cross Entropy。很多新手会问为什么不用均方误差MSE来做分类这个问题里面藏着对分类本质的理解。我从两个角度来解释这个问题。第一分类任务的期望输出是“类别概率分布”而交叉熵本身就是用来度量两个概率分布之间差异的。用均方误差去度量概率分布之间的差异不符合分布本身的特性。第二从梯度优化的角度来看使用Sigmoid或Softmax激活函数之后如果配合均方误差在输出值接近0或1的饱和区时梯度会极小模型参数几乎得不到有效更新收敛速度会大幅减慢。而交叉熵配合Softmax在预测错误时能够提供足够的梯度信号让模型更快地学习到正确的分类边界。具体在代码层面PyTorch里有一个关键细节nn.CrossEntropyLoss()这个类内部已经包含了Softmax计算所以你在搭建模型时分类层不需要手动加Softmax直接把网络最后一层的原始输出logits传给损失函数即可。但如果是在推理阶段想要输出“每个类别的概率值”就需要单独对logits做一次Softmax。很多新手在这个地方容易搞混导致训练和推理行为不一致。另外如果是多标签分类用nn.BCEWithLogitsLoss()它内部也是把Sigmoid和BCE合并了理由和上面一样数值稳定性更好。2.3 一个完整可复现的图像分类示例PyTorch ResNet我用一个标准的图像分类示例来演示从数据加载到模型训练评估的完整流程。这里用CIFAR-10数据集类别数为10输入图像尺寸为32×32。import torch import torch.nn as nn import torch.optim as optim import torchvision import torchvision.transforms as transforms from torchvision.models import resnet18 device torch.device(cuda if torch.cuda.is_available() else cpu) transform_train transforms.Compose([ transforms.RandomCrop(32, padding4), transforms.RandomHorizontalFlip(), transforms.ToTensor(), transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010)), ]) transform_test transforms.Compose([ transforms.ToTensor(), transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010)), ]) train_set torchvision.datasets.CIFAR10(root./data, trainTrue, downloadTrue, transformtransform_train) test_set torchvision.datasets.CIFAR10(root./data, trainFalse, downloadTrue, transformtransform_test) train_loader torch.utils.data.DataLoader(train_set, batch_size128, shuffleTrue, num_workers4) test_loader torch.utils.data.DataLoader(test_set, batch_size256, shuffleFalse, num_workers4) model resnet18(num_classes10).to(device) criterion nn.CrossEntropyLoss() optimizer optim.SGD(model.parameters(), lr0.1, momentum0.9, weight_decay5e-4) scheduler optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max200) for epoch in range(30): model.train() running_loss 0.0 for inputs, labels in train_loader: inputs, labels inputs.to(device), labels.to(device) optimizer.zero_grad() outputs model(inputs) loss criterion(outputs, labels) loss.backward() optimizer.step() running_loss loss.item() * inputs.size(0) scheduler.step() model.eval() correct 0 total 0 with torch.no_grad(): for inputs, labels in test_loader: inputs, labels inputs.to(device), labels.to(device) outputs model(inputs) _, predicted torch.max(outputs, 1) total labels.size(0) correct (predicted labels).sum().item() epoch_loss running_loss / len(train_set) accuracy 100.0 * correct / total print(fEpoch {epoch1:3d} | Loss: {epoch_loss:.4f} | Acc: {accuracy:.2f}%)这段代码是一个标准的监督分类流程从里面能看到几个关键点。第一使用预训练的ResNet-18并在CIFAR-10上微调因为CIFAR-10的图像分辨率低直接使用预训练权重时需要注意输入尺寸的适配需要把模型的第一层卷积修改一下或者直接从头训练。第二数据增强用了随机裁剪和水平翻转这属于图像分类的基本操作目的是增加数据的多样性提升模型的泛化能力。但要注意增强过度反而会抑制性能我之前试过对CIFAR-10加颜色抖动和旋转结果准确率反而下降了原因是32×32的小图像本身信息量少过强的几何变换会引入无效信息。第三SGD配合动量在CIFAR-10上一直是非常稳的组合余弦退火学习率调度的效果也很稳定较小数据集上我通常优先考虑这个组合而不是直接上Adam。2.4 分类任务的评估指标只看Accuracy是不够的关于分类的评估一个常见的认知坑是只看Accuracy。当类别分布不均衡时Accuracy会骗人。比如一个异常检测场景99%是正常样本1%是异常样本模型全部预测为正常就能拿到99%的准确率但这显然是没有价值的模型。在类别不平衡的场景下我通常组合使用Precision、Recall、F1-Score和AUC-ROC。简单说Precision衡量的是“预测为正的样本中真正为正的比例”Recall衡量的是“真实为正的样本中被正确找出来的比例”F1是两者的调和平均AUC-ROC则反映模型对正负样本排序能力的优劣它不依赖于具体的分类阈值。在医疗诊断之类“漏检代价远高于误报”的场景里应优先提升Recall在垃圾邮件过滤这类“误杀正常邮件代价高”的场景里应优先保证Precision。这个取舍本质上是业务问题而不是技术问题做模型的同学一定要和业务方确认清楚“更怕漏还是更怕错”。另外很多项目里样本不平衡的处理方式也是值得一说的。常用的有效手段有几类第一是重采样对少数类做上采样或对多数类做下采样第二是调整类别权重在损失函数里给少数类更高的权重PyTorch里可以直接给CrossEntropyLoss传入weight参数实现第三是使用Focal Loss这类特殊设计的损失函数它在交叉熵的基础上引入了调制因子让模型把注意力集中在难分类的样本上减少大量易分类负样本对梯度的主导。这个损失在处理极度不平衡的检测任务中非常有用我在真实项目里靠它解决过正负样本比超过1:500的问题。3. 监督学习核心之二回归任务全解析回归任务的目标是给定一个输入样本预测一个连续的数值输出。看起来和分类只差最后一步但模型设计、损失函数、评估方式全都不一样。比如预测房价、预测商品销量、预测用户点击率这些都是回归任务。它们的共同点是输出是一个连续的实数而不是离散的类别。正是因为输出连续所以评估“预测值跟真实值差了多少”成为核心问题。3.1 回归任务的损失函数选型MSE、MAE与Huber回归任务里最常用的三个损失函数是均方误差MSE、平均绝对误差MAE和Huber Loss。我有一个自己的选择逻辑在实际项目里反复验证过分享出来。MSE的表达式是(y - y_pred)^2它的优势在于处处可导梯度在误差较小的时候也比较顺滑数学性质好是回归任务默认的选择。但MSE有一个致命弱点对离群点极度敏感。因为误差被平方了一个离群点带来的损失会以平方级别放大导致模型为了“照顾”这个离群点而对整体产生偏移。MAE的表达式是|y - y_pred|它对离群点的容忍度更高损失随着误差线性增长不会像MSE那样被异常值主导。但MAE在误差接近0的地方不可导导数会跳变靠近最优解时梯度恒定收敛速度相对变慢。Huber Loss是对二者的折中在误差小于某个阈值δ时使用MSE在误差大于δ时退化为MAE。实际效果是模型在训练初期误差较大的阶段使用类似MAE的行为对离群点不敏感随着训练收敛、误差缩小到阈值以内切换为MSE行为保证收敛精度和梯度稳定性。阈值δ通常取1.0也可以根据标签的值域做调整。实际项目里怎么选如果标签数据相对干净、没有明显离群点优先选MSE如果数据里有明显离群点且预测目标对离群点敏感度低选MAE如果你不想费心判断数据质量直接用Huber Loss是相对稳妥的选择。比如做人体年龄估计输入一张人脸图像预测年龄数据集中有一些因为标注误差或特殊外观导致标签明显偏离的样本用MSE训练时这些样本会强烈干扰模型后来换成Huber Loss问题缓解了很多验证集上的MAE直接下降了约8%。这就是活生生的经验。3.2 回归任务的网络结构与输出层设计分类任务的输出层是Softmax或Sigmoid输出是概率值有明确的取值范围。回归任务的输出层通常就是线性层不加任何激活函数输出一个无约束的实数。这个“不加激活函数”的决定经常被新手忽略有人会在输出层加一个ReLU或Sigmoid结果导致输出范围被限制住了完全不符合回归的目标。比如预测房价范围可能从几十万到几千万输出层必须能够输出任意范围内的数值加Sigmoid把输出限制在0到1之间反而成了束缚。如果实际问题确实需要限制输出范围比如预测的销量不能为负数可以在线性输出后再接一个ReLU或Softplus但这些属于针对业务约束的特殊设计不能默认添加。网络结构上回归任务的特征提取器和分类任务可以共用比如都是卷积网络提取图像特征、Transformer提取序列特征。区别在于损失函数和输出层。但当任务是回归时最后一层特征向量的维度选择要更讲究。分类任务最后可能能把特征压缩到类别数个维度回归任务通常需要保留一定信息量再映射到一维。我自己做回归时一般会在最后一层加一个隐藏层比如256维再做线性映射到1维输出这样能提高模型的表达能力。3.3 回归任务评估MAE还是RMSE谁更贴近业务回归模型常用的评估指标有MAE、MSE、RMSE均方根误差和MAPE平均绝对百分比误差。这些指标各有侧重。MAE衡量的是平均绝对误差单位与标签一致直观易懂。RMSE是MSE开平方同样在原始量纲下但因为先平方再开方RMSE会放大离群点的影响所以RMSE永远大于等于MAE。如果RMSE显著大于MAE说明预测中存在一些误差很大的样本也就是离群点不少。MAPE衡量的是相对误差排除了标签尺度的影响适合标签量级差异大的场景比如有些商品销量是几万、有些是几个此时绝对误差无法横向比较。实际项目中我选择评估指标有一个经验标准先看业务方关注什么再选对应的评估指标。业务说“我关心预测值和真实值平均差多少”就用MAE业务说“我担心个别极端样本差太多管控风险”就用RMSE业务说“不同品类销量差异很大想统一看误差占比”就用MAPE。评估指标一定要能翻译成业务语言否则模型做得再漂亮在业务那边也说不过去。另外提一个在回归任务中经常被忽视但影响很大的细节标签分布。当标签分布严重偏向某些区域时比如大部分商品销量集中在低价区少数高价商品销量也大模型会被主导区间的样本带着跑尾部区间的预测效果显著变差。一种有效手段是对标签做对数变换即让模型预测log(y)而不是直接预测y。这能压缩极端值的尺度让模型更容易拟合。预测时对输出做指数变换还原。我在处理销量预测任务时用过这个技巧对高尾部分的预测精度提升非常明显。4. 自监督学习不靠人工标签也能学到好特征前面讲的分类和回归都是典型的有监督学习强依赖人工标注数据。但现实中标注成本极高尤其在一些专业领域需要标注者的专业知识门槛。自监督学习的核心思路是不依赖人工标签而是从数据本身构造监督信号让模型学出好的表征再在下游任务上做微调。这个方向已经成了大模型时代的标配路径也是我认为每个深度学习从业者都必须理解的一类任务。4.1 自监督为什么重要从“给模型喂标签”到“让模型自己出题”传统监督学习是有“标准答案”的模型拿着输入去对答案错了就更新参数。自监督学习没有这个标准答案它自己从数据里构造一个辅助任务pretext task用数据自身的结构当标签。举一个最直观的例子文本模型的预训练输入是一段话把其中一部分单词给挖掉让模型根据上下文预测被挖掉的词是什么。这不需要任何人标注直接把原始文本拿来就能用。模型在完成这个任务的过程中被迫学习词汇的语义、上下文的语法结构最终得到的能力就是对语言本身的理解。图像领域同样如此把一张图切成若干块挖掉其中一块让模型根据周围信息重建这一块的内容模型在做的过程中学到了颜色、纹理、形状、物体边界等丰富的视觉概念。自监督最大的价值在于可以用海量无标注数据训练出一个强大的特征提取器这个特征提取器在下游任务分类、检测、分割等中只需要少量标注数据做微调即可达到不错的性能。尤其在标注成本高的行业这个策略几乎是唯一的可行路线。我参与过一个工业质检项目缺陷样本只有几百张刚开始直接用这些数据训练一个分类模型怎么调准确率都上不去。后来换成先在无标注的产线图像上做自监督预训练再把学到的参数迁移到缺陷分类任务上微调效果直接提升了一大截。这让我彻底改变了对自监督学习的态度它不是什么理论前沿而是实际解决问题的重要工具。4.2 对比学习范式让相似样本靠近、不相似样本远离对比学习是自监督学习中最有代表性的一条路线。它的核心思想很直观同一张图片经过两种不同的数据增强变换比如随机裁剪、色彩抖动、旋转得到的两个版本被视为一对“正样本”它们在特征空间里的表示应该彼此靠近不同图片之间则被视为“负样本”它们的表示应该彼此远离。用一句话概括就是学到一种特征空间让相似的样本在空间里聚集不相似的样本在空间里散开。这里给出一个基于SimCLR思路的简化实现在实际学习中这个框架理解透了再去看各种对比学习变体就会容易很多import torch import torch.nn as nn import torchvision.models as models class SimCLRModel(nn.Module): def __init__(self, feature_dim128): super().__init__() # 使用ResNet-18作为编码器输出原始特征 self.encoder models.resnet18(pretrainedFalse, num_classes512) # 投影头将特征映射到对比学习用的低维空间 self.projection nn.Sequential( nn.Linear(512, 256), nn.ReLU(inplaceTrue), nn.Linear(256, feature_dim) ) def forward(self, x): features self.encoder(x) # L2归一化约束特征在单位球面上 features nn.functional.normalize(features, dim1) project self.projection(features) project nn.functional.normalize(project, dim1) return features, project def contrastive_loss(projected_a, projected_b, temperature0.5): # 将两个分支的特征拼接成同一批次 batch_size projected_a.size(0) # 这里最底层的实现使用NT-Xent损失 logits torch.matmul(projected_a, projected_b.T) / temperature labels torch.arange(batch_size, deviceprojected_a.device) # 对角线位置是正样本对其余为负样本 loss nn.functional.cross_entropy(logits, labels) return loss这里有一个很值得注意的细节温度系数temperature。这个超参数控制着相似度分布的“锐利程度”。温度越低特征分布越尖锐模型对负样本的区分要求越高温度越高分布越平滑对所有样本一视同仁。SimCLR原文和其他对比学习论文普遍发现较低的温度能显著提升效果默认值常取0.5或0.1。我在实际调参过程中也发现这个参数对最终表征质量的影响非常大甚至比模型结构本身还关键。建议重点调这个值而不是一上来就去换大模型。除了温度系数对比学习里还有几个公认的实操要点。一是batch size要足够大因为负样本对来自同一个batch内batch越大负样本越丰富SimCLR原文甚至用了8192的batch size。在资源受限的情况下可以借助梯度累积机制模拟大batch。二是数据增强是效果的关键随机裁剪和色彩抖动是最常用的变换组合增强强度过弱会让正样本对太简单学不到好特征过强会让正样本对难以识别出是同一个物体。三是投影头的设计SimCLR专门实验证明了projection head对效果很重要因为它把编码器得到的特征先映射到一个对比空间进行训练训练完之后再丢弃投影头使用编码器特征做下游任务。4.3 掩码重建范式大模型预训练的路子比起对比学习掩码重建的思路更直给输入一部分已知信息预测被遮住的部分。这个思想在NLP里已经存在了很久BERT的Masked Language Model就是掩码重建的典范。在图像领域MAEMasked Autoencoder把这一思路发扬光大。MAE的做法是先把图像划分成若干Patch随机遮蔽掉大部分Patch比如75%然后将可见的小部分Patch送入编码器解码器负责重建被遮蔽的Patch。关键发现是这种看似“自虐”的做法能逼着模型学到高级的语义特征因为想要从25%的可见信息中重建完整图像模型必须真正理解物体形状、纹理和上下文关系。这里有个反直觉的点遮蔽比例越高学习到的表征反而越好即使重建的视觉质量变差了。原因是高遮蔽比例强迫模型去做真正的语义理解而不能靠邻近像素直接插值填补。掩码重建范式在图像和文本中已经成为大模型预训练的主流几乎所有主流大语言模型和视觉Transformer模型都走这条路。它的优势在于不需要构造正负样本对训练更稳定数据利用率高任何无标注数据都可以直接用学到的是深度语义特征在下游任务上泛化能力强。在工程落地时有一个实用建议如果你的业务是垂直领域比如医学影像、工业缺陷或特定类型的文本强烈建议先用自己的领域数据做自监督预训练或领域继续预训练。通用预训练模型虽然强大但未必熟悉你领域数据的分布特点。我在医学影像任务上做过一次实验拿一批无标注的胸片做MAE预训练再只给几百张有标注的胸片做微调效果比直接使用通用ImageNet预训练模型高出不少。这个结果其实体现了自监督学习最重要的价值让模型从你的数据里先学会“这一行长什么样”再去解决具体问题。5. 序列任务不只是输入不同而是对时序和语义的理解序列数据在现实世界中随处可见文本是一串词构成的序列语音是一串帧构成的序列传感器数据是一串时间点构成的序列。序列任务的特殊之处在于数据点之间存在先后依赖关系模型不能把它们当作独立样本来看待。分类和回归虽然也能处理序列输入但当任务是“基于序列上文预测下文”、“判断序列中每个位置对应的标签”时就进入了序列任务的范畴技术路线也跟着变化。5.1 序列标注任务为每个位置打标签序列标注是NLP和信息抽取里的基础任务。给定一串输入序列模型需要为序列中的每个位置输出一个对应的标签。命名实体识别就是最典型的代表一句话中的每个词需要被标记为人名、地名、组织机构名或无关词。词性标注同样如此每个词要标出它是名词、动词还是形容词。这类任务的标准技术栈已经非常成熟。分词器先把文本切成Token队列模型编码器如BERT、LSTM等提取每个位置的特征最后每个位置接一个全连接层做分类。由于序列中的标签前后有依赖比如“人名”后面很少直接跟“组织机构名”业界普遍会再叠一个CRF层对输出约束做全局优化。CRF的作用是学习标签之间的转移规则保证输出的标签序列整体合理。用BERT做序列标注任务时有一个关键工程细节很容易踩坑标签对齐问题。BERT使用WordPiece分词器一个英文单词可能被切成多个子词subword而标注标签通常是对“原始单词”级别标注的。处理办法是第一个子词的标签保留原始标签其后的子词全部标记为某种占位标签比如“X”或“-1”计算损失时忽略这些占位标签的预测结果。我见过好几个项目因为没处理好对齐模型训练时loss异常震荡、评估效果非常差排查了一圈才发现是标签错位导致的。实体识别任务里有另一个几乎人人都会碰到的问题嵌套实体。比如“北京大学人民医院”中“北京大学”是一个组织机构实体而“人民医院”整体又是另一个组织机构实体但它们的位置是重叠的。常规序列标注只能处理不重叠的扁平实体遇到嵌套实体就有问题。业界目前有几种方案最常用的是“打平”后输出最长实体或者用基于Span的方式预测所有可能的实体片段起点终点类型再配合全局解码。如果业务里嵌套实体比例不小建议一开始就选择Span-based方案而不是硬套序列标注。5.2 序列生成任务从翻译到摘要与序列标注不同序列生成任务的输入和输出都是序列但长度可以不同内容可以同构也可以异构。机器翻译是最典型的例子输入一句中文输出一句英文输入输出是不同语言的同义表达。文本摘要也类似输入一篇长文输出一小段浓缩的要点。当前做序列生成任务的标配方案是Transformer配合“自回归解码”的策略逐词生成输出每次生成一个Token把已生成的Token拼接在输入后面继续生成下一个Token直到生成结束标记。这个看似机械的过程背后是一个核心逻辑生成任务里“上下文依赖”非常强当前生成的词依赖于之前所有已生成的词。这也是为什么自监督预训练先学理解加微调再学生成框架在NLP领域几乎统治了所有任务。序列生成训练阶段最需要注意的问题是“训练与推理不一致”即所谓的Exposure Bias问题。训练时模型每一步看到的是真实历史TokenTeacher Forcing但推理时它看到的是自己之前生成的Token上一步的错误会沿着生成过程累积。为了缓解这个问题业界常用的手段是计划采样就是训练前期多使用真实Token做输入训练后期逐渐增加模型自己生成Token的比例让模型适应自己的错误。听完原理可能觉得很简单但实际训练时这个比例怎么安排很影响效果我试过把采样概率均匀地从1降到0效果不如在训练后段保持一个较小的概率长期存在来得好。另一个在序列生成里极其影响体验的工程问题是重复生成。模型经常会出现“我我我我”、“你好你好你好”这种复读机现象或者整段话绕圈重复。这本质上是因为解码策略选择的贪心解码每次选概率最大的Token容易陷入局部循环或者因为训练表里的目标序列本身多样性不足。业界通用的做法是引入Beam Search束搜索维护多个候选序列全局评分取最优而不是每一步只看当前最优。同时还可以在解码时加入repitition penalty对已经出现过的Token施加惩罚。我在长期做文本生成项目后有个心得90%的重复问题靠调解码参数能解决而不是换模型。5.3 序列任务在非NLP领域的应用以时序预测为例序列任务绝不仅是NLP的专属领域。工业设备传感器的读数随时间变化金融产品的价格走势电商平台的日销量这些都是时间序列数据。基于深度学习的时序建模已成为一个重要方向与NLP有相通之处但也有独特之处。经典的时间序列预测模型有很多从最早的LSTM到后来引入注意力机制的Transformer变体再到专门设计的时序卷积网络。如果数据量不大或序列模式相对规律LSTM其实效果就很不错。如果一个序列包含非常长期且复杂的依赖模式或者你要同时预测多个变量、捕捉多个变量之间的交互关系Transformer结构会更合适。时序预测有个极其关键且容易被新手忽略的步骤归一化。时间序列数据往往包含趋势项和季节性成分不同变量的数值范围可能差异悬殊。如果不做归一化模型训练时大量算力会被大数值变量主导模型学不到小数值变量的规律。在工程实践中我对每个滑动窗口内做标准化是一种常见且有效的处理方式。窗口内的标准化能保留局部相对变化同时消除尺度差异。还有一个细节有些时候需要对差分后的序列建模即预测变化量而不是绝对值这能大幅消除非平稳性让预测准确率明显提升。6. 面对新任务时如何选择方案一个可复用的决策框架到了这一步理论框架和各类任务的实现方式都覆盖到了。现在面临一个更实际的问题拿到一个业务需求怎么判断它是哪类任务怎么选择技术方案我在带团队时总结了一个决策框架用了几轮迭代目前看下来很稳定。第一个问题是输出是什么形态。如果输出是离散的有限类别标签那就是分类问题如果输出是连续数值那就是回归问题如果输出是一个序列就要看输出序列和输入序列等不等长等长且逐位对应是序列标注不等长或内容不逐位对应是序列生成。这个判断基本锁定了任务大类。第二个问题是有没有标注数据。如果完全没有标注分类和回归就做不了此时要么先去采集和标注数据要么走自监督路线先学特征再在极小标注量下微调。如果有一定的标注数据但量不大最有效路径是先做预训练或使用别人预训练好的模型再做迁移学习微调。第三个问题是业务到底关心什么。这一点很多人会忽略。评估标准直接决定了模型优化的方向。之前做推荐相关项目时业务方说“用户点击率要尽可能高”这就是二分类问题但后来发现业务方真正的诉求是“每一条给用户看到的推荐内容都要尽量准确”这句话则变成了对置信度和排序能力的考量。同样的数据诉求不同技术方案完全不同。拿到需求先别急着搭模型先把业务关心的事情翻译成任务类型和评估指标。最后一个问题是资源约束。同一个任务从零训练一个模型和自己标数据成本要准确评估。可现在很多人拿到任务第一反应就是“用大模型”实际上在很多任务中一个训练良好的小模型效果就能胜过通用大模型。自监督预训练加任务微调的策略就是在算力有限情况下兼顾效果和成本的选择。我在多个实际项目里反复确认了一条经验先跑通弱智线简单模型基础特征再上复杂模型一步一步优化往往比一开始就上最强模型更高效。另一种常见情况是面对一个全新的数据集无从下手。我推荐一个“三步走”策略。先用一个小型模型快速跑通流程确认数据能正常加载、Loss能正常下降这一步只求“能动”。然后分析模型输出看错误都集中在哪些样本上定位问题方向是数据问题、标签问题还是模型容量问题。最后再针对性地换模型结构、加数据增强、调损失函数。跳过前三步直接上大模型结果往往是训练半天发现数据有bug浪费大量时间。多任务学习对工程落地也非常有实际意义。很多业务天然就是多输出的比如一个商品推荐系统既要判断用户会不会点击二分类又要预测点击后下单的可能性回归还要预测用户看了之后会不会收藏二分类。与其做三个模型不如共享底层特征、在上层分叉出多个输出头这样能共享表示、减少重复计算。这个思路在工业界应用非常普遍训练时需要注意多个任务的Loss量级需要做平衡否则大Loss的任务会主导梯度。我常用的做法是先给每个任务设置初始权重再根据训练中Loss的量级动态调整权重让多个任务的训练进度尽量同步。7. 写在最后从任务分类到真正的项目实战整个系列的第一篇就在这里收个尾。我把监督学习的两大主力分类和回归讲透了也把当前大模型时代绕不开的自监督学习、以及序列相关的典型任务做了系统梳理。回看整篇内容我想强调一个被无数人忽视的认知任务分类不是学术概念而是工程方法论的起点。你在项目里看到的所有数据处理、模型选择、损失函数设计、评估指标确定都由任务类型决定。选错了任务类型就是在错误的赛道上努力再好的模型和调参都救不回来。在我个人做项目的过程中最深的体会是拿到一个需求先别急着调包跑模型把问题翻译成技术任务把所有技术选项都摆出来想清楚每种选择的代价和收益再决定动手方向。这个习惯帮我避开了大量的无效劳动。深度学习技术的迭代速度很快今天的最优模型结构可能半年后就会被新的替代但任务分类的逻辑框架相对稳定它教你的是“面对一个未知问题时如何找到正确的解决路径”。下一篇我打算接着讲生成任务图像生成、风格迁移、文本生成的核心闭环和评估方法这些都是当前AIGC实战中最常遇到的方向。如果你在阅读过程中有任何困惑或者遇到某个具体任务不知道怎么归类欢迎带着问题来交流。系列文章后面还会继续更新我会保持这种“讲原理更讲实战”的风格尽量让大家读完就能用到自己项目里去。