简介一份面向目标检测入门与项目实战的完整教程资料包聚焦Yolov5Pytorch训练自定义数据集的全流程适合希望掌握数据标注、模型训练、评估与部署的深度学习初学者或进阶开发者。压缩包共69个文件大小约13.81MB包含20个Python脚本、9个YAML模型配置文件、多张示例图像、Dockerfile、Markdown与PDF说明文档脚本覆盖数据拆分、标签检查、模型训练、测试与导出等环节。目前已有302人学习下载资源目录按功能模块划分配合readme和示例输出便于按步骤查漏补缺。资料从环境安装、数据格式转换到训练参数调优均有涉及并附有预训练权重下载脚本、推理演示和Docker部署支持帮助读者快速跑通从数据集准备到模型部署的完整流程同时理解YOLOv5架构与配置文件的修改方法。整体实用性强是一份可直接用于毕设、课设或工程预研的高性价比实战资源。1. 目标检测入门九成时间耗在训练之前目标检测这个方向Yolov5 加 Pytorch 的组合几乎是新手训练自己数据集的首选但真正卡住人的从来不是检测原理而是从一张张图片到模型跑通的那段路。我见过太多人把三四个工作日耗在环境报错、标签格式和显存崩溃上最后连 train.py 都没跑起来。下面这份流程是我基于 Yolov5 主线反复验证过的完整落地路径环境搭建、数据准备、格式转换、训练调参、避坑记录到推理验证。适合手里有图片素材、想训练专属检测模型的从业者也适合刚接触 Pytorch 的小白按步骤复现。现在 YOLOv8、YOLO26 都在快速迭代但 Yolov5 的资料生态依然是做第一套自有数据集训练最稳的选择跑通一次后面换任何框架都是同一套思路。每个环节我都给了可照抄的命令和参数范围跟着做就能把模型跑出来。2. 先把 Pytorch 环境装对Yolov5 项目跑通前的两件正事2.1 用 Anaconda 配置 Pytorch 环境GPU 版安装与镜像源选择我见过最多的一类翻车是把 Pytorch 直接装进 base 环境后面某个依赖升级把整个环境搞崩所有项目跟着遭殃。所以第一步永远是用 Anaconda 建独立虚拟环境conda create -n yolov5 python3.8 -y conda activate yolov5 nvidia-smi第一行创建名为 yolov5 的独立环境Python 版本 3.8 到 3.10 都行Yolov5 在这几个版本上都跑得稳。第三行的 nvidia-smi 用来确认显卡驱动支持的最高 CUDA 版本输出右上角的 CUDA Version 只是驱动能兼容的上限不等于环境里要装的 CUDA——Pytorch 的 CUDA 运行时是独立打包的只要驱动不低于它要求的下限就能用。确认驱动没问题后装 GPU 版 Pytorch。常见做法是直接用 Pytorch 官方源指定 CUDA 版本pip install torch torchvision --index-url https://download.pytorch.org/whl/cu121cu121 对应 CUDA 12.1驱动较老就换 cu118。没有 NVIDIA 显卡或者只有 AMD 显卡比如 RX 系列时最省事的办法是装 CPU 版 torch训练会慢十倍以上但流程能完整跑通代码一行不用改。装完在 Python 里验证import torch print(torch.__version__) print(torch.cuda.is_available())第二行输出 True 说明 GPU 可用。很多人的环境问题在这一步现形nvidia-smi 正常但这里输出 False多半是装成了 CPU 版或者 torch 版本和显卡驱动不匹配。这一步的验证结果决定了后面所有训练操作是在 GPU 上完成还是在 CPU 上磨洋工。提示不建议用 conda install 装 Pytorch。conda 默认源包版本偏旧解析依赖时还容易和 pip 冲突。统一用 pip 管理 torch 和后面的 requirements.txt省心得多。2.2 项目目录结构与依赖安装先搞清楚每个文件夹干嘛的环境就绪后克隆 Yolov5 官方仓库并安装依赖git clone https://github.com/ultralytics/yolov5.git cd yolov5 pip install -r requirements.txtrequirements.txt 会一次性装好 numpy、opencv-python、matplotlib、tensorboard 这些运行依赖。之前用官方源装好的 torchpip 在解析依赖时认为已经满足不会重复下载。网络中途超时是这里最高频的坑换国内镜像重试即可pip install -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple装完先别急着改代码把目录结构过一遍核心就这几个文件/目录作用data/存放数据集配置 yaml类别数、类名、数据路径models/网络结构定义如 yolov5s.yamlutils/数据集加载、增强、mAP 计算逻辑train.py训练入口detect.py推理验证入口export.py导出 ONNX 等部署格式第一次训练建议直接用官方预训练权重yolov5s.pt、yolov5m.pt、yolov5l.pt、yolov5x.pt参数量逐级递增。显存 8G 以内的机器用 yolov5s.pt 起步最稳它也是微调自有数据集性价比最高的选择。权重会在首次运行时自动下载慢的话可以手动下好放进项目根目录脚本检测到文件存在就不会重复拉取。环境全部就绪后先跑一个官方示例做冒烟测试python detect.py --source data/images/bus.jpg如果终端输出检测结果且项目根目录出现 runs/detect/exp 文件夹说明 Pytorch、OpenCV、模型加载这条链路全部通了。最常见的输出是类似 Bus: 1 persons, 1 bus 的结果看到它就说明后面训自己的数据只是换数据和换参数的事。这一步能提前暴露 opencv 装得不完整、依赖缺失等一系列隐藏问题别跳过。这一章的落点很实在环境不干净、版本不匹配带来的报错占整个流程排查量的六成以上。虚拟环境和 Pytorch 验证这两步走扎实后面所有章节的操作都在同一套环境里完成。如果后续要迁移到树莓派这类 ARM 设备做部署安装逻辑不变只是 torch 要选对应 aarch64 的版本——那部分等模型训练好再操心训练阶段 x86 机器足够。3. 自制数据集从图片采集到标注文件生成整套流程直接抄3.1 图片采集与 LabelImg 标注什么样的数据能喂出能用的模型数据集质量决定模型上限这是全流程里最不容偷懒的一环。采集图片时记住一个底线每个类别至少 300 张想做出能落地用的模型至少 500 张每类低于 100 张训练出来的只能算玩具。图片要覆盖目标在不同角度、不同光线、不同距离下的样子尤其要保证背景多样化——很多人只拍自家一个场景训练集 loss 很好看一到现场就翻车本质就是背景过拟合。标注工具用 LabelImg一条命令装好pip install labelimg labelimg打开后先设置图片目录和标签保存目录按 W 画框按 D 切换下一张画完一张按 CtrlS 保存。重点右侧输出格式要选 PascalVOC也就是存成 xml 文件。原因后面讲格式转换时会说明——Yolov5 吃的不是这个格式但 xml 是中间交换格式里兼容性最好的之后转 YOLO txt 只需一段脚本公开数据集里也能直接拿到现成的 xml 配标注。标注质量比标注数量重要得多。框要贴目标边界能少留白就少留白同一个目标不要画两个重叠框遮挡超过一半的目标建议跳过这类样本会给训练提供矛盾梯度。还有一条血泪经验标注完一定要自己重新翻一遍特别是批量标注时手一抖漏掉的目标会让 mAP 莫名其妙掉三四个点而且极难排查。3.2 目录结构与 data.yamlYolov5 的数据加载逻辑Yolov5 不会自动扫描所有图片它通过一个 yaml 配置告诉训练脚本数据在哪。标准的目录结构长这样dataset/ ├── images/ │ ├── train/ │ └── val/ └── labels/ ├── train/ └── val/images 和 labels 下的文件名一一对应前缀相同、扩展名不同图片是 0001.jpg标签就是 0001.txt。同一个目标的标签行格式为class_id x_center y_center width height后四个值全部是相对图片宽高的比例取值范围 [0,1]。这个格式是 YOLO 系的通用约定不管训练还是部署都会按这个解析尽早习惯它。train/val 的划分比例一般取 8:2关键点是按图片随机划分不要按文件夹或按拍摄批次划分否则同一个场景的相邻帧会被拆进两边造成数据泄漏val 指标虚高部署时现原形。划分脚本我一般写成 copy 而不是 move这样万一划分出问题还有后悔药import os import random import shutil random.seed(42) src_dir dataset/source # 收集的所有图片和 txt 混放此处 train_dir dataset/images/train val_dir dataset/images/val train_lbl dataset/labels/train val_lbl dataset/labels/val for d in [train_dir, val_dir, train_lbl, val_lbl]: os.makedirs(d, exist_okTrue) imgs [f for f in os.listdir(src_dir) if f.endswith(.jpg)] random.shuffle(imgs) val_num int(len(imgs) * 0.2) for i, img in enumerate(imgs): prefix img[:-4] if i val_num: shutil.copy(f{src_dir}/{img}, f{val_dir}/{img}) shutil.copy(f{src_dir}/{prefix}.txt, f{val_lbl}/{prefix}.txt) else: shutil.copy(f{src_dir}/{img}, f{train_dir}/{img}) shutil.copy(f{src_dir}/{prefix}.txt, f{train_lbl}/{prefix}.txt)脚本逻辑把全部图片随机打乱前 20% 进 val后 80% 进 train同名 txt 跟随图片走。random.seed(42) 保证每次执行结果一致方便复现对比。复制而不是移动是因为后面想调整比例或发现标签错误时原始数据还在 src_dir 里重新划分一遍就行。最后在 data/ 目录下写一个数据集配置文件文件名随意比如 data/custom.yamltrain: dataset/images/train val: dataset/images/val nc: 2 names: [person, car]train 和 val 这两行新手最容易犯的错是写相对路径导致训练时找不到文件。Yolov5 是相对当前命令行所在目录解析这些路径的最稳的方法是把 train 和 val 都写成绝对路径。nc 是类别总数names 的顺序必须和标注时的类名顺序一致这个顺序直接决定模型输出的类别 ID下一章转换脚本里会再强调一次。4. 训练自己的数据集格式转换脚本与 train.py 调参经验4.1 把 VOC 格式转成 YOLO 格式转换脚本与四个边界坑LabelImg 保存的是 PascalVOC 的 xmlYolov5 需要的是 txt中间用一段转换脚本衔接。我贴一个最直接的版本import xml.etree.ElementTree as ET import os classes [person, car] # 顺序必须和 data.yaml 的 names 一致 def voc2yolo(xml_path, out_path): tree ET.parse(xml_path) root tree.getroot() size root.find(size) w int(size.find(width).text) h int(size.find(height).text) lines [] for obj in root.iter(object): name obj.find(name).text if name not in classes: continue cls_id classes.index(name) box obj.find(bndbox) xmin float(box.find(xmin).text) ymin float(box.find(ymin).text) xmax float(box.find(xmax).text) ymax float(box.find(ymax).text) cx (xmin xmax) / 2 / w cy (ymin ymax) / 2 / h bw (xmax - xmin) / w bh (ymax - ymin) / h lines.append(f{cls_id} {cx:.6f} {cy:.6f} {bw:.6f} {bh:.6f}) with open(out_path, w) as f: f.write(\n.join(lines)) for f in os.listdir(dataset/xml): if f.endswith(.xml): voc2yolo(fdataset/xml/{f}, fdataset/labels/{f.replace(.xml, .txt)})脚本做的事解析 xml 的 size 拿图片宽高遍历每个 object 取 bndbox 的四个角点换算成中心点加宽高的归一化坐标按「类别 ID 中心 x 中心 y 宽度 高度」写入 txt。换算公式总共就那么四句不建议直接复制网上那种带整数坐标的旧脚本——早期 YOLO 的 txt 是像素坐标Yolov5 统一要求归一化混用必挂。这里有四个边界坑挨个说清楚。一是归一化坐标必须落在 [0,1]。如果标注框画到了图片外面转换后会出现大于 1 或小于 0 的值训练时 Loss 直接变 NaN。遇到这种情况要么重标图片要么转换时用 min/max 把坐标夹回 [0,1]。二是类别索引从 0 开始。classes 的顺序就是模型的类别 ID比如 classes [person, car]person 是 0car 是 1这必须和 data.yaml 的 names 完全一致差一个位置整个模型的输出就全错了。三是空 txt 是合法的。图片里没有目标时txt 文件内容为空这代表负样本Yolov5 能正常处理不要因此删掉图片。负样本对抑制误检很有用尤其是在工厂质检这类只有少数缺陷出现的场景里。四是 xml 里的 size 要以标注时读取到的实际尺寸为准。有些手机拍完照片会旋转EXIF 信息里的方向与实际像素不一致如果 xml 的 width/height 和图片真实分辨率对不上转换出来的框全部偏移。这类问题的特征就是 val loss 正常但 mAP 上不去检查方式是把转换后的框画回图上肉眼一看就明白。转换完成后随手抽查三五个 txt内容应该长这样0 0.512345 0.623012 0.231045 0.412056 1 0.783102 0.190234 0.150203 0.281034第一列类别 ID后四列依次是中心 x、中心 y、宽、高。如果看到全 0 或全部相同的值回到第一步检查标注环节。4.2 跑 train.pybatch-size、epochs、imgsz 怎么搭配不翻车数据就绪后训练命令就是这一条python train.py --data data/custom.yaml --weights yolov5s.pt --epochs 120 --batch-size 16 --imgsz 640 --device 0逐个说明参数--data 指向刚写的 data/custom.yaml--weights 指定预训练权重 yolov5s.pt--epochs 是遍历整个训练集的次数--batch-size 是每次迭代喂给模型的图片数量--imgsz 是输入分辨率默认 640--device 0 表示第一张 GPUCPU 训练时写 cpu。参数搭配的总原则显存不够先降 batch-size再降 imgsz最后才考虑换更小的模型。imgsz 从 640 降到 512mAP 通常只掉一两个点显存占用却能有明显下降。batch-size 选多大有点玄学经验上 8 到 32 之间收益最明显超过 32 之后提升有限小数据集上反而容易让模型收敛到尖锐的最小值泛化变差。我一般以显存不爆为上限8G 显存跑 yolov5s、imgsz 640batch-size 16 是稳妥起点。小数据集每类几百张epochs 建议 100 到 150。Yolov5 默认开了早停连续 100 轮验证集 loss 不降就自动终止所以即使写成 300 也多数在 80 轮左右停掉不必担心一路训过拟合。两个值得动的增强超参数--hsv-h 控制色调偏移--fliplr 控制随机左右翻转对小数据集防过拟合明显但每次改完要重新对比 mAP别一上来全开。训练过程中想看实时曲线另开一个终端tensorboard --logdir runs浏览器打开 localhost:6006能看到 box_loss、obj_loss、mAP 三条主曲线的变化。判断训练是否正常就看两个点box_loss 随 epoch 稳步下降mAP0.5 中后期持续爬升不剧烈震荡。训练正常时的终端输出长这样Epoch gpu_mem box_loss obj_loss cls_loss Instances Size 15/120 5.21G 0.06210 0.02813 0.00942 12 640关注 gpu_mem 是否稳定、loss 是否比前几个 epoch 低。如果 gpu_mem 显示一直很小但仍有进程报显存不足多半是别的东西占了卡先 nvidia-smi 看一眼再说。5. 目标检测训练避坑指南四个高频翻车现场与排查顺序训练过程对新手来说像个黑匣子好在翻车的规律基本固定。下面四条覆盖了我被问得最多的场景每条按现象、原因、解决写清楚遇到问题直接对照。5.1 现象loss 不降反升曲线来回震荡现象训练到中途box_loss 在某轮突然跳到之前的两倍之后迟迟降不下来或者整条曲线一直在 0.08 附近震荡不收敛。原因最常见有两个。一是学习率问题Yolov5 默认学习率 0.01配合 warmup 和余弦退火正常不用动但如果你人为调大了 --lr0或者数据量太小导致每个 batch 的梯度方向差异巨大loss 就会震荡。二是训练数据里有错标比如类别标错、框明显偏了模型在矛盾样本上反复横跳。解决先跑一个 20 轮的对照组用默认学习率确认是不是自己改过超参数。然后随机抽 20 张训练图把预测结果画在原图上人工核对。之后可以加 --cos-lr 平滑学习率衰减。三者都试过还震荡再检查类别是否严重不平衡少数类样本量少于 50 张时简单复制几份做过采样往往最有效。5.2 现象CUDA out of memory训练秒退现象train.py 启动后几秒内报 RuntimeError: CUDA out of memory连带出现 Cannot allocate 字样的错误训练进程直接退出。原因batch-size 和 imgsz 的组合超出了显存上限或者机器上有其它程序占着显存。Yolov5 默认的数据加载会额外占一部分临时显存做 mosaic 拼图实际占用比纯模型参数算出来的要多不少。解决按顺序排查。第一步 --batch-size 8还爆就降到 4第二步 --imgsz 512第三步给 train.py 加 --workers 4降低数据加载的并发开销。8G 以下显存还可以加 --half 半精度训练显存占用能砍一半但 20 系之前的显卡对半精度支持不稳定优先降 imgsz 而不是开半精度。启动前顺手 nvidia-smi 看一眼确认没有残留的训练进程占着显存这是很多人忽略的一点。5.3 现象训练集 loss 正常mAP 却不到 0.3现象box_loss 降得很好训练集上画框也很准但 val mAP0.5 一直上不去或者训练集和验证集的 mAP 差距巨大。原因典型过拟合常见诱因三选一样本量太少、场景单一导致背景过拟合、train/val 划分泄漏。第三种最隐蔽——如果图片来自视频抽帧按文件夹划分很容易把连续帧分到两边检测结果被剧透val 指标虚高部署时现原形。解决先确认划分是随机做的并把 val 里的图片和训练集做一次视觉比对排除相邻帧。然后确认 mosaic 增强开着Yolov5 默认开启。小目标多的场景先检查目标像素尺寸如果大量目标小于 32x32切图放大再训练或者关注 mAP0.5:0.95 而不是只盯 mAP0.5——小目标检测的场景里大目标的指标会掩盖小目标的问题。最后才考虑换 yolov5m 或 yolov5l 加大模型容量不要一上来就上大模型。5.4 现象No labels found 或 cache 文件一直报错现象训练刚开始就报 Dataset error提示 No labels found in train path或者之前改过标签再重新训练结果用的还是旧标签mAP 怎么调都不变。原因两类。一是目录结构不对Yolov5 要求 images 和 labels 严格配对且 txt 文件名必须和图片名一字不差二是 Yolov5 的标签缓存机制——首次读取标签会生成 .cache 文件之后直接从缓存加载手动改了 txt 但没删缓存训练用的还是旧数据。还有一类隐蔽的txt 里 class_id 大于 nc-1或某个字段越界。解决先检查目录结构和 txt 内容确认每行五个字段齐全、class_id 合法。然后删掉数据集目录下所有 .cache 文件再重跑。最快的定位办法是写几行脚本遍历全部标签import os for root, _, files in os.walk(dataset/labels): for f in files: if f.endswith(.txt): path os.path.join(root, f) for line in open(path): parts line.strip().split() if len(parts) ! 5: print(字段数不对:, path, line.strip()) elif int(float(parts[0])) 2: # 2 换成自己的 nc print(类别ID越界:, path, line.strip())这段脚本只负责把问题文件定位出来不做任何修改。定位到具体文件后多半是转换脚本里 classes 顺序写错或者某个 xml 的类别名不在 classes 里被 continue 跳过导致对应 txt 少了一行。修完记得删掉 .cache重新生成缓存。6. 训练完先别高兴用 detect.py 和 export.py 把模型收尾6.1 用 detect.py 跑真实推理容易忽略的路径细节训练结束后权重在 runs/train/exp/weights/ 下best.pt 是验证集表现最好的权重last.pt 是最后一轮的。推理验证用 best.ptpython detect.py --weights runs/train/exp/weights/best.pt --source data/images/test --conf-thres 0.25--source 可以指定单张图片、文件夹、视频文件甚至摄像头设备号--conf-thres 是置信度阈值验证阶段用 0.25 看得全部署阶段调到 0.4 以上降低误检。新手最容易犯的错是用 last.pt 推理效果往往比 best.pt 差一截。6.2 用 export.py 导出 ONNX部署到边缘设备的最后一步验证通过后导出 ONNX 为部署做准备比如放到树莓派、工控机上交给 ONNX Runtime 跑python export.py --weights runs/train/exp/weights/best.pt --include onnx导出后先用 onnxruntime 加载跑同一张图和 detect.py 的结果逐框对比。输出一致再交给部署侧不要直接发一个从没验证过的 onnx 文件出去。我的习惯是每次训练结束先把 best.pt 复制出来按日期命名归档。runs 目录下一旦开始新一轮训练旧结果容易被覆盖这是整个流程里最便宜的后悔药。从环境配置到模型导出每一环偷懒都会在 mAP 或部署现场还回来参数可以照抄数据质量必须自己把关。这份流程跑通一次后面换 YOLOv8、换自己的检测任务都是同一套方法论。希望帮到你。本文还有配套的精品资源点击获取
企业数字化 ERP 产品动态
相关推荐
酷鸟云是什么?一文看懂云手机与安卓虚拟化的落地应用 第一次听到“酷鸟云是什么”这个问题时,我下意识愣了两秒——不是因为答不上来,而是因为在云服务满天飞的这几年,突然冒出一个不太按套路起名的产品,确实会让人反复确认它到底是做什么的。后来我专门花了两周时间,把它… · 2026/9/24 23:54:01
douyin-downloader 完整使用指南:快速上手抖音批量下载,去水印保存视频、图集与音乐 douyin-downloader 完整使用指南:快速上手抖音批量下载,去水印保存视频、图集与音乐 【免费下载链接】douyin-downloader A practical Douyin downloader for both single-item and profile batch downloads, with progress display, retries, SQLite de… · 2026/9/24 23:54:01
x86电脑如何编译ARM程序?交叉编译原理与工具链实战 为什么x86电脑能编译ARM程序?这件事还得从我第一次在x86的Ubuntu上敲出arm-linux-gnueabihf-gcc hello.c -o hello说起。那会儿我盯着生成的文件,死活想不明白:我手里这台CPU明明是Intel的,凭什么能吐出一个给ARM板子用的可执行文… · 2026/9/24 23:53:54
深度学习新闻分类推荐系统:从TextCNN到个性化推荐 简介:这份基于深度学习的新闻分类推荐系统Python实现源码,是专为课程设计与期末大作业准备的高分项目,下载后无需修改即可运行,适用于需要快速交付完整课题的高校学生。系统涵盖新闻数据预处理、文本分类模型训练、推荐逻辑展示等… · 2026/9/24 23:59:53
汽车电子底层软件开发:AUTOSAR与CAN总线实战解析 1. 这门“汽车电子底层软件开发就业课”到底在教什么?——不是写个LED闪烁就能上岗的很多人看到“汽车电子底层软件开发就业课”这个标题,第一反应是:不就是嵌入式C语言单片机CAN通信?刷几道LeetCode、调通一个STM32 CAN收发例程&… · 2026/9/24 23:59:53
Vim基础操作全攻略:保存退出、模式切换与高频命令实战 1. 项目概述1.1 核心需求解析今天聊聊Vim。写这个题目的原因是:几乎每个后端开发者、运维人员、数据工程师某天都会遇到一个场景——深夜加班,服务器登录界面只有黑底白字,编辑器只有vi/vim,你必须在五分钟内完成一次配置修改并保… · 2026/9/24 23:59:53
Python+CNN车牌识别实战:从数据预处理到模型训练与部署 简介:基于Python与卷积神经网络的车牌识别项目,面向计算机视觉初学者及智能交通开发者,目标是帮助用户掌握从数据预处理、模型构建到实际部署的完整流程。压缩包共25个文件,包含jpg/png图像样本、py训练脚本、md说明文档、dat数据… · 2026/9/24 23:59:53
AI元人文:从工具使用到思维重构的深度探索 最近半年我一直在琢磨一件事:AI元人文到底是什么?说白了,就是“用元视角重新审视人与AI的关系”,也在“探索AI如何反向逼着我们发现自己的思考边界”。标题里的“元探索”,在我看就是一层套一层的追问——当你用AI解决… · 2026/9/24 23:59:53