拓十年匠心定制 · 商业建站与技术教学双线并行 咨询热线:400-886-1026 service@lmnt.cn
ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

4300张YOLO猫狗检测数据集实战:从数据评估到模型部署全链路

4300张YOLO猫狗检测数据集实战:从数据评估到模型部署全链路

猫狗检测这个方向,看起来简单,实际上手才知道坑有多深。我前后用过五六个公开的宠物数据集,要么类别标注混乱,要么图片分辨率参差不齐,要么背景单一导致模型一换场景就崩。这次拿到一份4300张的YOLO格式猫狗检测数据集,从清洗到训练再到部署完整跑了一遍,中间踩了不少坑,也积累了一些在标准文档里找不到的经验。这篇文章会把整个流程拆开讲清楚——数据集怎么评估、YOLO训练参数怎么调、常见报错怎么排查、模型怎么落到实际场景里。不管你是刚接触目标检测的新手,还是想找一个靠谱猫狗数据集做baseline的老手,应该都能从里面找到有用的东西。

1. 拿到数据集先别急着训练:4300张猫狗数据的质量评估方法

很多人拿到数据集第一反应就是直接丢进YOLO跑训练,结果训到一半发现loss不降、mAP上不去,回头查才发现数据集本身有问题。4300张听起来不少,但如果标注质量差、类别不均衡、场景重复度高,实际有效数据可能连一半都不到。所以第一步一定是做数据质量评估,这个环节花半小时,后面能省你好几天。

1.1 类别分布与标注框尺寸分布检查

猫狗检测数据集最基础的两个类别就是cat和dog,但实际情况往往比这复杂。有些数据集会把猫细分成不同品种,有些会把流浪猫狗和宠物猫狗分开标注,还有些数据集里混入了其他动物甚至人物。拿到数据后第一件事就是统计每个类别的实例数量和标注框的尺寸分布。

我一般用一段简单的Python脚本做统计:

import os from collections import Counter label_dir = "labels/train" class_counter = Counter() box_sizes = [] for txt_file in os.listdir(label_dir): if not txt_file.endswith(".txt"): continue with open(os.path.join(label_dir, txt_file), "r") as f: for line in f.readlines(): parts = line.strip().split() if len(parts) < 5: continue cls_id = int(parts[0]) w = float(parts[3]) h = float(parts[4]) class_counter[cls_id] += 1 box_sizes.append((w, h)) print("类别分布:", class_counter) print("平均框宽:", sum(s[0] for s in box_sizes) / len(box_sizes)) print("平均框高:", sum(s[1] for s in box_sizes) / len(box_sizes))

跑完之后重点看几个指标:如果cat和dog的比例超过3:1,训练时就需要考虑类别加权或者过采样;如果大量标注框的宽高都小于0.05(归一化坐标),说明数据集中有很多小目标,默认的YOLO anchor可能匹配不好,需要重新聚类anchor;如果某些图片的标注框数量异常多(比如一张图里标了20个框),要检查是不是标注工具出了问题导致重复标注。

1.2 图片分辨率与长宽比的实际影响

4300张图片的分辨率分布直接决定了你训练时的输入尺寸选择。我见过一些数据集里混着4K高清图和320x240的缩略图,这种数据如果不做统一处理,训练时letterbox缩放会导致小图被过度放大、大图被严重压缩,模型学到的特征尺度完全混乱。

实际操作中,我会先统计所有图片的宽高:

from PIL import Image import os img_dir = "images/train" sizes = [] for img_file in os.listdir(img_dir): if img_file.endswith((".jpg", ".png", ".jpeg")): with Image.open(os.path.join(img_dir, img_file)) as im: sizes.append(im.size) widths = [s[0] for s in sizes] heights = [s[1] for s in sizes] print(f"宽度范围: {min(widths)} - {max(widths)}, 中位数: {sorted(widths)[len(widths)//2]}") print(f"高度范围: {min(heights)} - {max(heights)}, 中位数: {sorted(heights)[len(heights)//2]}")

如果中位数在640x640附近,直接用YOLO默认的640输入就行。如果中位数偏小(比如416x416),可以考虑用512或416训练以加快速度。如果图片长宽比差异很大(有的16:9有的1:1),letterbox之后有效像素会损失不少,这时候可以考虑用矩形训练(rect=True)来减少padding。

1.3 场景重复度与背景多样性的快速判断

