
做过几年视觉项目的人大概都有这么一段经历手上拿到一个检测需求第一反应是拉个 YOLO 跑一跑可真到了要解释「为什么这个方案比上一版好」的时候却发现自己讲不清 baseline 是什么。这时候回头去看目标检测的传统方法与深度学习算法对比就不是怀旧而是补课。传统方法指的是靠人工设计的特征算子加浅层分类器完成检测的一整套流程HOGSVM、DPM、Viola-Jones 是其中最有代表性的三个流派深度学习算法则是用卷积网络或注意力结构直接从数据里学特征从 R-CNN 一路演进到 YOLOv8、DETR。这篇文章想解决的就是一件事把两条路线放在同一份数据、同一套评价指标下摊开比让你知道各自的适用边界在哪里什么场景该选谁选错了会付出什么代价。内容偏实操适合正在做目标检测本科毕业设计的学生、刚转行做视觉工程的同学以及需要在嵌入式或低算力设备上落地方案的人。1. 先想清楚为什么还要回头看传统目标检测方法1.1 两条路线的根本分歧手工特征还是特征学习传统目标检测和深度学习目标检测的分歧点说到底就一句话特征是人设计的还是模型自己学的。传统方法里人要先想明白「猫的边缘长什么样」「行人的梯度分布有什么规律」然后把这些先验写成数学公式比如 HOG 把图像切成小格子统计梯度方向直方图SIFT 找尺度不变的关键点Haar 用矩形区域的灰度差描述明暗结构。这些特征一旦定下来后面接个 SVM、AdaBoost 或者随机森林就能出结果。优势是推理极快、内存占用极低、可解释性强你在嵌入式芯片上跑一个人形检测完全不需要 GPU。深度学习算法走的是完全相反的路。以 YOLO 为代表的检测网络不告诉你特征长什么样它只负责把标注好的框喂进去让卷积核自己去筛。卷积核在浅层学到的往往是边缘和纹理到了深层就变成了车轮、眼睛、文字块这种语义部件。这种「让数据说话」的方式在数据量足够的时候上限极高但代价也明显需要大量标注、需要 GPU、模型体积动辄几十上百 MB。有意思的是近几年轻量化方向又在往回走出现了 MACs 仅 5MB 的目标检测模型这类成果本质上是在用结构设计的手段把深度学习的开销压到接近传统方法的水平。这说明两条路线并不是取代关系而是在不同的约束条件下互相借鉴。我自己带过一个做鸟类目标检测的项目一开始直接上 YOLOv5mAP 很好但部署到野外监测盒子上温度压不住。后来把场景缩小到「白天、固定机位、只检测大体型鸟」用 HOGSVM 做了个粗筛把候选区域数量从整幅图降到十几个再交给一个小型 CNN 做细分类整体功耗降了一大截。这个例子很典型不是深度模型不行而是没想清楚约束条件在哪。1.2 一张对比表把差异摊开看空口讲差异容易飘直接上表更实在。下面这张表是我在做方案选型时常用的速查版本参数取自常见开源实现的中位数水平具体到你自己的项目会有出入但量级关系基本成立。维度传统方法HOGSVM / DPM / Viola-Jones深度学习算法Faster R-CNN / YOLO / SSD / DETR特征来源人工设计公式固定网络自动学习随数据变化典型标注需求每类几十到几百张即可起步每类通常需要上千张长尾类更多训练资源单核 CPU 分钟级单卡 GPU 小时级大模型天级推理速度CPU 上可达实时甚至更高视模型而定轻量模型 GPU 上可达数百 FPS模型体积通常几百 KB 到几 MB轻量 5MB 起常规几十到几百 MB小目标表现依赖滑动窗口步长漏检多多尺度特征融合后明显更好遮挡与形变明显退化相对鲁棒但严重遮挡仍难可解释性强能追溯到具体特征弱中间层语义靠可视化猜测类别扩展成本换类要重设计特征成本高加数据重训即可成本低部署门槛任意平台无特殊依赖需要推理框架或算子支持这张表里最容易被忽略的是最后两行。很多人只盯着 mAP 和 FPS却没算过「需求变更时我要付出多少」。传统方法在需求稳定、类别固定的场景里性价比极高比如闸机口的人脸粗定位、工业流水线上的固定缺陷检测。而一旦业务方今天要你加个新类别明天要你支持新角度传统方法的特征就得推倒重来这时候深度学习的优势才真正体现。提示选型时先把「类别是否会变、数据能拿到多少、部署端有什么算力」这三个问题写下来答案基本就决定了你该走哪条路不用纠结。2. 传统方法三大流派拆解与落地细节2.1 HOGSVM行人检测的经典配方与参数怎么定HOG 加 SVM 是传统检测里最值得先吃透的一套。它的流程拆开来是五步灰度化与 Gamma 校正、计算每个像素的梯度幅值和方向、把图像切成 cell 统计方向直方图、把相邻 cell 组成 block 做归一化、把所有 block 的特征拼成一条长向量丢给 SVM。Dalal 和 Triggs 在原始论文里给出的经典参数是 cell 8×8 像素、block 2×2 个 cell、block 步长 1 个 cell、方向 bin 取 9 个这套参数在 64×128 的行人窗口上跑出来是 3780 维特征。为什么是 9 个 bin因为把 0 到 180 度均分成 9 份每份 20 度这个粒度刚好能区分人体轮廓的主要梯度方向再多就冗余再少就丢信息。为什么 block 要重叠因为归一化能抑制光照变化带来的整体梯度缩放重叠取样相当于给每个 cell 多次归一化的机会对阴影和逆光更稳。这些设计背后的逻辑其实就是人工把「光照不变性」「局部对比度」这些先验编码进了特征。实操里最需要注意的是滑动窗口的尺度问题。原始 HOG 只在一个固定尺度上训练检测时要做图像金字塔每层缩放到 1.05 或 1.1 倍。步长和缩放比例的乘积决定了漏检率步长太大会漏掉小目标太小则速度崩掉。我一般先用 8 像素步长、1.05 缩放做粗筛再对有响应的区域做二次精检。2.2 DPM把形变这件事装进模型里的尝试DPM 全称是 Deformable Part Model可以理解成 HOG 的升级版。它的核心想法是一个物体不是一个刚性整体而是一个根滤波器加若干部件滤波器部件可以在一定范围内相对根移动移动的代价用一个形变损失项描述。比如检测行人根滤波器看整体轮廓部件滤波器分别盯着头、躯干、腿允许它们之间有小幅位移。这套设计对关节物体的鲁棒性明显好于纯 HOG代价是计算量翻了好几倍而且训练用的是 Latent SVM需要交替估计部件位置和更新模型参数调参非常容易翻车。实际项目里如果不是特别需要形变建模我不建议为了那两三个点的提升上 DPM。它更大的价值是思路上的启发——后来深度学习里的可变形卷积、注意力机制某种程度上都在解决同一个问题让模型知道物体的哪些部分可以怎么动。2.3 Viola-Jones级联结构为什么能在低算力设备上跑Viola-Jones 是少数真正做到「当年就在数码相机上实时跑」的检测算法。它的三件套是 Haar-like 特征、积分图、AdaBoost 级联。Haar 特征就是几种矩形区域的灰度差组合比如「上黑下白」这种模式积分图让任意矩形的求和变成四次查表把特征计算从 O(面积) 降到 O(1)AdaBoost 从几万个候选特征里挑出几百个最有区分度的弱分类器加权组合级联则是把强分类器串成一排前几级特别简单、专门用来砍掉大量明显的背景窗口后面的级才逐渐复杂。级联的精髓在于「早退」假设第一级把 50% 的背景干掉第二级再干掉 50%二十级之后背景误检率能压到百万分之一而真正包含目标的窗口几乎每一级都能通过平均计算量就大幅下降。这个思路后来被 SSD 的多尺度检测头、YOLO 的多级下采样变相继承——先便宜地排除掉大量简单负样本再花力气处理难样本。2.4 传统方法的实操代码与调参心得下面这段是用 skimage 和 sklearn 做 HOGSVM 行人检测的最小可跑版本我把关键参数都标了注释。注意这里用的是 INRIA 行人数据集的目录结构正样本放在 pos/ 下负样本放在 neg/ 下。import os import glob import cv2 import numpy as np from skimage.feature import hog from sklearn.svm import LinearSVC from sklearn.model_selection import train_test_split from sklearn.metrics import classification_report IMG_SIZE (64, 128) # HOG 行人检测的经典窗口尺寸 def extract_hog(img_path): img cv2.imread(img_path, cv2.IMREAD_GRAYSCALE) img cv2.resize(img, IMG_SIZE) # cell 8x8block 2x2步长 1 个 cell9 个方向 bin feat hog( img, orientations9, pixels_per_cell(8, 8), cells_per_block(2, 2), block_normL2-Hys, # 对光照更鲁棒比 L2 稍慢 transform_sqrtTrue, # Gamma 校正的廉价替代 feature_vectorTrue ) return feat def load_dataset(pos_dir, neg_dir): X, y [], [] for p in glob.glob(os.path.join(pos_dir, *.png)): X.append(extract_hog(p)) y.append(1) for p in glob.glob(os.path.join(neg_dir, *.png)): X.append(extract_hog(p)) y.append(0) return np.array(X), np.array(y) X, y load_dataset(./pos, ./neg) X_train, X_test, y_train, y_test train_test_split( X, y, test_size0.2, random_state42, stratifyy ) # C 是惩罚系数HOG 特征维度高C 太大会过拟合 clf LinearSVC(C0.01, max_iter5000, class_weightbalanced) clf.fit(X_train, y_train) pred clf.predict(X_test) print(classification_report(y_test, pred))调参上有几个我从踩坑里总结的点。第一C一定要往小调HOG 特征动辄几千维样本量又不大C 取 1 会立刻过拟合我一般从 0.01 开始试。第二transform_sqrtTrue能替代显式的 Gamma 校正效果差不多但省事。第三正负样本比例别搞成 1:1 就完事行人检测里负样本要多得多建议正负比控制在 1:3 到 1:5可以用难负样本挖掘反复迭代几轮。第四检测阶段别只在单一尺度上滑动一定要做图像金字塔否则远处的小目标全漏。注意LinearSVC 在高维稀疏特征上比 RBF 核 SVM 快一个数量级精度差距通常不到两个点。除非数据量很小又想榨干性能否则没必要上核方法。3. 深度学习检测算法的演进脉络与选型逻辑3.1 两阶段检测器R-CNN 到 Faster R-CNN 改了什么两阶段路线的核心思想是「先找候选区域再分类回归」。R-CNN 用 Selective Search 生成约两千个候选框逐个缩放到固定尺寸送进 CNN 提特征最后用 SVM 分类加线性回归修框。问题很明显两千次前向传播一张图要几十秒而且训练要分好几段。Fast R-CNN 把整张图先过一遍 CNN再用 ROI Pooling 从共享特征图上抠出候选区域的特征速度提升十倍以上还把分类和回归合并成一个多任务损失。Faster R-CNN 更进一步干脆用 RPN 网络自己生成候选框彻底扔掉了 Selective Search。Faster R-CNN 到现在仍是很多高精度场景的首选尤其是医学影像、遥感这类对漏检零容忍的任务。它的优点是精度稳、召回高、对小目标相对友好缺点是推理慢模型大。如果你的场景允许几百毫秒的延迟它比 YOLO 更省心因为不需要在精度和速度之间反复折磨。3.2 单阶段检测器YOLO 与 SSD 的速度哲学YOLOv1 把检测直接建模成回归问题把图像切成 7×7 的网格每个格子负责预测落在它中心的目标的类别和框。整个网络一次前向就出结果速度极快但小目标和密集目标表现差。后续版本一直在补这些短板v2 引入 anchor 和 BNv3 引入 FPN 多尺度预测和更深的 Darknet-53v5 加了自适应锚框和 Mosaic 增强到 v8 已经变成 anchor-free 加解耦头加 DFL 损失。SSD 走的是另一条路在多张不同尺度的特征图上分别预测浅层大特征图负责小目标深层小特征图负责大目标用 default box 而不是 anchor 来匹配。SSD 对小目标的效果比同期的 YOLO 好但 Positive/Negative 样本极度不平衡训练时负样本会淹没正样本后来 RetinaNet 用 Focal Loss 专门解决这个问题让单阶段检测器在精度上追平两阶段。选型上我的经验是追求极致速度选 YOLO 的 nano/tiny 版本追求精度和速度平衡选 YOLOv8m 或 SSD 的轻量骨干版本需要处理严重类别不平衡选带 Focal Loss 的 RetinaNet 结构。3.3 Anchor-Free 与 TransformerFCOS、DETR、YOLOv8 的分野Anchor 机制一直被人诟病的地方在于锚框的尺寸、比例、数量都是超参换个数据集就得重新聚类不然召回上不去。FCOS 直接取消了锚框改成对特征图上每个点预测它到目标四条边的距离配合中心度分支抑制低质量框。这种设计少了一堆超参训练也更简单对小目标反而更友好。DETR 则是把检测当成集合预测问题用 Transformer 编码器解码器加匈牙利匹配完全不需要 NMS 后处理。想法很优雅但收敛极慢要训几百个 epoch对小目标也不友好。后续的 Deformable DETR 用可变形注意力加速收敛才让它进入实用范围。至于 YOLOv8它本质上是把 anchor-free、解耦头、C2f 结构、DFL 损失这些已有的好设计整合在一起工程完成度极高ultralytics 库几行代码就能跑是目前落地最省心的选择。3.4 骨干网络与轻量化5MB 模型是怎么压出来的想做出 MACs 仅 5MB 级别的检测模型靠的不是单一技巧而是一套组合拳。第一是换骨干用 MobileNetV3、ShuffleNetV2、GhostNet 这类深度可分离卷积结构把标准卷积的乘加量降到三分之一以下。第二是砍输入分辨率从 640 降到 320计算量按面积平方下降代价是小目标基本没了。第三是通道剪枝训练完把贡献低的通道裁掉再微调。第四是量化FP32 转 INT8 通常体积直接除以四速度还能再提一截。我在一个类似需求上做过对比同样检测四类工业零件YOLOv8s 在 640 分辨率下模型 22MB换成 YOLOv8n 加 416 分辨率加 INT8 量化压到 6MB 出头mAP 只掉了三个点左右在 Jetson 上延迟从 40ms 降到 12ms。这个取舍值不值完全取决于业务能容忍多少精度损失。我的建议是先定死延迟和体积上限再往上堆精度而不是反过来。4. 评价指标不搞明白对比全是玄学4.1 IoU、Precision、Recall 的计算过程IoU 是交并比等于预测框和真实框的交集面积除以并集面积。通常 IoU 大于某个阈值比如 0.5就认为这个预测是正样本匹配上了。这里有个细节一个真实框可能被多个预测框匹配一个预测框也可能匹配多个真实框处理规则不同会直接影响结果两种常见的做法是把多余的预测判为 FP、把多余的 GT 判为 FN。Precision 精确率是「预测为正的里面有多少是对的」Recall 召回率是「真实的正样本里有多少被找出来了」两者天生打架。提高置信度阈值能让 Precision 上升但 Recall 下降所以看单一指标毫无意义必须画 PR 曲线。AP 就是 PR 曲线下的面积mAP 是所有类别 AP 的平均值。我见过太多人只报一个 mAP 就交差结果一上业务线发现漏检严重。原因通常是 Recall 高但 Precision 低框提了一大堆正确的没几个后处理扛不住。所以在对比传统方法和深度学习算法时我建议把 P、R、AP 分开列看曲线形状而不是只看一个数。4.2 mAP0.5 和 mAP0.5:0.95 到底差在哪VOC 时代用的是 mAP0.5IoU 阈值固定 0.5只要框得差不多就算对。COCO 引入了 mAP0.5:0.95也就是从 0.5 到 0.95 每隔 0.05 取一个阈值算十个 AP 再平均。这个指标对定位精度的要求高得多同一个模型在 mAP0.5 上可能是 0.85在 mAP0.5:0.95 上只有 0.55差出来的这 30 个点就是「框得准不准」的差距。实际对比时一定要说清楚用的哪个指标否则传统方法和深度学习算法的数字根本没有可比性。传统方法基于滑窗和 SVM 打分框的位置往往偏大偏松mAP0.5 尚可一旦收紧到 0.75 以上就崩得厉害。所以公平的比较方式是两者都调到自己最优状态然后在同一套阈值下评估。4.3 FPS、参数量、MACs速度指标怎么看才不被忽悠FPS 是最容易被包装的指标。同一个模型在 A100 上跑 200 FPS在 Jetson Nano 上可能只有 8 FPS差二十多倍。所以报 FPS 必须带上硬件型号、batch size、输入分辨率、推理框架这四个信息缺一个都不可信。参数量Params决定模型体积和显存占用MACs 决定理论计算量。这两个指标经常被混用实际上不一定正相关某些结构参数量小但 MACs 大比如大卷积核浅层网络。轻量化模型评估时两个都要看再加上实测延迟才是完整画像。做嵌入式选型时我更看重「目标硬件上的实测延迟」因为它把访存、算子支持、调度开销全都算进去了比理论 MACs 靠谱得多。指标反映什么适用场景容易踩的坑mAP0.5分类与粗定位能力VOC 类任务对比掩盖定位不准问题mAP0.5:0.95综合定位精度COCO 类任务对比数值普遍偏低别拿它跨论文比FPS端到端速度实时性要求场景不注明硬件就是耍流氓Params模型体积存储受限场景与速度不必然相关MACs理论计算量算法层面比较与实际延迟常脱节5. 同一份数据跑两套方案完整对比实验流程5.1 数据集准备与标注规范要做对比实验第一步是让两条路线吃同一份数据。我一般选一个中等规模的公开数据集比如只取 COCO 里的两个类或者用自建的工业缺陷数据。标注格式上HOGSVM 用的是「切片图 0/1 标签」YOLO 用的是「归一化中心点坐标 宽高」。切图这一步坑很多。传统方法需要正样本和负样本两个目录正样本要求目标尽量居中且带少量边距负样本要从明显的背景区域随机裁比例控制在 1:3 左右而且背景里不能混进任何目标的一小块。我做过一次实验负样本里混了几张带零件边角的图模型直接把那个边角特征学成了正类mAP 虚高十个点换测试集立刻打回原形。这种脏数据问题在对比实验里特别致命因为你会误以为传统方法很强。标注一致性也要检查。同一个目标两个人标的框可能差十几个像素对小目标来说这就是 IoU 从 0.6 掉到 0.4 的区别。建议用同一份标注文件同时导出两种格式从源头保证一致。5.2 传统方法训练与推理完整代码推理部分要自己写滑动窗口和图像金字塔下面这段是可直接跑的框架我加了 NMS 去重因为滑窗会产生大量重叠框。import cv2 import numpy as np from skimage.feature import hog def pyramid(img, scale1.05, min_size(64, 128)): yield img while True: w int(img.shape[1] / scale) h int(img.shape[0] / scale) if w min_size[0] or h min_size[1]: break img cv2.resize(img, (w, h)) yield img def sliding_window(img, win(64, 128), step8): for y in range(0, img.shape[0] - win[1] 1, step): for x in range(0, img.shape[1] - win[0] 1, step): yield (x, y, img[y:ywin[1], x:xwin[0]]) def nms(boxes, scores, iou_thr0.4): idx np.argsort(scores)[::-1] keep [] while len(idx) 0: i idx[0] keep.append(i) if len(idx) 1: break xx1 np.maximum(boxes[i, 0], boxes[idx[1:], 0]) yy1 np.maximum(boxes[i, 1], boxes[idx[1:], 1]) xx2 np.minimum(boxes[i, 2], boxes[idx[1:], 2]) yy2 np.minimum(boxes[i, 3], boxes[idx[1:], 3]) w np.maximum(0, xx2 - xx1) h np.maximum(0, yy2 - yy1) iou (w * h) / ( (boxes[i, 2]-boxes[i, 0]) * (boxes[i, 3]-boxes[i, 1]) (boxes[idx[1:], 2]-boxes[idx[1:], 0]) * (boxes[idx[1:], 3]-boxes[idx[1:], 1]) - w * h 1e-9 ) idx idx[1:][iou iou_thr] return keep def detect(img, clf): boxes, scores [], [] for scale_img in pyramid(img): for (x, y, patch) in sliding_window(scale_img, step8): gray cv2.cvtColor(patch, cv2.COLOR_BGR2GRAY) feat hog(gray, orientations9, pixels_per_cell(8, 8), cells_per_block(2, 2), block_normL2-Hys, transform_sqrtTrue, feature_vectorTrue) score clf.decision_function([feat])[0] if score 0.8: boxes.append([x, y, x 64, y 128]) scores.append(score) if not boxes: return [] keep nms(np.array(boxes, dtypefloat), np.array(scores)) return [boxes[i] for i in keep]这段代码有几个容易忽略的点。滑窗 step 取 8 是速度和召回的折中想更快可以取 16 但会漏小目标。score 阈值 0.8 是我在自己数据上调出来的通用情况下建议在验证集上扫一遍选 F1 最高的点。还有一点图像金字塔缩放后坐标要映射回原图否则框的位置全错这里为了简洁先省略了实际项目一定要补上。5.3 YOLOv8 训练与推理完整代码深度侧我用 ultralytics 的 YOLOv8训练和验证几行就搞定配置文件里指定数据集路径即可。from ultralytics import YOLO # 训练从预训练权重开始10 个 epoch 足够看出趋势 model YOLO(yolov8n.pt) model.train( datadataset.yaml, # 里面写 train/val 路径和类别名 epochs100, imgsz640, batch16, lr00.01, cos_lrTrue, # 余弦退火收敛更稳 mosaic1.0, # 小目标多的话保持默认 close_mosaic10 # 最后 10 个 epoch 关掉马赛克 ) # 验证输出 mAP0.5 和 mAP0.5:0.95 metrics model.val(datadataset.yaml, imgsz640) print(metrics.box.map50, metrics.box.map) # 推理并导出为 ONNX方便部署 model.export(formatonnx, dynamicFalse, simplifyTrue)dataset.yaml 的格式是固定的我贴一份模板path: ./data train: images/train val: images/val nc: 2 names: [defect, scratch]训练里我建议开cos_lr学习率余弦退火在中小数据集上比固定步长衰减稳定。close_mosaic这个参数很关键马赛克增强能把四张图拼一张对小目标帮助很大但最后几个 epoch 关掉它能让模型适配真实分布mAP 通常能再涨一两个点。如果数据集很小把pretrained打开迁移学习效果会比从零训练好得多。5.4 结果对照与误差分析怎么做才有意义跑完两边不要只比一个 mAP 就完事。我习惯按下面这个矩阵来对照因为不同指标的变化方向能告诉你问题出在哪。对比项HOGSVMYOLOv8n差异解读mAP0.50.620.87深度学习在分类上优势明显mAP0.750.310.71定位精度差距被放大小目标 AP0.180.52多尺度特征融合起决定作用CPU 单图延迟180ms1200ms传统方法在无 GPU 时更快GPU 单图延迟-6ms深度模型吃算力吃得值模型体积0.8MB6MB差距没有想象中大新增一类成本重设计特征重训需求易变时深度学习省事误差分析上一定要做可视化。把两边漏检和误检的图挑出来看如果传统方法的漏检集中在光照变化和遮挡样本上说明手工特征的归一化不够如果深度学习误检集中在某类背景纹理上说明训练集里缺少这类负样本。我做过一次对比传统方法在小目标上 AP 只有 0.18把金字塔缩放比例从 1.05 改成 1.02 后涨到 0.29代价是耗时翻倍。这种细节只有真正跑过才知道。6. 特殊场景踩坑实录小目标、三维、开放词汇6.1 小目标检测为什么 mAP 一直上不去小目标难在两个地方。一是像素太少一个 16×16 的目标经过五次下采样变成 0.5 个像素特征直接消失二是正样本太少anchor 匹配时一个目标可能一个正样本都分不到。解决思路有几种提高输入分辨率让小目标在特征图上多占几个像素用 FPN 或 PAN 把浅层高分辨率特征和深层语义特征融合改 anchor 尺寸让小框有匹配或者用 SAHI 这种切图推理的策略。我在一个遥感小目标项目里试过组合方案输入从 640 提到 1280加 FPNanchor 重新聚类到最小 8 像素mAP0.5 从 0.41 提到 0.68但推理延迟涨了三倍。所以小目标检测本质上是一个算力换精度的交易先确认硬件扛不扛得住再动手。6.2 三维目标检测与鸟类、滑坡泥石流这类垂直数据集三维目标检测和二维完全是两套体系。输入通常是点云或者点云加图像输出是带朝向的立方体框评价指标用的是 3D IoU还要考虑航向角误差。代表方法有 PointPillars、SECOND、CenterPoint 这些。它的难点在于点云稀疏且无序无法直接套卷积必须做体素化或柱状化。垂直领域的数据集又是另一回事。鸟类目标检测因为羽毛纹理和背景枝叶极其相似细粒度分类比检测本身更难CUB-200 这类数据集专门用来做细粒度识别。而滑坡泥石流检测的数据集往往来自无人机或监控特点是目标巨大、边界模糊、正负样本极度不平衡用常规检测网络容易把整片山体都框进去。这类场景我一般会把任务从「检测」退化到「分割 面积阈值判断」反而更稳。6.3 开放词汇检测与不确定学习的新思路传统检测网络只能检测训练时见过的类别想加一类必须重新标注重训。开放词汇目标检测OVD的思路是把图像区域和文本描述对齐比如用 CLIP 这样的图文预训练模型计算区域特征和类别文本特征的相似度从而实现零样本检测新类别。代表工作有 GLIP、Grounding DINO 这类。它解决了「长尾类别标注成本高」的问题但目前在定位精度上还打不过闭集模型更适合做辅助召回。不确定学习这个方向也值得关注。检测模型给出的置信度往往过度自信一个明显错的框也能给 0.9 分。做法是在损失里引入不确定性建模让模型对模棱两可的样本输出低置信度或者用贝叶斯近似估计预测方差。我在工业质检里试过用 MC Dropout 估计方差把高方差样本挑出来送人工复核误判率降了将近一半。这条路对安全关键场景很有价值。7. 排查速查表与场景选型建议7.1 训练不收敛、指标异常的排查清单不管是传统方法还是深度学习算法出问题的表现往往相似但原因完全不同。下面这张表是我这些年攒下来的对照清单按出现频率排序。现象传统方法可能原因深度学习方法可能原因优先排查mAP 极低正负样本标注混入标签格式或类别 id 错位先看标注文件只检出大类特征被大类主导类别不平衡长尾类样本少重采样或调 class_weight框位置偏移金字塔坐标未映射回原图回归损失权重太低检查坐标变换训练 loss 不降C 值过大过拟合学习率过大或数据未归一化学习率先除以 10验证集远差于训练集负样本太单一过拟合增强不足加数据增强或正则推理比训练慢很多滑窗步长太小输入分辨率过高或未用半精度先降分辨率试试小目标全漏缩放比例太粗下采样倍率过高加浅层检测头用这张表的时候有个原则一次只改一个变量。我见过太多人同时调学习率、改增强、换骨干最后涨了也不知道是哪个起的作用下次换个数据集又抓瞎。做对比实验尤其要克制。7.2 场景选型速查表最后给一份我自己在用的选型判断条件从上往下判断命中哪条就用对应方案。你的场景特征推荐方案理由只有 CPU延迟要求 10ms 内Viola-Jones 或轻量 HOGSVM无需 GPU 算子支持类别固定数据少于 500 张HOGSVM 加难负样本挖掘小数据下深度模型易过拟合需要检测 5 类以上数据充足YOLOv8 或 SSD扩展性和精度都占优小目标密集如航拍或遥感YOLOv8 加高分辨率加 FPN多尺度融合必不可少医学影像零漏检要求Faster R-CNN 加高分辨率召回优先速度可让位模型体积必须小于 10MB轻量骨干加量化剪枝加 INT8 是标准打法需要检测训练时没见过的类开放词汇检测模型图文对齐实现零样本三维空间定位PointPillars 或 CenterPoint二维方法无法给出深度我个人在实际操作中的体会是别把「传统方法」和「深度学习算法」当成新旧两代技术来对立。它们更像是工具箱里两把不同用途的扳手一个适合在资源紧张、需求稳定的场合快速交活一个适合在数据充足、需求易变的场合追求上限。真正拉开工程师差距的不是会不会调 YOLO 的参数而是拿到需求后能不能在十分钟内判断出该用哪把扳手以及用错了之后能多快发现自己错了。我踩过最大的一个坑就是在一个只有两千张图、五类缺陷的质检项目上硬上深度模型训练了两天 mAP 才 0.6后来换成 HOG 加级联分类器半天搞定mAP 反而 0.72。那次之后我给自己定了条规矩新项目先花两个小时把传统基线跑出来哪怕最后不用它也是你判断深度模型到底有没有价值的标尺。