news 2026/5/1 14:53:24

yolov26模型训练(使用yolov5样本训练)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
yolov26模型训练(使用yolov5样本训练)

1、样本转换

原始文件路径为

/dataSharing/otherTrain/dataset/yolo26_data/
Annotations/ # xml
images/ # jpg

第 0 步:确认你的数据是否一一对应

cd /dataSharing/otherTrain/dataset/yolo26_data # 看看有多少图片/标注 ls images | wc -l ls Annotations | wc -l # 随机抽几个看看是否同名 python3 - << 'PY' import os, random imgs = [f for f in os.listdir("images") if f.lower().endswith((".jpg",".jpeg",".png"))] xmls = set([os.path.splitext(f)[0] for f in os.listdir("Annotations") if f.lower().endswith(".xml")]) sample = random.sample(imgs, min(20, len(imgs))) bad = [f for f in sample if os.path.splitext(f)[0] not in xmls] print("sample missing xml:", bad) PY

如果sample missing xml为空,说明基本OK。

第 1 步:把 VOC(xml) 转 YOLO,并自动划分 train/val

/dataSharing/otherTrain/dataset/yolo26_data下新建脚本:

cd /dataSharing/otherTrain/dataset/yolo26_data nano voc_to_yolo_split.py

把下面代码粘进去(可直接用):

import os, random, shutil import xml.etree.ElementTree as ET from pathlib import Path ROOT = Path("/dataSharing/otherTrain/dataset/yolo26_data") IMG_DIR = ROOT / "images" ANN_DIR = ROOT / "Annotations" OUT_IMG_TRAIN = ROOT / "images" / "train" OUT_IMG_VAL = ROOT / "images" / "val" OUT_LBL_TRAIN = ROOT / "labels" / "train" OUT_LBL_VAL = ROOT / "labels" / "val" VAL_RATIO = 0.2 SEED = 42 def parse_xml(xml_path: Path): tree = ET.parse(xml_path) root = tree.getroot() size = root.find("size") if size is None: raise ValueError(f"{xml_path} missing <size>") w = int(size.findtext("width")) h = int(size.findtext("height")) objs = [] for obj in root.findall("object"): name = obj.findtext("name") if not name: continue difficult = obj.findtext("difficult") if difficult and difficult.strip() == "1": continue bnd = obj.find("bndbox") if bnd is None: continue xmin = float(bnd.findtext("xmin")) ymin = float(bnd.findtext("ymin")) xmax = float(bnd.findtext("xmax")) ymax = float(bnd.findtext("ymax")) xmin = max(0.0, xmin) ymin = max(0.0, ymin) xmax = min(float(w), xmax) ymax = min(float(h), ymax) if xmax <= xmin or ymax <= ymin: continue objs.append((name, xmin, ymin, xmax, ymax)) return w, h, objs def voc_to_yolo(w, h, xmin, ymin, xmax, ymax): xc = (xmin + xmax) / 2.0 / w yc = (ymin + ymax) / 2.0 / h bw = (xmax - xmin) / w bh = (ymax - ymin) / h return xc, yc, bw, bh def main(): assert IMG_DIR.exists(), IMG_DIR assert ANN_DIR.exists(), ANN_DIR # 收集图片 imgs = [p for p in IMG_DIR.iterdir() if p.suffix.lower() in [".jpg",".jpeg",".png"] and p.is_file()] # 排除已经分出来的 train/val 目录 imgs = [p for p in imgs if p.parent == IMG_DIR] if not imgs: raise RuntimeError(f"No images found in {IMG_DIR}") # 收集类别(扫一遍 xml) classes = set() missing_xml = 0 for img in imgs: xml = ANN_DIR / (img.stem + ".xml") if not xml.exists(): missing_xml += 1 continue _, _, objs = parse_xml(xml) for name, *_ in objs: classes.add(name) classes = sorted(list(classes)) if not classes: raise RuntimeError("No classes parsed from XML. Check your xml format.") class2id = {c:i for i,c in enumerate(classes)} # 写 classes.txt (ROOT / "classes.txt").write_text("\n".join(classes), encoding="utf-8") # 划分 train/val random.seed(SEED) random.shuffle(imgs) n_val = int(len(imgs) * VAL_RATIO) val_imgs = imgs[:n_val] train_imgs = imgs[n_val:] # 创建输出目录 for p in [OUT_IMG_TRAIN, OUT_IMG_VAL, OUT_LBL_TRAIN, OUT_LBL_VAL]: p.mkdir(parents=True, exist_ok=True) def write_one(img_path: Path, out_img_dir: Path, out_lbl_dir: Path): xml_path = ANN_DIR / (img_path.stem + ".xml") if not xml_path.exists(): return False, "missing_xml" w, h, objs = parse_xml(xml_path) lines = [] for name, xmin, ymin, xmax, ymax in objs: cid = class2id[name] xc, yc, bw, bh = voc_to_yolo(w, h, xmin, ymin, xmax, ymax) # 保险:限制在0~1 xc = min(max(xc, 0.0), 1.0) yc = min(max(yc, 0.0), 1.0) bw = min(max(bw, 0.0), 1.0) bh = min(max(bh, 0.0), 1.0) lines.append(f"{cid} {xc:.6f} {yc:.6f} {bw:.6f} {bh:.6f}") # 没有目标也要写空txt(YOLO允许) (out_lbl_dir / f"{img_path.stem}.txt").write_text("\n".join(lines), encoding="utf-8") # 复制图片(也可以改成移动:shutil.move) shutil.copy2(img_path, out_img_dir / img_path.name) return True, "ok" stats = {"ok":0, "missing_xml":0} for img in train_imgs: ok, reason = write_one(img, OUT_IMG_TRAIN, OUT_LBL_TRAIN) stats[reason] = stats.get(reason, 0) + (0 if ok else 1) if ok: stats["ok"] += 1 for img in val_imgs: ok, reason = write_one(img, OUT_IMG_VAL, OUT_LBL_VAL) stats[reason] = stats.get(reason, 0) + (0 if ok else 1) if ok: stats["ok"] += 1 # 生成 data.yaml(Ultralytics/YOLO系列通用) data_yaml = f"""path: {ROOT} train: images/train val: images/val names: """ for i, c in enumerate(classes): data_yaml += f" {i}: {c}\n" (ROOT / "data.yaml").write_text(data_yaml, encoding="utf-8") print("Done.") print("Classes:", classes) print("Stats:", stats) print("Generated:", ROOT/"data.yaml", ROOT/"classes.txt") if __name__ == "__main__": main()