这一步很多人会忽略,但对模型泛化能力影响极大。如果4300张图里有3000张都是同一个客厅背景、同一只猫,那训出来的模型基本只能在这个客厅里工作。快速判断的方法是计算图片的感知哈希(pHash),看看有多少图片是高度相似的:

import imagehash from PIL import Image import os hashes = [] img_dir = "images/train" for img_file in os.listdir(img_dir)[:500]: # 抽样500张 if img_file.endswith((".jpg", ".png")): with Image.open(os.path.join(img_dir, img_file)) as im: hashes.append(imagehash.phash(im)) duplicates = 0 for i in range(len(hashes)): for j in range(i+1, len(hashes)): if hashes[i] - hashes[j] < 5: # 汉明距离小于5认为高度相似 duplicates += 1 print(f"抽样500张中,高度相似对数量: {duplicates}")

如果相似对超过50,说明数据集场景重复度偏高,训练时需要更强的数据增强(比如Mosaic、MixUp、随机裁剪),否则模型很容易过拟合到特定背景。

提示:数据质量评估不是可选项。我自己的习惯是每次拿到新数据集,先花20分钟跑完上面三个检查,把有问题的图片和标注挑出来单独处理,再开始训练。这个习惯帮我省下了大量反复调参的时间。

2. YOLO训练猫狗检测模型:从环境搭建到参数配置的完整链路

数据评估做完之后,接下来就是训练环境的搭建和参数配置。这部分我会以YOLOv8为例来讲,因为它在猫狗检测这种中等规模数据集上表现稳定,社区支持也最好。但思路对YOLOv5、YOLOv9甚至YOLOv10都是通用的。

2.1 环境搭建中最容易翻车的三个细节

环境搭建看起来简单,pip install几条命令就完事了,但实际翻车率极高。我总结下来最容易出问题的是三个地方。

第一个是CUDA版本和PyTorch版本的匹配。很多人直接pip install ultralytics,然后发现torch.cuda.is_available()返回False。这是因为pip默认装的是CPU版本的PyTorch。正确的做法是先确定你的显卡驱动支持的CUDA版本,然后去PyTorch官网找到对应的安装命令。比如CUDA 11.8对应的命令是:

pip install torch torchvision --index-url https://download.pytorch.org/whl/cu118 pip install ultralytics

第二个是OpenCV的版本冲突。ultralytics依赖opencv-python,但如果你之前装过opencv-contrib-python或者opencv-python-headless,可能会出现cv2.imshow报错或者视频读取失败。解决办法是先卸载所有opencv相关的包,再重新安装:

pip uninstall opencv-python opencv-contrib-python opencv-python-headless -y pip install opencv-python

第三个是numexpr和bottleneck的版本问题。这两个包在某些系统上会和numpy版本冲突,导致训练时出现奇怪的RuntimeError。如果你遇到类似"module 'numexpr' has no attribute"的报错,直接升级这两个包就行。

2.2 数据配置文件yaml的写法与常见错误

YOLO训练需要一个data.yaml文件来指定数据集路径和类别信息。猫狗检测的yaml文件基本结构如下:

path: /home/user/datasets/cat_dog train: images/train val: images/val test: images/test nc: 2 names: 0: cat 1: dog

看起来简单,但有几个坑我必须提醒。第一,path字段最好用绝对路径,相对路径在不同工作目录下运行时会找不到文件。第二,train和val的路径是相对于path的,不是相对于yaml文件本身。第三,names的顺序必须和标注文件里的class_id对应,如果标注时cat是0、dog是1,这里就不能写反。

还有一个隐蔽的问题:如果图片文件夹里混有非图片文件(比如.DS_Store或者Thumbs.db),YOLO在扫描时会报错。训练前最好清理一下:

find images/ -name ".DS_Store" -delete find images/ -name "Thumbs.db" -delete

2.3 训练参数的选择逻辑:为什么这样设而不是那样设

YOLOv8的默认训练参数在猫狗检测数据集上基本可用,但有几个关键参数需要根据你的实际情况调整。我一般用这样的配置:

yolo detect train \ data=cat_dog.yaml \ model=yolov8s.pt \ epochs=100 \ imgsz=640 \ batch=16 \ lr0=0.01 \ lrf=0.01 \ patience=20 \ augment=True \ mosaic=1.0 \ mixup=0.1 \ degrees=10.0 \ translate=0.1 \ scale=0.5 \ fliplr=0.5 \ name=cat_dog_v8s

