公司动态
基于YOLO的人群计数实战:从原理到部署的完整指南
简介目标检测是计算机视觉的核心任务之一旨在识别图像中的物体并定位其位置。其原理是通过深度学习模型学习图像特征预测物体的边界框和类别。这项技术具有巨大的应用价值是实现自动化感知和理解的关键。在安防监控、智慧零售、交通管理等实际场景中对人群进行快速、准确的计数是普遍需求。传统方法在密集、遮挡等复杂环境下效果有限。本文聚焦于利用YOLO这一高效的单阶段目标检测算法解决人群计数这一具体问题。通过介绍YOLO的设计哲学、模型训练、推理优化及生产部署的全流程为开发者提供从概念到工程实践的完整路径帮助实现实时、鲁棒的人群统计应用。1. 项目概述从“数人头”到智能感知“数人头”这件事听起来简单但在实际场景中却是个老大难问题。无论是大型商超评估客流热力、交通枢纽监测人流密度、还是大型活动保障公共安全传统的人工计数或基于简单图像处理的方法要么成本高昂、误差大要么在复杂场景下如遮挡、光照变化、人群密集完全失效。这正是“基于YOLO的人群计数实现”这个项目要解决的核心痛点。简单来说这个项目就是利用当前在目标检测领域堪称“瑞士军刀”的YOLOYou Only Look Once算法来自动、实时、准确地检测并统计图像或视频画面中的人数。YOLO以其惊人的速度和不错的精度让在普通计算设备甚至是一些边缘计算设备上运行实时人群计数成为可能。这不仅仅是技术上的一个实现更是将前沿的计算机视觉能力落地到安防、零售、智慧城市等众多关乎效率与安全的具体业务中。对于开发者而言这个项目是一个绝佳的入门到精通的实践路径。你将亲历从环境搭建、数据准备、模型训练或使用预训练模型、到最终部署推理的完整机器学习Pipeline。过程中你会深刻理解目标检测的基本原理、YOLO网络的设计哲学、以及如何针对“人群”这个特定目标进行优化和调参。无论你是计算机视觉的初学者想通过一个有趣的项目练手还是有一定经验的工程师需要为实际业务构建一个可靠的人群统计模块这个项目都能提供扎实的参考和清晰的实现路径。2. 核心思路与方案选型为什么是YOLO当我们决定用深度学习来做人群计数时摆在面前的有几条主流技术路线。理解为什么最终选择YOLO是理解整个项目架构的第一步。2.1 人群计数的技术路线对比传统的人群计数方法如基于检测的滑动窗口HOG特征或者基于回归的MCNN多列卷积神经网络各有其局限性。前者在密集场景下检测框重叠严重精度骤降后者直接学习从图像到人数的映射虽然避免了检测框但丢失了每个人的位置信息无法进行更细粒度的分析如人群分布热力图。而基于深度学习的目标检测算法尤其是单阶段one-stage检测器成为了更优的选择。它们能在单次前向传播中同时预测出图中所有行人的边界框和类别置信度。在主流单阶段检测器中YOLO系列因其在速度和精度之间取得的卓越平衡而脱颖而出。2.2 YOLO的独特优势与版本选择YOLO的核心思想是将图像划分成SxS的网格每个网格负责预测中心点落在该网格内的物体。这种“看一次”就出结果的设计使其天生具有极快的推理速度。对于人群计数这种常常需要处理视频流、要求实时或准实时响应的场景速度是至关重要的指标。一个在服务器上需要好几秒才能处理一帧的算法是无法用于实时监控的。目前YOLO系列已迭代至v11版本由Ultralytics公司维护。对于本项目我们有几种选择YOLOv5/v8生态成熟社区资源丰富预训练模型多易于上手和部署。尤其是YOLOv8提供了分类、检测、分割、姿态估计等多种任务支持其检测模型在精度和速度上表现非常均衡。YOLOv11最新版本通常包含了最新的架构优化和训练技巧可能在某些指标上更优。但新版本的社区沉淀和踩坑记录相对较少。实操心得对于大多数入门和工业应用场景我强烈推荐从YOLOv8开始。它的API设计非常友好文档清晰并且其detect模型在COCO等通用数据集上表现已经足够好我们可以直接在其基础上进行微调Fine-tuning。选择v8能在开发效率、资源获取和最终效果之间取得最佳平衡。本项目的后续实操也将以YOLOv8为例展开。2.3 项目整体流程设计基于以上分析我们确定的核心实现路径如下环境准备搭建Python、PyTorch、Ultralytics YOLO等必要的软件环境。数据准备与处理收集或获取带标注的行人数据集并将其转换为YOLO所需的格式通常是txt文件存储归一化后的中心坐标和宽高。模型选择与配置选择YOLOv8的预训练模型如yolov8n.pt,yolov8s.pt等nano和small版本适合轻量部署并根据数据集配置数据加载路径和模型参数。模型训练与验证在自有数据集上对预训练模型进行微调使用验证集监控性能防止过拟合。模型推理与计数加载训练好的最佳模型对图像或视频流进行推理解析检测结果并实现计数逻辑。优化与部署考虑模型量化、TensorRT加速、OpenVINO部署等方案以满足实际生产环境对速度和资源的要求。这个流程形成了一个完整的闭环从数据到模型再到应用。3. 环境搭建与数据准备万事开头难3.1 开发环境配置详解一个稳定、一致的环境是项目成功的基石。为了避免后续出现各种诡异的版本冲突问题建议使用Conda或Venv创建独立的Python环境。# 1. 创建并激活conda环境推荐 conda create -n yolo_counting python3.9 conda activate yolo_counting # 2. 安装PyTorch请根据你的CUDA版本前往PyTorch官网获取对应命令 # 例如对于CUDA 11.8 pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118 # 3. 安装Ultralytics YOLOv8 pip install ultralytics # 4. 安装其他可能用到的工具库 pip install opencv-python matplotlib pandas seaborn tqdm注意事项PyTorch的版本必须与你的CUDA驱动版本匹配。使用nvidia-smi查看CUDA版本。如果不使用GPU可以安装CPU版本的PyTorch但训练速度会非常慢仅适用于推理测试。验证安装是否成功import torch print(torch.__version__) print(torch.cuda.is_available()) # 输出True则表示GPU可用 from ultralytics import YOLO print(YOLO) # 无报错即表示ultralytics安装成功3.2 数据集获取与格式解析数据是模型的“粮食”。对于人群计数我们需要的是包含行人、并且标注了边界框Bounding Box的数据集。常用公开数据集COCO (Common Objects in Context):包含80个类别其中‘person’类别标注质量高、场景丰富是极佳的预训练和微调数据源。CrowdHuman:专门针对密集人群的数据集标注非常精细包含可见框和全身框是研究人群计数的顶级数据集。VisDrone, UAVDT:无人机视角的数据集适合特定场景。自建数据集使用标注工具如LabelImg、CVAT、Roboflow对业务场景下的图片进行标注。YOLO格式解析YOLO要求每个图像对应一个同名的.txt标注文件。文件每一行代表一个物体格式为class_id x_center y_center width heightclass_id: 类别索引对于纯人群计数通常只有0代表‘person’。x_center, y_center: 边界框中心点的x、y坐标已归一化即除以图像宽度和高度取值范围0~1。width, height: 边界框的宽度和高度同样已归一化。例如一张500x300的图片上有一个行人其边界框左上角为(100,50)右下角为(200,180)则宽: 200-100100 高: 180-50130中心x: (100 100/2) / 500 0.3中心y: (50 130/2) / 300 ≈ 0.3833归一化宽: 100/5000.2归一化高: 130/300≈0.4333 标注行即为0 0.3 0.3833 0.2 0.4333数据集目录结构datasets/ ├── crowd_counting/ │ ├── images/ │ │ ├── train/ │ │ │ ├── img1.jpg │ │ │ └── ... │ │ └── val/ │ │ ├── img2.jpg │ │ └── ... │ └── labels/ │ ├── train/ │ │ ├── img1.txt │ │ └── ... │ └── val/ │ ├── img2.txt │ └── ...3.3 数据增强策略人群场景复杂多变直接使用原始数据训练容易导致模型过拟合泛化能力差。YOLOv8内置了强大的数据增强功能我们需要根据人群特点进行配置。在数据配置YAML文件中如data/custom.yaml可以指定增强参数# data/custom.yaml path: /path/to/datasets/crowd_counting train: images/train val: images/val # 类别名 names: 0: person # 增强参数 (在训练命令中通过augmentTrue启用也可在此细调) # 以下是一些针对人群场景可能有用的增强建议 # hsv_h: 0.015 # 色调增强模拟不同光照 # hsv_s: 0.7 # 饱和度增强 # hsv_v: 0.4 # 明度增强 # translate: 0.2 # 平移模拟视角变化 # scale: 0.9 # 缩放模拟远近不同的人 # mosaic: 1.0 # 马赛克增强对小目标和密集目标很有效 # mixup: 0.5 # MixUp增强提高泛化性对于密集人群mosaic和mixup增强能极大地提升模型在复杂场景下的鲁棒性但可能会增加训练时间。4. 模型训练与调优让模型学会“看人”4.1 模型选择与初始化YOLOv8提供了不同大小的模型从轻量到重型满足不同需求yolov8n.pt(nano): 参数量最小速度最快适合移动端或边缘设备。yolov8s.pt(small): 平衡了速度和精度是许多应用的首选。yolov8m.pt(medium)yolov8l.pt(large)yolov8x.pt(extra large): 精度最高但速度最慢参数量最大。我们使用Ultralytics的简洁API加载预训练模型并开始训练from ultralytics import YOLO # 加载一个预训练模型 model YOLO(yolov8s.pt) # 这里选择small版本 # 开始训练 results model.train( datadata/custom.yaml, # 数据配置路径 epochs100, # 训练轮数 imgsz640, # 输入图像尺寸 batch16, # 批次大小根据GPU内存调整 workers4, # 数据加载线程数 device0, # 使用GPU 0如果是CPU则设为cpu projectruns/train, # 结果保存目录 nameexp1, # 实验名称 pretrainedTrue, # 使用预训练权重 optimizerAdamW, # 优化器 lr00.01, # 初始学习率 augmentTrue, # 启用数据增强 patience20, # 早停耐心值若精度在20轮内无提升则停止 save_period10, # 每10轮保存一次检查点 )4.2 关键超参数解析与调优经验训练过程中的超参数对最终模型性能有决定性影响。以下是一些核心参数及其调优思路imgsz(图像尺寸):默认640。增大尺寸如1280可以提升对小目标的检测能力远处的小人但会显著增加显存消耗和训练时间。如果场景中行人普遍较小可以尝试增大尺寸。batch(批次大小):在GPU显存允许范围内尽可能设大。大的批次能使梯度更新更稳定。如果出现内存不足OOM错误首先尝试减小imgsz或batch。lr0(初始学习率):0.01是一个不错的起点。如果训练损失震荡剧烈或下降很慢可以尝试调低如0.001。YOLOv8内置了学习率调度器通常无需手动调整。optimizer(优化器):SGD和AdamW是主流选择。SGD配合动量momentum通常能获得更好的最终精度但可能需要更精细的学习率调整。AdamW收敛更快对初始学习率不那么敏感更适合快速实验。patience(早停):防止过拟合的重要工具。如果验证集指标如mAP0.5连续多轮没有提升训练会自动停止并恢复到最佳模型。实操心得我的经验是对于人群检测mosaic增强和适当的imgsz增大带来的收益往往比盲目调整学习率更大。首先确保你的数据增强是有效的然后再去微调学习率等参数。训练时务必监控验证集的损失和mAP这是判断模型是否在“学习”而非“记忆”的关键。4.3 训练过程监控与评估训练开始后Ultralytics会实时输出日志并在runs/train/exp1目录下生成大量有用文件weights/best.pt: 验证集上表现最好的模型权重。weights/last.pt: 最后一轮的模型权重。args.yaml: 本次训练的所有参数配置。results.csv: 每轮训练的详细指标记录。events.out.tfevents.*: TensorBoard日志文件。使用TensorBoard可视化训练过程tensorboard --logdir runs/train在浏览器中打开localhost:6006你可以看到损失曲线、精度曲线、学习率变化等非常直观。评估模型性能训练完成后使用最佳模型在验证集上进行评估model YOLO(runs/train/exp1/weights/best.pt) metrics model.val() # 在验证集上评估 print(metrics.box.map) # 打印mAP0.5 print(metrics.box.map50) # 打印mAP0.5:0.95关键指标是mAP0.5(mean Average Precision)它综合衡量了模型在不同置信度阈值下的检测精度。对于人群计数我们还应关注召回率Recall因为漏检False Negative比误检False Positive对计数准确性的影响通常更大。5. 推理实现与计数逻辑从检测框到数字训练出模型只是第一步如何用它来稳定、准确地计数才是项目的最终目标。5.1 单张图片推理与结果解析from ultralytics import YOLO import cv2 # 加载训练好的模型 model YOLO(runs/train/exp1/weights/best.pt) # 读取图片 img_path test_image.jpg image cv2.imread(img_path) # 进行推理 results model(image, conf0.25, iou0.45) # conf: 置信度阈值 iou: NMS阈值 # 解析结果 result results[0] # 因为只有一张图取第一个结果 boxes result.boxes # 检测框信息 # 获取所有检测到的行人框 if boxes is not None: # boxes.data 是一个Tensor包含 [x1, y1, x2, y2, conf, cls] detections boxes.data.cpu().numpy() person_count len(detections) print(f检测到行人数量: {person_count}) # 可视化在图像上绘制框和标签 for det in detections: x1, y1, x2, y2, conf, cls_id det # 绘制矩形框 cv2.rectangle(image, (int(x1), int(y1)), (int(x2), int(y2)), (0, 255, 0), 2) # 添加置信度标签 label fperson {conf:.2f} cv2.putText(image, label, (int(x1), int(y1)-10), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0,255,0), 2) else: person_count 0 print(未检测到行人) # 显示或保存结果 cv2.imshow(Result, image) cv2.waitKey(0) cv2.destroyAllWindows() # cv2.imwrite(result.jpg, image)5.2 视频流实时计数将上述逻辑嵌入到视频流循环中即可实现实时计数。这里以摄像头为例import cv2 from ultralytics import YOLO import time model YOLO(runs/train/exp1/weights/best.pt) cap cv2.VideoCapture(0) # 0代表默认摄像头 # 设置视频写入可选 frame_width int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)) frame_height int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)) fps cap.get(cv2.CAP_PROP_FPS) # out cv2.VideoWriter(output.avi, cv2.VideoWriter_fourcc(*XVID), fps, (frame_width, frame_height)) prev_time 0 while cap.isOpened(): success, frame cap.read() if not success: break # 推理 results model(frame, conf0.25, iou0.45, verboseFalse) # verboseFalse关闭控制台输出 result results[0] boxes result.boxes count 0 if boxes is not None: detections boxes.data.cpu().numpy() count len(detections) # 绘制检测框可选影响帧率 for det in detections: x1, y1, x2, y2, conf, cls_id det cv2.rectangle(frame, (int(x1), int(y1)), (int(x2), int(y2)), (0, 255, 0), 2) # 计算并显示FPS curr_time time.time() fps 1 / (curr_time - prev_time) if prev_time 0 else 0 prev_time curr_time cv2.putText(frame, fFPS: {fps:.1f}, (10, 30), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 255, 0), 2) # 显示计数结果 cv2.putText(frame, fCount: {count}, (10, 70), cv2.FONT_HERSHEY_SIMPLEX, 1, (0, 0, 255), 2) cv2.imshow(YOLO People Counting, frame) # out.write(frame) if cv2.waitKey(1) 0xFF ord(q): break cap.release() # out.release() cv2.destroyAllWindows()5.3 计数逻辑的优化与陷阱简单的框数量统计在大多数情况下是有效的但在复杂场景下会面临挑战遮挡问题严重遮挡会导致一个人被检测成多个部分如头、身体分开从而被重复计数。优化思路使用更小的iou阈值进行非极大值抑制NMS或者采用更先进的检测后处理算法如Soft-NMS。对于固定摄像头场景可以引入跟踪算法如ByteTrack, DeepSORT通过ID关联来避免同一人的重复计数。小目标漏检远处或密集处的人像可能只有几十像素容易漏检。优化思路训练时使用更大的输入分辨率imgsz或使用专门针对小目标优化的YOLO变体如YOLO-Fine。推理时可以对图像进行多尺度或切片slice推理但会牺牲速度。误检问题人形雕像、海报、模特等可能被误检为人。优化思路提高置信度阈值conf但这会增加漏检。最根本的方法是丰富训练数据在数据集中加入这些“负样本”并标注为背景或其他类别。计数区域ROI限定实际应用中我们可能只关心特定区域如商场入口、电梯口的人数。优化思路在推理后只统计中心点或边界框与预定义多边形区域ROI有交集的检测框。OpenCV的cv2.pointPolygonTest()函数可以方便地实现点与多边形的位置判断。import numpy as np # 定义ROI多边形顶点假设为四边形 roi_polygon np.array([[100, 100], [500, 100], [500, 400], [100, 400]], np.int32) def is_inside_roi(box, polygon): 判断检测框中心点是否在多边形内 x_center (box[0] box[2]) / 2 y_center (box[1] box[3]) / 2 # 使用OpenCV函数判断 # 或者使用shapely库的Polygon.contains(Point) distance cv2.pointPolygonTest(polygon, (x_center, y_center), False) return distance 0 # 在内部或边界上 # 在计数循环中 valid_count 0 for det in detections: x1, y1, x2, y2, conf, cls_id det if is_inside_roi([x1, y1, x2, y2], roi_polygon): valid_count 16. 性能优化与生产部署从Demo到产品一个在Jupyter Notebook里跑通的模型离真正的生产应用还有距离。我们需要考虑速度、资源消耗和稳定性。6.1 模型导出与优化YOLOv8训练出的.pt文件是PyTorch模型直接用于推理可能不是最高效的。我们可以将其导出为其他更高效的格式。from ultralytics import YOLO model YOLO(runs/train/exp1/weights/best.pt) # 导出为ONNX格式通用交换格式 success model.export(formatonnx, imgsz640, simplifyTrue) # 导出为TensorRT引擎NVIDIA GPU上极致加速 # 需要先安装TensorRT success model.export(formatengine, imgsz640, workspace4) # workspace单位为GB # 导出为OpenVINO IR格式Intel CPU/GPU/NPU加速 success model.export(formatopenvino, imgsz640)格式选择建议ONNX:作为中间格式兼容性强可用于多种推理后端ONNX Runtime, TensorRT等。是部署的第一步。TensorRT:如果你在NVIDIA Jetson等边缘设备或服务器上部署TensorRT能提供最大的推理速度提升通常有数倍到数十倍。OpenVINO:针对Intel硬件CPU, iGPU, VPU优化在x86服务器或Intel边缘设备上表现优异。CoreML, TFLite:分别用于苹果生态和安卓/嵌入式设备。6.2 使用ONNX Runtime进行高性能推理导出ONNX后我们可以脱离PyTorch使用更轻量、优化的ONNX Runtime进行推理通常能获得更快的速度和更低的内存占用。import onnxruntime as ort import cv2 import numpy as np # 1. 加载ONNX模型并创建推理会话 onnx_model_path path/to/best.onnx providers [CUDAExecutionProvider, CPUExecutionProvider] # 优先使用CUDA session ort.InferenceSession(onnx_model_path, providersproviders) input_name session.get_inputs()[0].name output_name session.get_outputs()[0].name # 2. 图像预处理需与训练时一致 def preprocess(image, input_size640): # 保持长宽比resize h, w image.shape[:2] scale min(input_size / h, input_size / w) new_h, new_w int(h * scale), int(w * scale) resized cv2.resize(image, (new_w, new_h)) # 填充到正方形 padded np.full((input_size, input_size, 3), 114, dtypenp.uint8) padded[:new_h, :new_w] resized # 转换通道和类型 padded padded.transpose(2, 0, 1) # HWC - CHW padded np.ascontiguousarray(padded, dtypenp.float32) / 255.0 # 归一化 padded np.expand_dims(padded, axis0) # 增加批次维度 return padded, scale, (new_h, new_w) # 3. 推理 image cv2.imread(test.jpg) input_tensor, scale, (new_h, new_w) preprocess(image) outputs session.run([output_name], {input_name: input_tensor})[0] # outputs: [1, 84, 8400] # 4. 后处理解析YOLOv8输出 # YOLOv8输出格式为 [batch, 84, 8400]其中844(xywh)80(COCO类别数) # 需要根据置信度阈值和NMS进行过滤代码略长可参考Ultralytics官方后处理逻辑 # ... # 最终得到 detections [x1, y1, x2, y2, conf, cls_id] count len(detections)6.3 部署架构思考对于真正的生产系统我们很少直接运行一个Python脚本。需要考虑服务化使用FastAPI、Flask等框架将模型封装成RESTful API或gRPC服务供其他系统调用。流水线化对于视频流可以使用GStreamer、FFmpeg构建处理流水线将解码、推理、编码、推流等环节解耦。边缘部署在Jetson、树莓派等设备上需要交叉编译、模型量化INT8来进一步压缩模型、提升速度。监控与日志记录请求量、推理延迟、计数结果便于问题排查和系统优化。避坑指南生产部署中最常见的问题是内存泄漏和并发安全。确保你的推理代码在处理完每一帧后正确释放资源如中间张量。如果是Web服务注意模型加载和会话Session的生命周期管理避免在多线程环境下出现竞争条件。对于高并发场景可以考虑使用模型副本或批处理推理来提高吞吐量。7. 常见问题与排查实录在实际操作中你几乎一定会遇到下面这些问题。这里记录了我的排查思路和解决方案。7.1 训练阶段问题问题1训练损失loss不下降或者震荡非常剧烈。可能原因与排查学习率过高这是最常见的原因。尝试将lr0降低一个数量级如从0.01降到0.001。数据有问题检查标注文件格式是否正确归一化类别ID从0开始。检查图像和标注文件是否一一对应。可以使用ultralytics内置的data‘coco8.yaml’这样的简单数据集先跑通流程。批次大小太小如果GPU显存小导致batch只能设为1或2梯度更新会很不稳定。尝试使用梯度累积accumulate参数来模拟更大的批次。模型与数据不匹配你加载的预训练模型如yolov8s.pt是在COCO上训练的有80类。如果你的数据集只有‘person’一类需要在data.yaml中正确设置nc: 1和names: [‘person’]。问题2验证集mAP很低但训练集损失正常下降过拟合。可能原因与排查数据量太少深度学习是数据驱动的人群场景复杂几百张图片很难训练出泛化能力强的模型。尝试收集更多数据或使用更强的数据增强增大mosaic,mixup的概率。数据增强不够或太强增强不够导致模型没见过各种变化增强太强可能破坏了图像语义。调整data.yaml中的增强参数或使用augmentTrue默认让框架自动调节。训练轮数太多使用patience参数启用早停让训练在模型性能不再提升时自动停止。7.2 推理阶段问题问题3推理速度很慢FPS达不到实时要求。排查与优化模型太大换用更小的模型如从yolov8l换到yolov8n。输入分辨率太高降低imgsz如从640降到320。速度会成平方倍提升但小目标检测能力会下降。没有使用GPU确保device‘0’或cuda并且PyTorch/TensorRT正确识别了GPU。后处理耗时在Python循环中做NMS可能成为瓶颈。确保使用模型内置的NMSiou参数控制或使用优化过的C/CUDA后处理代码。导出为TensorRT/OpenVINO这是提升速度最有效的手段通常能有数倍提升。问题4在密集人群场景下计数严重不准漏检或重复计数。排查与优化调整置信度和IOU阈值降低conf如0.2以提高召回率减少漏检适当调整iou如0.4以平衡重复计数和漏检。使用专门的数据集训练用CrowdHuman这类密集人群数据集进行微调或者在自己的密集场景数据上重新标注训练。尝试其他模型头YOLOv8也有分割模型-seg后缀实例分割能提供像素级掩码在极度密集、遮挡严重的场景下有时比检测框更鲁棒。后处理算法升级引入简单的跟踪如基于IOU的跟踪或使用人群密度图回归作为辅助而不仅仅依赖检测框计数。7.3 环境与依赖问题问题5ImportError或RuntimeError提示CUDA、Torch版本不匹配。解决方案这是环境管理的经典问题。严格按照PyTorch官网提供的命令根据你的CUDA版本安装对应的PyTorch。使用conda list | grep torch和python -c “import torch; print(torch.__version__)”确认版本。最干净的方法是重建一个全新的Conda环境从头安装。问题6训练时GPU显存溢出OOM。解决方案减小batch大小。减小imgsz。使用梯度累积accumulate参数例如accumulate4表示每4个批次更新一次梯度等效于增大batch 4倍但显存占用不变。使用更小的模型如yolov8n。检查是否有其他程序占用了大量显存。这个项目就像搭积木从环境配置到模型部署每一步都可能遇到独特的“坑”。但每解决一个问题你对整个系统的理解就会加深一层。我个人最大的体会是数据质量决定模型上限工程细节决定系统下限。花在数据清洗和标注上的时间以及花在优化推理管道、处理边界情况上的时间其回报往往比盲目调参要大得多。最后别忘了在真实场景中反复测试你的系统摄像头角度、光照变化、行人姿态的多样性总会给你带来新的挑战而这正是迭代和优化的开始。本文还有配套的精品资源点击获取