图像语义分割,说白了就是把图像里的每个像素都标上类别。和物体检测只画框不同,分割要的是像素级的“地图”。这几年卷积神经网络几乎把这个任务的精度上限拉高了一个量级,从最初的全卷积网络到后来的 U-Net、DeepLab,每个阶段都在解决前人留下的具体痛点。这篇内容适合正在做相关毕设、课题,或者想把分割模型真正用起来的同学,我会从原理讲到实操,顺带把踩过的坑都摊开说。
你如果刚开始接触这个概念,可以先记一个最直观的区别:检测输出的是“框 + 类别”,而语义分割输出的是和原图一样大的掩膜,每个像素点都有自己的预测标签。它不区分同一类别的不同个体,比如画面里有三辆车,语义分割把所有车都标成一类;如果你想区分车1、车2、车3,那是实例分割的范畴。理解这个边界之后,再去看网络结构、损失函数和评测指标,会顺畅很多。
1. 语义分割到底在解决什么问题
1.1 像素级分类与任务定义
语义分割在视觉任务里属于“稠密预测”这一档。图像分类只给整张图一个标签,检测定位出几个矩形框,而分割要对每一个像素做分类。一个 (H \times W) 的图像输入进来,模型的输出也是空间尺寸约等于 (H \times W) 的类别图,第 (i) 个像素的预测值表示它属于哪个语义类别。
这种任务对模型的要求有两个维度:一是要有足够的“感受野”,看到足够的上下文才能判断一块像素是“道路”还是“人行道”,因为单独看局部纹理可能完全一样;二是要保留足够的空间细节,不然物体边界会被糊掉。这两个要求天然存在张力——看全局往往靠下采样,而细节又依赖高分辨率特征。
很多时候我会把这个过程类比成给地图填色。检测是在地图上画几个包围圈,分割却是要把每块区域按土地用途涂满颜色。涂色这个过程容不得模糊地带,所以模型的输出必须经过上采样恢复到原始分辨率,并且每个像素的类别概率要准确。
举个例子:一张街景照片里,一块灰色的区域看起来既像人行道也像路面,你需要看周围是否有马路牙子、是否有车辆行驶,才能判断它的类别。这就是上下文信息的作用。卷积神经网络通过不断堆叠卷积层,把局部边缘组合成部件语义,再由部件组合成物体语义,本质上就是从“看颜色”进化到“看物体”。
1.2 为什么传统方法解决不了,必须靠卷积神经网络
在卷积神经网络普及之前,图像分割基本靠手工特征。阈值分割按灰度区间切,边缘检测找梯度突变点,区域生长靠种子点邻域相似性扩散,聚类方法按颜色、亮度聚类。这套思路只能处理“像素特征差异大”的场景,一旦两个区域颜色纹理相似但语义不同,比如蓝天和蓝衣服,或者路灯和树后的边缘,手工特征直接就崩了。
卷积神经网络改变的是特征提取方式。卷积层用局部感受野扫描图像,底层能提取边缘、角点,高层逐渐组合出“车灯”“车轮”这类语义部件。权值共享让网络参数量大幅降低,同时因为图像本身有平移不变性,滑动卷积的归纳偏置非常契合。更关键的是,层次化特征天然适配“既要语义又要细节”的分割需求。
从网络设计角度看,分割模型就是在平衡两件事:编码器把分辨率降下来,换取更大的感受野和更抽象的语义;解码器再把分辨率升回去,恢复出像素级预测。上采样过程如果只靠简单双线性插值,边界就会模糊;所以后来研究者们想出了各种机制,让模型在上采样时重新利用编码器中的高分辨率特征,这就是后面要讲的跳跃连接和空洞卷积等思路。
这里面还有一个常被忽略的细节:卷积操作本身不会把二维结构拍扁,它只是在空间平面上滑动窗口,因此每个输出位置都能拿到对应的局部感受野。分类网络末尾会用全局池化或全连接层把空间信息压缩成类别概率,而分割网络要把这种空间结构保留到最后一层,这就是全卷积架构出现的真正动机。
2. 语义分割的核心模型演进:从FCN到U-Net和DeepLab
2.1 全卷积网络的历史性突破
第一个真正端到端的深度语义分割模型就是全卷积网络,核心改动很简单:把分类网络最后的全连接层全部替换成卷积层。这样网络不再输出一个固定长度的类别向量,而是输出一个带空间维度的特征图,再通过转置卷积或者其他上采样方式恢复到原图尺寸。
这个改动的重要性不在于结构复杂,而在于它打破了分类网络对“固定输入尺寸”的限制,并且保留了二维空间结构。以前我们提取特征之后把特征拉平做分类,位置信息全丢了;全卷积网络让每个位置的特征还能对应到原图坐标。FCN 里还有一个跳级结构,把不同层级的特征图融合起来后再上采样,后来几乎所有分割模型都吸收了这种跨层融合思想。
FCN 的缺点也很明显:上采样过程比较粗暴,转置卷积很难把丢失的细节恢复回来,所以预测出来的边界往往又粗又模糊。当年它在公开数据集上的 mIoU 只能做到及格水平,和今天动辄0.8以上的结果相差很大,但这扇门一旦打开,后面模型的迭代速度就快了起来。
2.2 U-Net的编码-解码结构为什么有效
U-Net 是我个人最推荐初学者入手看的模型,原因就是它的结构特别直白:左边编码器一层层下采样,右边解码器一层层上采样,中间用跳跃连接把同分辨率级别的编码器特征拼到解码器特征上。名字叫 U-Net,结构长得就像字母U。
跳跃连接解决的是上采样过程中细节丢失的问题。下采样时特征图变小但感受野变大,语义信息越来越强;可是边界细节恰恰在浅层特征里最丰富。解码器上采样时如果只凭高层语义,很难还原出锐利边界。U-Net 的做法相当于在上采样阶段不断把浅层的“高清但语义弱”的特征补充进来,让模型在算每个像素类别时既能看懂大局,又能看清边缘。
在实际使用中,U-Net 对训练数据的数量要求比较友好。我在一个规模很小的医学图像练手项目里,数据量只有一百多张,靠平移翻转和弹性形变增强,U-Net 仍然能训出可用的分割结果。原因就在于编码器较小、参数不多,而且跳跃连接让梯度传播更顺畅,网络不容易过拟合到噪声上。不过要注意,U-Net 的显存消耗会明显高于同深度的纯卷积网络,因为跳跃连接要保存大量中间特征图,训大图时记得把 crop 或者 batch size 降一降。
2.3 DeepLab系列:空洞卷积和多尺度感受野
如果 U-Net 是“连接细节”的典型代表,DeepLab 系列则是“扩大视野”的典型代表。DeepLab 的核心武器是空洞卷积,做法是在卷积核的元素之间插入间隔,比如一个 3×3 的空洞卷积,膨胀率是2,实际覆盖范围相当于7×7,但参与计算的参数仍然只有9个。这样做的好处是不需要额外下采样就能扩大感受野,也就不用反复让分辨率缩水。
光有空洞卷积还不够,因为不同物体的尺寸差异很大。DeepLab 的提出者设计了 ASPP 模块,把不同膨胀率的空洞卷积并行堆在一起,分别提取不同尺度上下文,再拼在一起。这就像是让模型同时用几副不同倍率的望远镜去观察同一个区域,小目标看到的是近处细节,大目标看到的是整体结构,最后融合起来。
后来的迭代版本又加入了编码-解码结构、可变形卷积等设计,一步步把复杂场景分割精度推到新高度。选型时,DeepLab 系特别适合图像分辨率高、尺度变化大的任务,比如遥感图像或者自动驾驶的多类别分割。它的一个实际短板是算子相对复杂,在低算力嵌入式设备上实时性不好,后面会再展开。
2.4 注意力机制与Transformer对分割的影响
到了2020年前后,纯卷积的改进空间变小,大家开始把注意力机制搬进分割模型。注意力机制的本质是让特征图上每个位置按照相关性去加权聚合其他位置的信息,SENet 这类模块先在通道维度做注意力,而自注意力则直接把所有位置两两建立关联。这个能力对分割帮助很大,因为很多语义判断依赖长距离上下文,比如远处的一辆小车被树挡了一半,单看局部的卷积核不容易看出它是什么。
Transformer 结构的视觉骨干网络出来后,也衍生出了不少分割方案。它们的好处是全局建模能力更强,大场景里的干扰纹理更少;坏处是计算量和显存消耗普遍高于CNN。我在实际项目里只用过轻量化 Transformer 和简单解码器做对比,发现标注充足的大数据集上精度确实能涨,但小数据集、高实时性场景下往往不如调优好的 U-Net 或者 DeepLab。这个选择背后还是那句老话:没有免费午餐,模型越复杂,需要的资源就越多。
2.5 预训练与迁移学习的关键细节
做分割实验,基本上都会用到在分类任务上预训练过的骨干网络。预训练权重相当于让模型提前掌握“边缘、颜色块、纹理”这些通用视觉概念,再针对分割任务去微调。这样收敛速度快很多,尤其在数据量不大时效果更明显。但预训练并不是万能药,如果你的图像域和预训练数据差异很大,比如医学影像、红外图像、超声图像,预训练权重带来的增益会变小,某些情况下甚至会拖慢收敛,因为底层特征分布完全对不上。
我在做迁移学习时一般分两部分处理:编码器加载预训练权重,解码器随机初始化。训练时给编码器设一个较小的学习率,比如解码器的十分之一,防止分类任务学到的特征被分割任务一开始就打乱。冻结层数不建议冻结太多,分割要求的特征比分类更精细,冻结太多会让网络学不到领域特有问题。还有一个容易踩的坑是预训练模型对输入尺寸有预设,比如有的骨干要求输入能被32整除,如果你直接缩放数据集忘记了 padding,训练过程不会报错,但预测时边缘会莫名其妙多一圈噪声。
3. 从零训练一个语义分割模型的完整实操
3.1 数据集与预处理:标注格式和增强策略
训练语义分割模型第一步是准备标注数据。最常见的标注格式是单通道索引图,每个像素值直接对应类别 ID,比如0表示背景、1表示人、2表示车,最后再留一个255作为忽略区域。训练时读取原图和标签图,把它们缩放成模型可接受的尺寸,再做归一化:图像减均值除方差,标签不要做这种数值变换。
数据增强是分割训练里特别值得花心思的一环。几何增强(随机翻转、旋转、缩放、裁剪)一定要对图像和标签使用同一套变换矩阵,否则标签错位会直接毒害模型。我在代码里一般用随机数种子绑定两个张量的变换:翻转前生成一个随机标志,图像和标签用同一个标志翻转。色彩增强(亮度、饱和度、对比度扰动)只作用在图像上,因为标签是类别信息,不受光照影响。
还有一个很容易被忽略的细节是 padding。当输入尺寸不能被缩放因子整除时,需要把图像和标签都 pad 到合适的尺寸,pad 区域的标签不参与 loss,通常把它置为 ignore_index。我见过不少次新手直接对标签做插值缩放,导致边界类别被打乱,这种情况训练不会崩,但评估指标永远上不去。
3.2 模型搭建与Loss选择
模型部分我不打算贴完整的大段代码,给一个最核心的训练循环就够。假设你已经定义好一个模型类 model,输入是 (B,3,H,W),输出是 (B,C,H,W) 的 logits,C 是类别数。损失函数我优先用交叉熵,这是很多分类问题的默认起点,对分割也有效。
import torch criterion = torch.nn.CrossEntropyLoss(ignore_index=255) optimizer = torch.optim.AdamW(model.parameters(), lr=1e-4, weight_decay=1e-4) for images, labels in train_loader: images = images.to(device) labels = labels.to(device) logits = model(images) # (B, C, H, W) loss = criterion(logits, labels) # 标签为 (B, H, W) 长整型 optimizer.zero_grad() loss.backward() optimizer.step()交叉熵对每个像素独立计算,逻辑上很直接。但如果类别分布严重不均衡,比如道路占了大半个画面,行人只占几十个像素,交叉熵会让模型把精力全放在道路类别上。这时就要换思路,常见方案有三类:一是给每个类别一个权重,把小众类别的 loss 放大;二是改用 Dice Loss 或 Focal Loss,让模型更关注难分样本;三是重采样训练数据,让每个批次里不同类别的比例尽量均衡。我看很多项目最后用的是“交叉熵 + Dice”的组合,既保留像素级监督,又用 Dice 弥补对小目标的敏感度。
举个直观的例子:一个图像里有 95% 背景,5% 目标。你把所有像素预测成背景,准确率已经 95%,但目标一点没框出来。交叉熵的梯度被背景淹没,权重更新方向几乎不考虑目标。加权交叉熵的做法是给目标类一个比较大的权重,比如 20,让目标类贡献的损失在总量里占可观比例。Focal Loss 更细一点,它会在训练过程中动态降低已预测正确的像素的权重,让模型逐渐把注意力集中到那些“很难搞”的边界和目标上。
3.3 训练配置与评估指标
训练配置上,优化器现在用得最多的是 AdamW,初始学习率 1e-4 左右,配合 warmup 和余弦退火。分割模型的收敛速度比分类慢很多,我建议第一个模型先用小迭代数跑通流程,再加大训练周期。batch size 受显卡显存限制,一般 2 到 16 不等;显存不够时可以减小裁剪尺寸,而不是硬调 batch。
评估阶段不能只看 loss,要看 mIoU(平均交并比)。对每个类别计算“预测区域和真实区域的交集 / 并集”,然后对所有类别取平均。mIoU 的取值范围是0到1,越接近1越好。给你一段简洁的参考代码:
def compute_miou(pred, target, num_classes=19, ignore_index=255): ious = [] pred = pred.argmax(dim=1) valid = target != ignore_index pred = pred[valid] target = target[valid] for cls in range(num_classes): pred_cls = pred == cls target_cls = target == cls inter = (pred_cls & target_cls).sum().float() union = (pred_cls | target_cls).sum().float() iou = (inter / (union + 1e-6)).item() ious.append(iou) return sum(ious) / num_classes你可能注意到代码里先把忽略像素过滤掉了,这是个好习惯。有些指标脚本没这么做,把 ignore 像素算成错误,结果会非常难看。
除了 mIoU,还要关注每类 IoU。整体 mIoU 高不代表模型可靠,很可能只是因为背景类占了大头。比如工业质检里缺陷只占画幅 1%,背景 IoU 99% 就把整体拉上去了,缺陷 IoU 可能还是 0。所以真实项目里我几乎都会报告“少数类 IoU”和“总体 mIoU”两个数字,早停也会基于少数类 IoU。
3.4 实际训练中的参数记录与调参轨迹
拿我自己在某公开街景数据集上的一个练手 demo 来说,用的模型是 U-Net 基础版,输入 512×512,batch size 8,学习率 1e-4,跑了 80 个 epoch。训练刚开始 loss 在 1.8 附近掉得很快,到第 20 个 epoch 就降到 0.6,mIoU 大约 0.42。之后进入平台期,loss 下降很慢,mIoU 在 0.65 附近抖动。我果断把学习率降到 3e-5,又训了 30 轮,mIoU 最后到了 0.73。
这个过程很典型:前段是模型快速学习主流类别,中段是慢慢磨难分像素,后段需要降低学习率才能继续收敛。如果一开始就把学习率调太大,loss 会出现震荡,mIoU 甚至可能倒退。如果你在实验里看到 loss 下降但 mIoU 不涨,优先怀疑类别不均衡;如果 loss 不降,再检查数据预处理和 label 是否有错。
Epoch 20 | loss 0.61 | mIoU 0.42 Epoch 50 | loss 0.38 | mIoU 0.65 Epoch 80 | loss 0.27 | mIoU 0.72 Epoch 110 | loss 0.24 | mIoU 0.73上面这组曲线来自我当时随手记的日志,可以看出后 30 轮提升非常有限。这种收益递减非常正常,真实项目做在线评估时,我会额外关注小类别的 IoU 是否提升,而不是只看整体平均。
3.5 消融实验与算法研究的正确打开方式
标题加上了“算法研究”,就不能只停留在“跑通一个模型”的层面。做对比实验要有结构:基线模型、改进模块、完整模型。每一次只改一个变量,这样才能确定精度提升来自什么地方。比如你想验证某个注意力模块有没有用,就必须在同样数据、同样增强、同样随机种子下,分别跑“不带模块”和“带模块”两个版本,比较 mIoU 和每类 IoU。
随机种子这一点很关键。分割训练里有很多随机操作:数据增强、dropout、初始化参数。如果不固定随机种子,同一份代码跑两次可能都会有 0.5 到 1 个点的 mIoU 浮动,很小的模块差异很容易被噪声掩盖。我的习惯是至少用三种随机种子跑三遍,报告均值,重点看最优和最差的差值有没有大于模块带来的净收益。
另外,消融实验也要关注计算量。一个模块如果让 FLOPs 涨了 20%,精度只涨 0.3 个点,那在工程上其实不值得。研究型和落地型项目对“涨点”的判断标准不同,前者看边际收益,后者更看重性价比。所以我在做实验记录时,会把参数量、推理耗时、显存峰值一起记录下来,后续好横向对比。
4. 项目落地中的常见问题与排查技巧
4.1 类别不平衡和loss不收敛
类别不平衡是分割任务里最常见的问题。我参与过一个路面积水检测项目,训练图像里道路和天空占绝大多数,积水的像素占比可能只有百分之几。用普通交叉熵训出来的模型几乎把所有像素都预测成背景,mIoU 看着还行,因为背景占比高,但积水区域基本全错。
排查时先统计训练集每个类别的像素占比,然后针对性处理。一种做法是降低大类别的 Loss 权重,让人为地放大目标类的作用;另一种做法是加权抽样,让每个批次尽量有足够的难例样本;还有 Focal Loss,它对已经被预测正确的像素降低贡献,让模型关注错误像素。最终我在这里采用了“加权交叉熵 + 在验证时用小类别 IoU 作为早停指标”的组合,效果比单纯改 loss 更好。记住,评估指标也要跟着业务目标走。
4.2 边界模糊和细节丢失
分割结果最让人头疼的往往是边界。明明原始图像里边缘很清晰,模型画出来却像锯齿或糊了一片。这是因为网络反复下采样和上采样之后,高频细节信息大量丢失。模型对区域中间部位预测得准,对边缘像素就犹豫不决。
解决方向有几个。第一,用带跳跃连接的模型,比如 U-Net,把浅层边缘特征引入解码器。第二,在训练损失里加一个边界感知项,比如单独计算边界区域的交叉熵,让模型把注意力放到边界像素上。第三,加强数据增强里的锐利度变化,或者使用边缘检测分支辅助监督。还有一个后处理思路是用条件随机场做平滑,现在已经不如以前流行,因为深度模型自己就能学出来,但对某些特定场景仍然有效。
4.3 GPU显存不足与推理速度优化
我在跑高分辨率遥感图像时遇到过好几次显存爆炸。遥感图动不动上万像素,直接放大模型显然不现实。常见的处理方法是把大图切成若干块训练和推理,每块尺寸设成 512×512 或 1024×1024,推理时再重叠滑窗并做融合。落到工程上,减少显存还有几招:把 batch size 调小、使用梯度累积、开启混合精度。混合精度尤其好用,在支持算力高的设备上能明显提速省显存,但要注意浮点稳定性,必要时在 loss scale 上做调整。
推理速度优化是另一个维度。很多落地场景要求实时,嵌入式设备算力有限。我先说结论:先做模型轻量化,再做推理加速。轻量化可以直接换 MobileNet 之类的轻量骨干,也可以对现有模型做通道剪枝;推理加速可以上 TensorRT、ONNX Runtime 这些工具,把模型转换成优化图,显存和时延都能降不少。我在某个实习项目里试过把 U-Net 用 TensorRT 做 FP16,性能在嵌入式设备上大约提升了 1.5 倍,误差几乎看不出来。
补充一点:滑动窗口推理时如果窗口之间没有重叠,拼接处会出现很明显的边界伪影。我的做法是让相邻窗口有 10% 到 20% 的重叠,在重叠区对预测概率做加权平均,权重偏向窗口中心。这样虽然推理时间增加了一些,但很大程度避免了“被切成块”的视觉断层。
4.4 标注噪声和数据质量问题
标注噪声对分割的影响往往被低估。语义分割的标注成本很高,一张街景图可能标几十分钟,所以真实项目里常会出现边缘不一致、漏标小物体甚至类别错标。模型为了拟合这些不一致,会把边界学得怪异,小目标时而出现时而消失。
处理标注噪声的办法,第一是设置 ignore_index,把标注者不确定的区域直接忽略掉,不要在 loss 里逼模型学它。第二是在训练中做置信度过滤,连续多轮预测都异常稳定的区域如果出现高 loss,很可能是坏标签。第三,如果条件允许,做一次标注复核,把模型预测结果和原始标签叠在一起给标注人员检查。个人体会是:宁可只标几百张干净图,也不要几千张带脏标的图,脏标会带来持续的精度损失,而且很难定位。
4.5 小目标漏检与多尺度问题
语义分割另一个高发问题是小目标漏检。一张图里远处的小人、交通标志、路面积水可能只有几十个像素,经过若干次 stride 为 2 的下采样后,到了高层特征图上只剩几个点甚至消失。常见改进办法是减少总下采样倍数,比如让特征图最终是原图的 1/8 而不是 1/32,但这会增加显存;也可以用空洞卷积保持分辨率。还可以引入特征金字塔或者 ASPP,把不同尺度的特征都接出来用于预测。
如果你暂时不想换模型,先试试测试时增强:把原图放大 1.5 倍预测一次,再原尺寸预测一次,把两次概率平均。这个方法在很多数据集上能稳定提升小目标 IoU,代价是推理时间翻倍。我在一些小目标缺陷检测任务上实测,mIoU 提升约 2 到 3 个点,属于便宜又有效的技巧。
5. 典型应用场景与选型建议
5.1 自动驾驶与道路场景分割
自动驾驶里的语义分割主要用于理解可行驶区域、车道线、行人、车辆和交通标志。这类场景有几个特点:类别多、目标尺度差异大、实时性要求极高。基于视觉的感知通常在车端芯片上跑,算力有限,所以模型不光要准,还要快。
我了解到的一些落地做法是先用离线大模型蒸馏出轻量化学生模型,学生模型用实时性高的网络结构,部署时再做 INT8 量化。这样能保留大部分精度,又把时延控制在几十毫秒以内。如果你刚入门,可以从一个简化版场景入手:只分割道路和背景,专注把数据平衡和边界问题处理清楚,再逐步加类别。
5.2 医学影像分割
医学影像是分割技术落地最深的领域之一。比如 CT 图像里分割某个器官,或者病理切片里分割病变区域。这类数据和自然图像差异很大:视场相对稳定,器官形态位置有一定规律,但个体差异、设备差异会带来域偏移。
U-Net 及变体是医学分割的主流,因为医学样本少、标注昂贵,跳跃连接带来的细节保留非常宝贵。训练时一般会用到弹性形变来增强,这样能模拟组织变形。另外医学分割通常要求结果平滑、连通性好,因为器官不能碎成几块,所以后处理里开闭运算或者条件随机场仍有一定价值。我个人的建议是,先花时间把数据格式和设备参数统一,否则跨中心测试时精度掉得吓人。
5.3 遥感图像与工业质检
遥感图像分割常用于土地利用分类、建筑物提取、道路提取。大图和复杂背景是主要痛点,单个目标可能只有十几像素,也可能是一整个稻田。解决方案通常是裁块 + 多尺度推理。有的项目会额外引入高程或光谱通道,把多模态数据拼到输入里,网络需要相应调整第一层卷积输入的通道数。
工业质检是更偏向成本敏感的小样本场景,比如产品表面缺陷分割。缺陷面积小而形态多样,普通交叉熵很难训练好。我的做法是先用少量标注数据训一个初始模型,再靠模型预测生成伪标签,不断用半监督方式扩充训练集。这类场景里模型精度不是唯一指标,漏检率和误报率往往更加重要,所以评估时不能只看 mIoU,可以额外统计逐像素的精确率和召回率。
5.4 如何根据硬件和效果选择模型
选择模型没有万能答案,但有几个常见路线可以参考。下面这张表是我在多个项目里总结出来的粗略经验:
| 场景 | 推荐模型族 | 核心原因 | 注意点 |
|---|---|---|---|
| 小样本医学图像 | U-Net 及变体 | 参数少、细节保留好 | 注意过拟合,增强要足 |
| 大尺度街景/遥感 | DeepLab 系 | 空洞卷积+多尺度强 | 计算量大,需优化 |
| 实时边缘设备 | 轻量化骨干+解码器 | 速度快 | 精度靠蒸馏补 |
| 极强全局上下文 | Transformer 分割 | 长距离建模强 | 显存和数据要求高 |
如果你的显卡显存只有8G左右,我的建议是不要一上来就跑最大的模型。先把 U-Net 或 DeepLabV3+ 的轻量版本跑通,确认数据流程和指标没问题,再逐步扩大。选模型本质是在效果、速度和开发成本之间做权衡,很多时候调优一个好的中等模型,效果比盲目上大模型更好。
从我自己的实验经历来看,与其一开始追新模型,不如先把数据质量、增强策略、损失函数和评估指标处理干净。很多时候你们以为是模型的问题,多看看数据,往往会有意外收获。这是我踩过不少坑之后比较深的体会,希望对你有用。