逐个解释一下选择理由。model选yolov8s而不是yolov8n,是因为猫狗检测虽然类别少,但猫和狗的形态差异大、姿态多变,nano模型的特征提取能力偏弱,small模型在精度和速度之间平衡得更好。epochs设100是因为4300张图片属于中等规模,通常50-80轮就能收敛,设100留足余量配合patience=20做早停。batch=16是在8GB显存下的安全值,如果你显存更大可以加到32。

lr0=0.01是SGD优化器的初始学习率,配合lrf=0.01意味着最终学习率降到0.0001。这个衰减策略在猫狗检测上比较稳,不会出现loss震荡。mosaic=1.0开启Mosaic增强,对提升小目标和遮挡场景的检测效果明显。mixup=0.1是轻度MixUp,再高会导致训练初期收敛变慢。degrees=10.0是随机旋转角度,猫狗的姿态本身就多变,适度的旋转增强有帮助,但不要超过15度,否则会出现大量不自然的倒立猫狗。

2.4 训练过程中的loss曲线解读与异常判断

训练启动后,重点盯三个指标:box_loss、cls_loss和mAP50。正常情况下,box_loss和cls_loss在前10个epoch快速下降,然后缓慢收敛。mAP50在30个epoch左右应该达到0.85以上(猫狗检测相对简单,这个指标不算高)。

如果出现以下情况,需要及时干预:

现象可能原因处理方式
box_loss持续在1.0以上不降学习率过大或标注框质量差降低lr0到0.001,检查标注
cls_loss震荡剧烈batch size太小或数据类别不均衡增大batch,检查类别分布
mAP50卡在0.5左右数据增强过强或模型容量不足降低mosaic概率,换更大模型
val_loss开始上升过拟合增加dropout,提前停止训练

我遇到过一次比较诡异的情况:训练到第40轮时mAP突然从0.88掉到0.72,查了半天发现是学习率衰减到太低之后,模型在某个局部最优解附近震荡。解决办法是把lrf从0.01调到0.05,让最终学习率不要降得太低。

注意:训练日志里的"混淆矩阵总和不为1"是一个常见警告,通常是因为某些类别的预测框和真实框匹配不上。如果只是轻微偏差不用管,如果偏差很大(比如总和只有0.6),说明模型在某些类别上完全没学到东西,需要检查该类别的标注数量是否过少。

3. 猫狗检测模型的效果验证:mAP之外你还需要看什么

训练完成后,mAP50和mAP50-95是最直观的指标,但光看这两个数字远远不够。实际部署中,模型的误检、漏检、边界框质量、不同场景下的稳定性,都比一个单一的mAP值更重要。

3.1 混淆矩阵与PR曲线的实际解读

YOLO训练结束后会自动生成混淆矩阵和PR曲线。混淆矩阵看的是猫和狗之间有没有互相误判——正常情况对角线应该很深,如果cat被预测成dog的比例超过10%,说明模型对这两个类别的区分能力不足。可能的原因是训练数据里猫和狗的图片风格差异太大(比如猫都是室内、狗都是室外),模型学到了背景而不是动物本身。

PR曲线看的是在不同置信度阈值下的精确率和召回率平衡。猫狗检测的理想PR曲线应该靠近右上角,如果曲线明显偏左,说明模型在高召回时精确率掉得很快,实际使用时需要把置信度阈值调高来减少误报。

我一般会跑一段验证脚本,把误检和漏检的图片单独挑出来看:

from ultralytics import YOLO import os model = YOLO("runs/detect/cat_dog_v8s/weights/best.pt") results = model.val(data="cat_dog.yaml", save_json=True) # 查看每个类别的详细指标 for i, name in enumerate(["cat", "dog"]): print(f"{name}: mAP50={results.box.map50:.3f}, " f"precision={results.box.p[i]:.3f}, " f"recall={results.box.r[i]:.3f}")

如果某个类别的recall明显低于precision,说明漏检严重,可能是该类别的训练样本太少或者标注不完整。如果precision低而recall高,说明误检多,需要提高置信度阈值或者增加负样本。

3.2 实际场景测试:室内、室外、遮挡、多目标

验证集上的指标好看不代表实际场景能用。我习惯在训练完成后,找几类典型场景做实际测试:室内近距离、室外远距离、部分遮挡、多只猫狗同框。每类场景至少测20张图,统计检测成功率和误检率。

