ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

监控场景猫狗检测数据集:VOC/COCO/YOLO三格式+YOLO11跨平台训练

监控场景猫狗检测数据集:VOC/COCO/YOLO三格式+YOLO11跨平台训练 简介本资源是一份面向目标检测初学者与实战开发者的猫狗检测专用数据集及配套训练方案适用于监控场景下的动物识别项目开发、YOLO系列算法入门实践与多平台模型部署验证。数据集包含1000张真实场景高质量图像涵盖奔跑、睡觉、散步、坐卧等多种姿态及不同品种的猫狗样本标注采用labelimg完成提供VOCXML、COCOJSON、YOLOTXT三种主流格式开箱即用于各类目标检测框架训练。资源以单个PDF文件形式交付5.78MB内含数据集结构说明、标注样例截图、YOLO11一键训练脚本兼容GPU/GPUs、CPU及Mac M系列芯片、训练日志参考及百度网盘获取指引。目前已有738人学习下载可直接支撑从数据加载、环境配置到模型训练的完整流程显著降低跨平台部署门槛与标注格式转换成本。1. 猫狗检测不是练手玩具1000张真实监控场景图VOC/COCO/YOLO三格式齐备YOLO11一键训到Mac M3这数据集真能进产线你有没有试过在监控视频里跑YOLOv8结果猫一跃而起就消失、狗刚转头就漏检不是模型不行是训练数据太“干净”——全是宠物店摆拍、白底正脸、光照均匀。而这个猫狗检测数据集1000张图全来自真实监控视角走廊拐角蹲着的橘猫、玻璃门后窜过的边牧、楼梯阴影里半露的狗头、空调外机上打盹的英短……它不追求像素高清但死磕监控场景下最难搞的case低对比度、小目标32×32、遮挡笼子/门框/人腿、动态模糊奔跑尾巴拖影、多尺度幼犬vs成年德牧。更关键的是它没把VOC/COCO/YOLO三种格式当摆设——XML里带difficult和truncated字段JSON里image_id与file_name严格对齐YOLO txt里坐标已按图像宽高归一化且无越界值。附赠的YOLO11训练脚本也不是噱头它用torch.compile()适配M系列芯片的Metal Performance ShadersMPS后端CPU模式自动启用torch.backends.mkldnn.enabledTrueGPU版则默认开启cudnn.benchmarkTrue并校验CUDA_VISIBLE_DEVICES。这不是Kaggle式玩具数据集而是你明天就要部署到社区安防盒子、宠物医院AI巡检终端、智能猫砂盆识别模块里的最小可行产线数据集。2. VOC/COCO/YOLO三格式不是翻译游戏为什么必须同时提供且如何验证其一致性2.1 VOC格式XML结构里藏着监控场景的标注逻辑VOC格式看似简单但真实监控数据要求XML必须承载更多语义。该数据集的annotation根节点下除标准filename、size外强制包含segmented0/segmented明确声明未使用分割掩码避免YOLO用户误读object内嵌poseUnspecified/pose因监控视角无法定义物体朝向不填Frontal等误导性值truncated1/truncated字段仅在目标被画面边缘裁切时置1如狗头伸出画面而非所有小目标都标1difficult1/difficult仅用于极难定位目标如暗光下蜷缩的黑猫占比3%防止训练时被loss淹没验证脚本需检查三项硬约束所有bndbox中xmin xmax且ymin ymax排除labelimg误操作导致的坐标翻转xmax width且ymax height杜绝YOLO转换时因越界导致的负坐标同一图像的多个object标签中name值严格为cat或dog无kitten/puppy等子类保持二分类任务边界清晰# voc_consistency_check.py import xml.etree.ElementTree as ET from pathlib import Path def validate_voc_xml(xml_path: Path): tree ET.parse(xml_path) root tree.getroot() size root.find(size) width int(size.find(width).text) height int(size.find(height).text) for obj in root.findall(object): bndbox obj.find(bndbox) xmin int(bndbox.find(xmin).text) xmax int(bndbox.find(xmax).text) ymin int(bndbox.find(ymin).text) ymax int(bndbox.find(ymax).text) # 检查坐标逻辑 assert xmin xmax, fInvalid xmin/xmax in {xml_path} assert ymin ymax, fInvalid ymin/ymax in {xml_path} assert 0 xmin width and 0 xmax width, fX out of bounds in {xml_path} assert 0 ymin height and 0 ymax height, fY out of bounds in {xml_path} # 检查类别 name obj.find(name).text assert name in [cat, dog], fUnknown class {name} in {xml_path} # 批量验证 for xml in Path(VOC/Annotations).glob(*.xml): validate_voc_xml(xml)提示该脚本应作为数据集交付前的CI步骤。若发现difficult字段批量为1说明标注员将小目标误判为困难样本——需重新抽样审核否则模型会学习到“小目标忽略”的错误先验。2.2 COCO格式JSON里categories与annotations的双向绑定陷阱COCO格式的坑不在结构复杂而在ID映射的隐式耦合。该数据集categories数组严格定义为categories: [ {id: 1, name: cat, supercategory: animal}, {id: 2, name: dog, supercategory: animal} ]而每个annotation对象中category_id必须为1或2且image_id必须存在于images数组中对应id字段。常见翻车点是导出时image_id用文件名哈希生成但images数组里file_name却保留原始名称如IMG_001.jpg导致coco.loadImgs()返回空列表。验证关键逻辑遍历所有annotations提取唯一image_id集合A遍历所有images提取id集合B断言A B否则coco_api初始化失败对每个annotation检查category_id是否在categories的id列表中# coco_consistency_check.py import json from pathlib import Path def validate_coco_json(json_path: Path): with open(json_path) as f: coco json.load(f) # 构建ID映射 image_ids {img[id] for img in coco[images]} ann_image_ids {ann[image_id] for ann in coco[annotations]} category_ids {cat[id] for cat in coco[categories]} # 双向ID校验 assert image_ids ann_image_ids, fImage ID mismatch in {json_path} assert all(ann[category_id] in category_ids for ann in coco[annotations]), \ fInvalid category_id in {json_path} # 检查bbox格式COCO要求[x,y,width,height]且全部0 for ann in coco[annotations]: bbox ann[bbox] assert len(bbox) 4 and all(x 0 for x in bbox), \ fInvalid bbox format in {json_path}: {bbox} validate_coco_json(Path(COCO/annotations/instances_train.json))2.3 YOLO格式txt文件里隐藏的归一化玄学YOLO格式表面最简单class_id center_x center_y width height但监控场景下极易踩坑归一化基准错乱必须用原图width/height归一化而非resize后尺寸该数据集所有YOLO txt均基于原始分辨率计算坐标越界center_x或center_y超出[0,1]即无效常见于labelimg缩放标注后未重算小目标截断当width或height 0.005约16px3200px宽图YOLOv8默认丢弃但该数据集保留并标记is_tiny: True在文件名后缀如IMG_001_tiny.txt验证脚本需捕获三类异常行数不匹配xxx.txt行数 ≠xxx.xml中object数量归一化溢出任一坐标值 ∉ [0,1]类别越界class_id≠ 0cat或1dog# yolo_consistency_check.py from pathlib import Path def validate_yolo_txt(txt_path: Path, img_width: int, img_height: int): with open(txt_path) as f: lines [l.strip() for l in f if l.strip()] # 检查行数应与VOC中object数量一致 xml_path Path(VOC/Annotations) / (txt_path.stem .xml) if xml_path.exists(): import xml.etree.ElementTree as ET tree ET.parse(xml_path) xml_obj_count len(tree.findall(object)) assert len(lines) xml_obj_count, fLine count mismatch: {txt_path} # 检查每行坐标 for i, line in enumerate(lines): parts line.split() assert len(parts) 5, fInvalid format at line {i} in {txt_path} cls_id, cx, cy, w, h map(float, parts) assert cls_id in [0, 1], fInvalid class_id {cls_id} at line {i} in {txt_path} assert 0 cx 1 and 0 cy 1, fCenter out of bounds at line {i} in {txt_path} assert 0 w 1 and 0 h 1, fSize out of bounds at line {i} in {txt_path} # 批量验证需传入对应图像尺寸 for txt in Path(YOLO/labels/train).glob(*.txt): # 从VOC XML获取原始尺寸 xml_path Path(VOC/Annotations) / (txt.stem .xml) if xml_path.exists(): import xml.etree.ElementTree as ET tree ET.parse(xml_path) size tree.find(size) w int(size.find(width).text) h int(size.find(height).text) validate_yolo_txt(txt, w, h)2.4 三格式一致性验证用Python构建跨格式校验流水线真正可靠的验证不是单点检查而是建立跨格式锚点比对。核心思路以VOC XML为黄金标准抽取每个object的bndbox坐标反向推算其在COCO JSON和YOLO txt中的理论值再与实际文件比对。# cross_format_validator.py import xml.etree.ElementTree as ET import json from pathlib import Path def get_voc_boxes(xml_path: Path): 从VOC XML提取所有bbox归一化到[0,1] tree ET.parse(xml_path) root tree.getroot() size root.find(size) width int(size.find(width).text) height int(size.find(height).text) boxes [] for obj in root.findall(object): bndbox obj.find(bndbox) xmin int(bndbox.find(xmin).text) / width xmax int(bndbox.find(xmax).text) / width ymin int(bndbox.find(ymin).text) / height ymax int(bndbox.find(ymax).text) / height # 转YOLO格式[center_x, center_y, width, height] cx (xmin xmax) / 2 cy (ymin ymax) / 2 w xmax - xmin h ymax - ymin boxes.append((cx, cy, w, h)) return boxes def get_coco_boxes(json_path: Path, image_id: int): 从COCO JSON提取指定image_id的所有bbox已归一化 with open(json_path) as f: coco json.load(f) # 获取图像宽高 img_info next(img for img in coco[images] if img[id] image_id) width, height img_info[width], img_info[height] # 提取该图所有标注 anns [a for a in coco[annotations] if a[image_id] image_id] boxes [] for ann in anns: x, y, w, h ann[bbox] # COCO bbox为[x,y,width,height]需归一化 boxes.append(( (x w/2) / width, (y h/2) / height, w / width, h / height )) return boxes def get_yolo_boxes(txt_path: Path): 从YOLO txt读取所有bbox boxes [] with open(txt_path) as f: for line in f: if not line.strip(): continue parts line.strip().split() _, cx, cy, w, h map(float, parts) boxes.append((cx, cy, w, h)) return boxes # 执行校验 xml_path Path(VOC/Annotations/IMG_001.xml) voc_boxes get_voc_boxes(xml_path) # YOLO校验 yolo_path Path(YOLO/labels/train/IMG_001.txt) yolo_boxes get_yolo_boxes(yolo_path) # COCO校验需先知image_id此处假设为1 coco_path Path(COCO/annotations/instances_train.json) coco_boxes get_coco_boxes(coco_path, image_id1) # 逐个比对容忍浮点误差±1e-4 for i, (voc, yolo, coco) in enumerate(zip(voc_boxes, yolo_boxes, coco_boxes)): for j, (v, y, c) in enumerate(zip(voc, yolo, coco)): assert abs(v - y) 1e-4, fYOLO mismatch at box{i} coord{j} assert abs(v - c) 1e-4, fCOCO mismatch at box{i} coord{j}注意此校验必须在数据集交付前运行。曾有团队因COCO导出时未同步更新images数组的width/height字段导致YOLO训练时mAP暴跌12%——问题根源是COCO bbox归一化用了错误的分母。3. YOLO11一键训练脚本不是封装命令而是平台感知的自适应执行引擎3.1 脚本架构设计三层决策树解决平台异构性YOLO11训练脚本train_yolo11.sh的核心不是写死python train.py --device 0而是构建硬件能力探测→框架后端选择→超参微调的决策链探测层检查项触发动作硬件层nvidia-smi是否存在、system_profiler SPHardwareDataType输出含Chip: Apple M、lscpu | grep CPU\(s\)\?:\s*[0-9]\识别GPU/CPU/Mac平台框架层python -c import torch; print(torch.cuda.is_available())、python -c import torch; print(hasattr(torch, mps) and torch.backends.mps.is_available())确认CUDA/MPS/CPUBackend可用性配置层nproc核数、free -g | awk NR2{print $2}内存、nvidia-smi --query-gpumemory.total --formatcsv,noheader,nounits显存动态设置--workers、--batch-size、--imgsz脚本启动时执行# train_yolo11.sh 核心逻辑节选 detect_platform() { if command -v nvidia-smi /dev/null; then echo gpu elif system_profiler SPHardwareDataType 2/dev/null | grep -q Chip: Apple M; then echo mac else echo cpu fi } PLATFORM$(detect_platform) case $PLATFORM in gpu) DEVICE_FLAG--device 0 BATCH_SIZE32 WORKERS8 ;; mac) DEVICE_FLAG--device mps BATCH_SIZE16 # MPS内存带宽限制 WORKERS4 # M系列CPU核心数通常≤8 ;; cpu) DEVICE_FLAG--device cpu BATCH_SIZE8 # 避免OOM WORKERS2 ;; esac # 自动启用torch.compileYOLO11专属优化 if [ $PLATFORM mac ] || [ $PLATFORM gpu ]; then COMPILE_FLAG--compile else COMPILE_FLAG fi python train.py \ --data data.yaml \ --weights yolov11n.pt \ --epochs 100 \ --batch-size $BATCH_SIZE \ $DEVICE_FLAG \ --workers $WORKERS \ $COMPILE_FLAG \ --project runs/train_yolo11_${PLATFORM}3.2 GPU模式CUDA_VISIBLE_DEVICES与cudnn.benchmark的协同陷阱GPU训练最易忽视的是多卡环境下的设备可见性与cudnn优化冲突。该脚本强制要求若用户设置CUDA_VISIBLE_DEVICES1,2脚本自动将--device改为1,2而非默认0cudnn.benchmarkTrue仅在--imgsz固定时启用监控场景常用640×640故默认开启显存不足时自动降级检测到OOM后脚本重启并设置--batch-size $(($BATCH_SIZE/2))最多尝试3次# train.py 中的关键补丁YOLO11专用 import os import torch import warnings def setup_device(): device_flag parse_args().device if device_flag mps: if not torch.backends.mps.is_available(): raise SystemExit(MPS not available on this Mac) return torch.device(mps) elif device_flag cpu: return torch.device(cpu) else: # 处理CUDA_VISIBLE_DEVICES visible_devices os.environ.get(CUDA_VISIBLE_DEVICES, ).strip() if visible_devices: # 将1,2映射为[1,2]供torch.device使用 device_ids [int(x) for x in visible_devices.split(,)] if len(device_ids) 1: return torch.device(fcuda:{device_ids[0]}) # 主卡 else: return torch.device(fcuda:{device_ids[0]}) else: return torch.device(cuda:0) def setup_cudnn(): if torch.cuda.is_available(): torch.backends.cudnn.benchmark True # 加速固定尺寸推理 torch.backends.cudnn.deterministic False # 允许非确定性算法提升速度 # 关键禁用cudnn.convolution.benchmarkYOLO11中易导致显存泄漏 torch.backends.cudnn.enabled True3.3 Mac模式MPS后端的三个致命细节Apple Silicon训练不是简单替换--device mps该脚本针对M系列芯片做了三处硬编码修复Metal缓存清理每次训练前执行xcrun metal -version触发缓存重建避免MTLCreateSystemDefaultDevice返回nil梯度裁剪绕过MPS不支持torch.nn.utils.clip_grad_norm_脚本自动替换为torch.nn.utils.clip_grad_value_阈值设为1.0Dataloader pin_memory禁用MPS不兼容pin_memoryTrue脚本强制设为False并警告# mac_specific_fixes.py import torch def apply_mac_fixes(): if torch.backends.mps.is_available(): # 1. 清理Metal缓存必须在torch.device(mps)前执行 import subprocess subprocess.run([xcrun, metal, -version], capture_outputTrue) # 2. 替换梯度裁剪 from ultralytics.utils.torch_utils import clip_gradients def clip_gradients_mps(model, max_norm1.0): torch.nn.utils.clip_grad_value_(model.parameters(), max_norm) # 注入YOLO11训练循环 # 3. 强制DataLoader参数 from torch.utils.data import DataLoader original_init DataLoader.__init__ def patched_init(self, *args, **kwargs): kwargs[pin_memory] False original_init(self, *args, **kwargs) DataLoader.__init__ patched_init3.4 CPU模式MKLDNN加速与NUMA绑定的实战配置CPU训练常被当成备选方案但该脚本将其视为监控边缘设备主力如Intel NUC部署。关键优化启用torch.backends.mkldnn.enabledTrueYOLO11默认关闭脚本强制开启使用numactl绑定到本地内存节点numactl --cpunodebind0 --membind0 python train.py...--workers动态计算min(32, os.cpu_count() // 2)避免超线程争抢# cpu_optimized_launch.sh if command -v numactl /dev/null; then # 检测NUMA节点数 NODES$(numactl --hardware | grep available: | awk {print $2}) if [ $NODES -gt 1 ]; then NUMA_CMDnumactl --cpunodebind0 --membind0 else NUMA_CMD fi else NUMA_CMD fi $NUMA_CMD python train.py \ --device cpu \ --workers $(($(nproc)//2)) \ --batch-size 8 \ --imgsz 640 \ --optimizer adamw \ --lr0 0.001 \ --project runs/train_yolo11_cpu4. 避坑指南YOLO11训练中90%的失败源于这5个监控场景特有陷阱4.1 现象训练Loss震荡剧烈Val mAP始终低于15%原因监控数据中小目标32px占比超40%但YOLO11默认--imgsz 640导致小目标在特征图上仅剩1-2个像素FPN无法有效提取特征。解决启用--multi-scaleYOLO11默认关闭训练时随机缩放输入尺寸512~768在data.yaml中增加mosaic: 0.5降低马赛克增强强度避免小目标被过度扭曲修改YOLO11的Detect头添加nn.Upsample(scale_factor2)对P3特征图上采样# data.yaml 关键修改 train: ../YOLO/images/train val: ../YOLO/images/val nc: 2 names: [cat, dog] mosaic: 0.5 # 原默认1.0监控场景需降低4.2 现象Mac M2训练10轮后显存占用飙升至24GB超物理内存原因MPS后端的torch.compile()在YOLO11的Detect.forward中生成过多内核缓存且未自动清理。解决训练脚本中插入torch._dynamo.reset()每5个epoch执行一次禁用--compile对Detect模块仅对Backbone启用设置环境变量PYTORCH_MPS_HIGH_WATERMARK_RATIO0.0强制禁用缓存# train_yolo11.sh 中的Mac专属修复 if [ $PLATFORM mac ]; then export PYTORCH_MPS_HIGH_WATERMARK_RATIO0.0 # 在训练循环中每5轮插入 if [ $EPOCH -ne 0 ] [ $((EPOCH % 5)) -eq 0 ]; then python -c import torch; torch._dynamo.reset() fi fi4.3 现象GPU训练时nvidia-smi显示显存占用100%但gpustat报告GPU利用率5%原因监控数据中大量图像宽高比极端如走廊长条图1920×108YOLO11的LetterBox预处理生成巨大填充区域显存被浪费。解决替换LetterBox为InferenceResize保持宽高比缩放不填充在val.py中设置rectTrue启用矩形推理YOLO11默认False使用--imgsz 1280替代640减少填充比例# utils/autobatch.py 中的修复 class InferenceResize: def __init__(self, new_shape(640, 640)): self.h, self.w new_shape def __call__(self, im): h0, w0 im.shape[:2] r min(self.h / h0, self.w / w0) # 保持宽高比 h, w int(h0 * r), int(w0 * r) im_resized cv2.resize(im, (w, h)) return im_resized # 无padding4.4 现象CPU训练时top显示CPU占用率100%但训练速度比GPU慢10倍原因YOLO11默认--workers 8在4核CPU上引发严重进程争抢且cv2.imread()在多进程下存在GIL锁死。解决--workers设为min(4, os.cpu_count()//2)替换cv2.imread为PIL.Image.open().convert(RGB)YOLO11中修改dataset.py启用--cache ram将图像缓存到内存需≥32GB RAM# datasets.py 中的CPU优化 from PIL import Image import numpy as np def load_image(self, i): # 原cv2.imread替换为PIL f self.im_files[i] im Image.open(f).convert(RGB) im np.array(im) # RGB to BGR for OpenCV compatibility return im4.5 现象训练日志显示Class accuracy: cat92%, dog38%严重类别不平衡原因监控场景中猫出现频次远高于狗如家庭摄像头但数据集未做类别权重平衡。解决在train.py中计算class_weights compute_class_weight(balanced, classesnp.arange(2), ytrain_labels)将权重注入nn.CrossEntropyLoss(weightclass_weights)对YOLO11的BCELoss在loss.py中为obj_loss和cls_loss分别加权# loss.py 中的类别加权 class ComputeLoss: def __init__(self, model, autobalanceFalse): # ...原有代码 # 新增类别权重 self.cls_weights torch.tensor([0.4, 0.6]).to(device) # cat权重低dog权重高 def __call__(self, p, targets): # ...原有代码 cls_loss self.BCEcls(pcls, tcls) * self.cls_weights[tcls] # 按目标类别索引加权5. 监控场景落地技巧用YOLO11的val模块做实时漏检归因分析5.1 构建漏检热力图定位监控盲区的物理坐标单纯看mAP无法指导硬件部署。该数据集配套的val_yolo11.py脚本可生成漏检热力图将漏检目标映射回监控画面物理位置# val_yolo11.py 核心逻辑 def generate_miss_heatmap(model, dataloader, output_dir): # 初始化热力图与原始图像同尺寸 heatmap np.zeros((1080, 1920)) # 假设监控分辨率为1920×1080 for batch_i, (imgs, targets, paths, shapes) in enumerate(dataloader): preds model(imgs) # 获取漏检目标GT有框pred无框IoU0.5 for i, (pred, target, path) in enumerate(zip(preds, targets, paths)): img_h, img_w shapes[i][0] # 将target坐标还原到原始尺寸 target_orig target.clone() target_orig[:, 1::2] * img_w target_orig[:, 2::2] * img_h # 计算pred与target的IoU矩阵 iou_matrix box_iou(pred[:, :4], target_orig[:, 1:5]) # 漏检target无匹配predIoU.max(dim0) 0.5 miss_mask iou_matrix.max(dim0).values 0.5 miss_targets target_orig[miss_mask] # 将漏检坐标累加到热力图 for tx, ty, tw, th in miss_targets[:, 1:]: cx, cy tx tw/2, ty th/2 # 映射到1920×1080画布双线性插值 x_idx int(np.clip(cx * 1920 / img_w, 0, 1919)) y_idx int(np.clip(cy * 1080 / img_h, 0, 1079)) heatmap[y_idx, x_idx] 1 # 保存热力图 plt.imshow(heatmap, cmaphot, interpolationbilinear) plt.savefig(f{output_dir}/miss_heatmap.png)效果输出miss_heatmap.png中红色密集区即为监控盲区如走廊尽头、天花板角落。物业可据此调整摄像头俯仰角或增补设备。5.2 时间维度分析用--conf 0.3挖掘低置信度漏检模式监控场景中模型常在特定时段漏检如傍晚光线变化时。脚本支持--time-analysis参数自动按小时分组统计时间段漏检率主要漏检类型建议措施06:00-08:0024%蹲姿猫低对比度启用CLAHE增强12:00-14:0018%窗边狗强光反射添加RandomBrightnessContrast18:00-20:0031%运动模糊狗增加MotionBlur增强# 启用时间分析 python val_yolo11.py \ --weights runs/train_yolo11_gpu/weights/best.pt \ --data data.yaml \ --imgsz 640 \ --conf 0.3 \ # 降低置信度阈值捕获更多潜在漏检 --time-analysis \ --project runs/val_time_analysis5.3 硬件部署验证用export.py生成TensorRT引擎并校验精度损失YOLO11训练完必须验证部署精度。该数据集提供export_trt.py一键生成TensorRT引擎并比对# export_trt.py import tensorrt as trt import pycuda.autoinit import numpy as np def build_engine(onnx_path, engine_path, input_shape(1,3,640,640)): # 创建TensorRT Builder logger trt.Logger(trt.Logger.WARNING) builder trt.Builder(logger) network builder.create_network(1 int(trt.NetworkDefinitionCreationFlag.EXPLICIT_BATCH)) parser trt.OnnxParser(network, logger) # 解析ONNX with open(onnx_path, rb) as f: if not parser.parse(f.read()): for error in range(parser.num_errors): print(parser.get_error(error)) # 构建引擎 config builder.create_builder_config() config.max_workspace_size 1 30 # 1GB engine builder.build_engine(network, config) # 保存引擎 with open(engine_path, wb) as f: f.write(engine.serialize()) # 精度校验随机采样100张图比对TRT与PyTorch输出 trt_outputs run_trt_inference(engine, sample_images) pt_outputs run_pt_inference(model, sample_images) mae np.mean(np.abs(trt_outputs - pt_outputs)) assert mae 0.01, fTRT precision loss too high: {mae}5.4 从那以后我每次部署监控AI都强制走一遍漏检热力图时间分析TRT精度校验三连不是因为流程规范而是吃过太多亏去年在社区养老院部署时只看了整体mAP82%上线后护工反馈“总在拐角处漏检流浪猫”热力图立刻暴露是走廊尽头15°仰角导致的透视畸变今年初给宠物医院做室内监控时间分析发现13:00-14:00漏检率飙升追查发现是午休时空调直吹摄像头镜头产生雾气——这些细节永远藏在m本文还有配套的精品资源点击获取
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进