保存退出后执行:

python3 voc_to_yolo_split.py

执行完成后,你会得到:

  • labels/train/*.txt

  • labels/val/*.txt

  • images/train/*.jpg

  • images/val/*.jpg

  • data.yaml

  • classes.txt

你的原始images/*.jpg不会被删(脚本是 copy2)。如果你想节省空间我可以使用“移动版”。

第 2 步:快速检查转换结果是否正确

cd /dataSharing/otherTrain/dataset/yolo26_data # 统计数量 find images/train -type f | wc -l find labels/train -type f | wc -l find images/val -type f | wc -l find labels/val -type f | wc -l # 随机看一个标注文件 ls labels/train | head head -n 5 labels/train/$(ls labels/train | shuf -n 1)

如果images/trainlabels/train数量一致,基本没问题。

第 3 步:新建一个虚拟环境训练 YOLOv26(Ultralytics 方式)

第 3-1 步:创建 YOLOv26 专用 conda 环境

进入你想放环境的目录(随便,比如放在项目目录旁边):

conda create -n yolo26 python=3.10 -y

第 3-2 步:激活虚拟环境

conda activate yolo26

激活成功后,你会看到前缀:

(yolo26) root@xxx:#

第 3-3 步:安装 PyTorch(最关键一步):

在 yolo26 环境中执行:

pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu121

安装完马上验证

python - << 'PY' import torch print(torch.__version__) print("CUDA:", torch.cuda.is_available()) print("GPU:", torch.cuda.get_device_name(0)) PY

必须看到:

CUDA: True

第 3-4 步:安装 Ultralytics(清华源)

pip install ultralytics -i https://pypi.tuna.tsinghua.edu.cn/simple --default-timeout=1000

验证:

yolo version

第 3-4步:开始训练

yolo26x.pt下载地址

https://huggingface.co/Ultralytics/YOLO26?utm_source=chatgpt.com

yolo26n.pt下载地址

https://github.com/ultralytics/assets/releases/download/v8.4.0/yolo26n.pt

yolo detect train \ model=./yolo26x.pt \ data=./data.yaml \ imgsz=640 \ epochs=200 \ batch=10 \ device=3 \ workers=8 \ amp=True \ cos_lr=True \ close_mosaic=10 \ project=/dataSharing/otherTrain/yolo26_runs \ name=yolo26x_640

3-5 验证(最直观:拿你真实业务视频/图片做推理,看框对不对)

nohup yolo detect train \ model=/data/dataSharing/otherTrain/dataset/yolo26_data/yunnan/yolo26x.pt \ data=/data/dataSharing/otherTrain/dataset/yolo26_data/yunnan/data.yaml \ imgsz=640 \ epochs=100 \ batch=8 \ device=1 \ workers=16 \ amp=True \ cos_lr=True \ close_mosaic=10 \ project=/data/dataSharing/otherTrain/yolo26_runs \ name=yolo26x_640_yunnan_20260430 &

输出会在:

ls /dataSharing/otherTrain/yolo26_runs/exp01_pred_vid
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/1 14:51:23

把 SNC PSE 创建对,别让 STRUST 成为你上线前最后一个拦路虎

很多团队在做 SNC 的时候,真正卡住的地方并不是参数表面上那几个开关,而是 PSE 身份到底该怎么建,建出来以后为什么系统还是不认,为什么 STRUST 里节点不显示,为什么 snc/identity/as 明明配了,运行时还是拿不到正确身份。把这些问题捋顺以后,你会发现 Creating the SNC…

作者头像 李华
网站建设 2026/5/1 14:50:27

Linux 0.11源码深度解析:kernel/exit.c —— 进程生命的终章与资源的轮回

一、文件概述&#xff1a;善始善终的进程生命周期管理者exit.c​ 位于 /kernel目录&#xff0c;是Linux 0.11中进程终止与资源回收的核心实现。如果说 fork.c和 exec.c负责进程的“生”与“变”&#xff0c;那么 exit.c就是负责进程的“死”与“归”。它实现了 exit()系统调用&…

作者头像 李华
网站建设 2026/5/1 14:50:24

配置OpenClaw智能体工作流使用Taotoken作为其模型服务后端

配置OpenClaw智能体工作流使用Taotoken作为其模型服务后端 1. 准备工作 在开始配置之前&#xff0c;请确保您已经完成以下准备工作&#xff1a;拥有有效的Taotoken API Key&#xff0c;并已在OpenClaw项目中安装必要的依赖。API Key可以在Taotoken控制台的"API密钥管理&…

作者头像 李华
网站建设 2026/5/1 14:49:24

基于AFSIM的无人机集群协同侦察打击一体化作战系统:最小化完整案例

一、项目背景与作战需求1.1 现代无人机作战面临的挑战随着无人机技术的快速发展&#xff0c;单一无人机平台已无法满足复杂战场环境下的作战需求。现代战争对无人机系统提出了更高要求&#xff1a;核心作战需求&#xff1a;协同侦察能力&#xff1a;多无人机协同完成大范围、多…

作者头像 李华
网站建设 2026/5/1 14:45:44

MOS管驱动电压选4.5V还是10V?从导通损耗和开关损耗的权衡说起

MOS管驱动电压选4.5V还是10V&#xff1f;从导通损耗和开关损耗的权衡说起 在开关电源和电机驱动电路设计中&#xff0c;MOS管的栅极驱动电压选择常常让工程师陷入两难。我曾在一个48V电机驱动项目中&#xff0c;因为Vgs电压选择不当导致MOS管温升异常&#xff0c;最终不得不重新…

作者头像 李华