室内近距离场景通常没问题,模型在训练集里见过大量类似图片。室外远距离是难点,猫狗在画面中可能只占几十个像素,这时候小目标的检测能力就体现出来了。如果远距离漏检严重,可以考虑在训练时增加小目标的过采样,或者用更高分辨率的输入(比如imgsz=1280)。

遮挡场景考验的是模型对局部特征的利用能力。猫躲在沙发后面只露出一个头,狗被其他物体挡住半个身子,这些情况在真实场景中很常见。如果模型对遮挡场景表现差,可以在数据增强里加大随机擦除(erasing)的概率。

多目标场景主要看NMS(非极大值抑制)的效果。如果两只猫挨得很近,NMS的IoU阈值设得太高会导致其中一只被抑制掉。YOLOv8默认的IoU阈值是0.7,对于密集场景可以适当调低到0.5-0.6。

3.3 模型量化与推理速度的平衡

如果你打算把模型部署到边缘设备上,推理速度就是一个必须考虑的因素。YOLOv8s在RTX 3060上的推理速度大约是每张图5-8毫秒,但在树莓派或者手机上可能慢到几百毫秒。这时候就需要做模型量化。

YOLO支持导出为ONNX、TensorRT、OpenVINO等格式。ONNX通用性最好,TensorRT在NVIDIA设备上速度最快,OpenVINO在Intel平台上表现好。导出命令很简单:

yolo export model=best.pt format=onnx opset=12 simplify=True yolo export model=best.pt format=engine half=True device=0

half=True表示FP16量化,在支持FP16的设备上能提速30%-50%,精度损失通常在1%以内。如果对精度要求极高,可以用INT8量化,但需要提供校准数据集,而且精度损失可能达到3%-5%。

我实测下来,YOLOv8s导出TensorRT FP16之后,在RTX 3060上的推理速度从6ms降到了3.5ms,mAP50只掉了0.3个百分点,性价比很高。但如果你的场景对精度极其敏感(比如需要精确区分猫的品种),建议还是用FP32。

4. 猫狗检测数据集使用中的典型踩坑与排查实录

这一部分记录我在使用这个4300张猫狗数据集过程中实际遇到的问题和排查过程。有些坑是数据集本身的,有些是YOLO训练框架的,还有些是环境配置的。每个问题我都会把排查链路完整写出来,方便你遇到类似情况时参考。

4.1 标注文件格式错误的批量修复

拿到数据集后第一次训练就报错,提示"Label format invalid"。检查后发现部分标注文件里出现了坐标值大于1的情况。YOLO的标注格式要求所有坐标都是归一化到0-1之间的,但有些标注工具在导出时没有做归一化,或者图片尺寸信息丢失导致归一化错误。

排查过程是这样的:先写脚本扫描所有标注文件,找出坐标值超出[0,1]范围的行:

import os label_dir = "labels/train" bad_files = [] for txt_file in os.listdir(label_dir): if not txt_file.endswith(".txt"): continue with open(os.path.join(label_dir, txt_file), "r") as f: for line_num, line in enumerate(f.readlines(), 1): parts = line.strip().split() if len(parts) < 5: bad_files.append((txt_file, line_num, "字段数不足")) continue coords = [float(x) for x in parts[1:5]] if any(c < 0 or c > 1 for c in coords): bad_files.append((txt_file, line_num, f"坐标越界: {coords}")) print(f"发现 {len(bad_files)} 个问题") for f in bad_files[:10]: print(f)

修复方式取决于问题原因。如果是归一化遗漏,需要找到对应的图片,读取实际宽高,重新计算归一化坐标。如果图片已经丢失,只能删除这些标注行。我处理的那批数据里有大约30个文件存在这个问题,修复后训练就正常了。

4.2 训练中BN层崩溃的排查链路

训练到第60轮左右时突然报错:"RuntimeError: Expected all tensors to be on the same device",指向BN层。这个错误在YOLO训练中不算罕见,但排查起来比较绕。

第一步先确认是不是多卡训练导致的设备不一致。如果你用了device=0,1,但某张卡的显存不够导致部分张量被自动放到了CPU上,就会出现这个问题。解决办法是改成单卡训练,或者减小batch size。

第二步检查是否有自定义的BN层实现和YOLO内置的冲突。如果你在模型里加了自定义模块,确认所有参数都在同一个device上。

第三步看是不是数据加载器的问题。num_workers设得太大时,某些系统上会出现数据加载异常,导致batch里的张量device不一致。把num_workers从8降到4试试。

我最后发现是num_workers=8加上pin_memory=True在某些Windows系统上会导致这个问题。改成num_workers=4、pin_memory=False之后就稳定了。这个坑在Linux上基本不会遇到,但Windows用户需要特别注意。

4.3 小目标漏检的针对性优化

猫狗检测中,远距离的小目标是漏检重灾区。我测试了一组室外远景图片,发现当猫狗在画面中的像素面积小于32x32时,召回率只有40%左右。针对这个问题,我尝试了几种优化方案。

方案一是提高输入分辨率。从640提到1280,小目标召回率提升到65%,但推理速度慢了3倍。方案二是修改anchor尺寸,用k-means对数据集中的标注框重新聚类,得到更适合小目标的anchor。方案三是在数据增强中增加小目标的复制粘贴(copy-paste augmentation),人为增加小目标样本的数量。

我最终采用的是方案二加方案三的组合。重新聚类anchor之后,小目标召回率提升到58%,再加上copy-paste增强,最终达到72%。虽然还是不如高分辨率方案,但推理速度没有损失,综合性价比更高。

anchor聚类的代码大概是这样:

import numpy as np from sklearn.cluster import KMeans # 读取所有标注框的宽高 boxes = [] for txt_file in os.listdir(label_dir): with open(os.path.join(label_dir, txt_file)) as f: for line in f: parts = line.strip().split() if len(parts) >= 5: boxes.append([float(parts[3]), float(parts[4])]) boxes = np.array(boxes) kmeans = KMeans(n_clusters=9, random_state=42).fit(boxes) anchors = kmeans.cluster_centers_ print("聚类得到的anchors:") for a in sorted(anchors.tolist(), key=lambda x: x[0]*x[1]): print(f" - [{a[0]:.4f}, {a[1]:.4f}]")

把得到的anchors写进模型配置文件里替换默认值,重新训练即可。

4.4 数据集类别不均衡的过采样实践

这个4300张的数据集里,猫的实例数大约是狗的1.8倍。虽然不算极端不均衡,但在训练中发现狗类别的recall明显低于猫。除了在loss里加类别权重,我还用了过采样策略:把包含狗的图片在训练集中重复采样,使得两个类别的实例数大致相等。

实现方式是在data.yaml里不直接指向原始文件夹,而是生成一个采样后的文件列表:

import os import random img_dir = "images/train" label_dir = "labels/train" cat_images = [] dog_images = [] for txt_file in os.listdir(label_dir): with open(os.path.join(label_dir, txt_file)) as f: classes = [int(line.split()[0]) for line in f if line.strip()] img_name = txt_file.replace(".txt", ".jpg") if 1 in classes: dog_images.append(img_name) if 0 in classes: cat_images.append(img_name) # 对狗类别过采样,使其数量接近猫 ratio = len(cat_images) / len(dog_images) oversampled_dogs = dog_images * int(ratio) + random.sample(dog_images, int(len(dog_images) * (ratio - int(ratio)))) all_images = cat_images + oversampled_dogs random.shuffle(all_images) with open("train_oversampled.txt", "w") as f: for img in all_images: f.write(f"./images/train/{img}\n")

然后在data.yaml里把train指向这个txt文件。过采样之后,狗类别的recall从0.78提升到了0.86,效果比较明显。但要注意不要过采样太狠,否则会导致狗类别过拟合。

5. 从训练到落地:猫狗检测模型的部署与持续优化思路

模型训练好只是第一步,真正产生价值是在部署之后。这部分聊聊部署方案的选择、推理优化的技巧,以及模型上线后怎么持续迭代。

5.1 不同部署场景的方案选择

猫狗检测的部署场景大致分三类:服务器端批量处理、边缘设备实时检测、移动端轻量应用。每类场景对模型的要求不同。

服务器端批量处理对速度要求不高,但对精度要求高,可以直接用PyTorch原模型或者ONNX Runtime,batch size设大一点充分利用GPU。边缘设备(比如Jetson Nano、树莓派)需要模型足够小、推理足够快,建议用YOLOv8n导出TensorRT或OpenVINO。移动端(Android/iOS)推荐用NCNN或TFLite,模型需要进一步量化到INT8。

我整理了一个简单的对比表:

部署场景推荐格式模型大小推理速度精度损失
服务器GPUPyTorch/ONNX22MB5ms0%
边缘设备TensorRT FP1611MB8ms<1%
移动端TFLite INT86MB25ms3-5%
CPU服务器OpenVINO11MB40ms<1%

选择的时候不要盲目追求最快,要根据实际业务需求来。比如一个宠物监控应用,每秒处理5帧就够了,那CPU上的OpenVINO完全能满足,没必要上GPU。

5.2 推理后处理中的NMS阈值调优

模型输出的原始检测框有很多重叠,需要NMS来去重。YOLO默认的conf阈值是0.25,IoU阈值是0.7。这两个值对最终效果影响很大。

conf阈值调高会减少误检但增加漏检,调低则相反。猫狗检测中,如果场景里只有猫狗没有其他干扰物,conf可以设低一点(0.15-0.2)保证召回。如果场景复杂(比如户外有各种动物),conf要设高一点(0.4-0.5)避免误报。

IoU阈值控制的是重叠框的抑制程度。两只猫挨在一起时,如果IoU阈值太低(比如0.3),其中一只可能被误抑制。如果太高(比如0.9),同一个目标可能出现多个检测框。猫狗检测中,0.5-0.6是比较稳妥的范围。

实际调优时,我会写一个简单的网格搜索脚本,在验证集上测试不同组合:

from ultralytics import YOLO model = YOLO("best.pt") best_f1 = 0 best_params = {} for conf in [0.15, 0.2, 0.25, 0.3, 0.4]: for iou in [0.4, 0.5, 0.6, 0.7]: results = model.val(data="cat_dog.yaml", conf=conf, iou=iou) f1 = 2 * results.box.p.mean() * results.box.r.mean() / (results.box.p.mean() + results.box.r.mean()) if f1 > best_f1: best_f1 = f1 best_params = {"conf": conf, "iou": iou} print(f"最佳参数: {best_params}, F1: {best_f1:.3f}")

5.3 模型上线后的bad case收集与迭代

模型部署之后,一定要建立bad case收集机制。每次检测置信度低于某个阈值(比如0.3)或者用户手动标记错误的样本,都保存下来。这些样本就是下一轮迭代的训练数据。

我一般会维护一个"hard example"文件夹,定期把里面的图片标注好加入训练集重新训练。通常迭代2-3轮之后,模型在真实场景中的表现会有明显提升。这个过程不需要每次都从头训练,可以在之前的基础上做增量训练,学习率设小一点(比如0.001),训练20-30轮即可。

还有一个技巧是:把bad case按场景分类,看看是哪种场景下模型表现差。如果是夜间场景差,就补充夜间数据;如果是遮挡场景差,就补充遮挡数据。有针对性地补数据比盲目增加数据量有效得多。

5.4 多模型融合与TTA的性价比分析

如果对精度有极致要求,可以考虑多模型融合或者测试时增强(TTA)。多模型融合是把YOLOv8s、YOLOv8m、YOLOv8l的检测结果做加权融合,TTA是对同一张图做翻转、缩放等变换后分别推理再合并结果。

这两种方法都能提升精度,但代价是推理时间成倍增加。我实测下来,TTA能把mAP50提升1-2个百分点,但推理时间增加3倍。多模型融合提升2-3个百分点,推理时间增加2-3倍。对于大多数猫狗检测应用来说,这个性价比不高。除非你的场景对精度要求极高且对速度不敏感,否则不建议上这些方案。

更务实的做法是把单模型优化到位:数据质量做好、anchor调好、NMS参数调好,这些基础工作带来的提升往往比模型融合更明显,而且没有额外的推理开销。

提示:模型迭代是一个持续的过程,不要指望一次训练就达到完美效果。我的经验是,第一版模型解决80%的常见场景,然后通过bad case收集和增量训练,逐步覆盖剩下的20%长尾场景。这个过程通常需要2-3个月,但每轮迭代的成本很低,值得坚持做。

最后分享一个我在实际项目中总结的小技巧:训练猫狗检测模型时,可以在验证集里故意加入一些其他动物的图片(比如兔子、仓鼠),观察模型会不会误检。如果误检率高,说明模型学到的特征不够鲁棒,需要在训练数据里加入负样本。这个测试方法能提前暴露模型在真实场景中的泛化问题,比单纯看mAP值有用得多。

返回列表