ARTICLE DETAIL

资讯详情

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

如何不转换格式直接用 Ultralytics YOLO 在 COCO JSON 标注上训练

如何不转换格式直接用 Ultralytics YOLO 在 COCO JSON 标注上训练 如何不转换格式直接用 Ultralytics YOLO 在 COCO JSON 标注上训练【免费下载链接】ultralyticsUltralytics YOLO26, YOLO11, YOLOv8 — object detection, instance segmentation, semantic segmentation, image classification, pose estimation, object tracking项目地址: https://gitcode.com/GitHub_Trending/ul/ultralytics如果你的数据集标注以 COCO JSON 格式存在如 Labelme、COCO 官方工具或 SAM 导出的instances_train.json而 Ultralytics YOLO 默认训练管线只识别 YOLO.txt标签常规做法是先跑一次convert_coco()把标注转成.txt文件再训练。项目文档提供了一条不转换的路径通过一个自定义数据集类在训练时直接解析 COCO JSON并用一个自定义 trainer 把它接入标准训练流程。完成本文后你可以用一个标准的model.train()调用直接在自己的 COCO JSON 标注上训练检测模型文档以 YOLO26 为例其他 Ultralytics YOLO 检测模型同样适用标注文件保持为唯一的真值来源不产生任何中间标签文件。这条路径适用于对象检测任务实例分割和姿态估计需要在cache_labels()中额外写入segments或keypoints字段本文最后会说明扩展方向。方案原理两个类替换默认数据加载Ultralytics 的训练管线默认构建YOLODataset它会扫描标签目录中的.txt文件。直接读 COCO JSON 的做法是替换这条数据通路只需要两个类COCODataset— 继承YOLODataset重写标签加载逻辑打开 COCO JSON把每个边界框从 COCO 像素格式[x_min, y_min, width, height]转换为 YOLO 归一化中心点格式[x_center, y_center, width, height]全部在内存中完成。iscrowd: 1的众包标注和零面积框会被自动跳过。COCOTrainer— 继承DetectionTrainer只重写build_dataset()方法让训练器构建COCODataset而不是默认的YOLODataset。这个实现是内置GroundingDataset的简化版——GroundingDataset同样直接读取 JSON 标注可参考其 源码实现 处理 segments 等更复杂的场景。COCODataset重写了三个方法get_img_files()、cache_labels()和get_labels()。其中get_img_files()返回空列表因为图片路径从 JSON 的file_name字段解析而不是扫描目录category_id会按 ID 排序后重映射为从 0 开始的类别索引所以 1-based标准 COCO、0-based 或非连续 ID 体系都能正确处理。与一次性转换convert_coco() 工作流的区别convert_coco()把.txt标签写入磁盘适合需要永久保留 YOLO 格式标签的场景本文方案在训练时解析 JSON、内存中转换适合希望以 COCO JSON 为唯一真值来源、不生成额外文件的场景。准备数据集目录结构按如下方式组织images/下按 train/val 分开放图片JSON 标注文件单独存放my_dataset/ images/ train/ img_001.jpg ... val/ img_100.jpg ... annotations/ instances_train.json instances_val.json dataset.yamlJSON 文件需符合 COCO 数据格式包含images、annotations、categories三个字段其中images中每条记录的file_name是相对于图片根目录的文件名解析时通过Path(self.img_path) / img_info[file_name]定位图片找不到的图片会被跳过。编写训练脚本下面是项目文档提供的完整脚本包含数据集类、训练器和训练调用。把它保存在dataset.yaml同目录并直接运行即可import json from collections import defaultdict from pathlib import Path import numpy as np from ultralytics import YOLO from ultralytics.data.dataset import DATASET_CACHE_VERSION, YOLODataset from ultralytics.data.utils import get_hash, load_dataset_cache_file, save_dataset_cache_file from ultralytics.models.yolo.detect import DetectionTrainer from ultralytics.utils import TQDM, colorstr class COCODataset(YOLODataset): Dataset that reads COCO JSON annotations directly without conversion to .txt files. def __init__(self, *args, json_file, **kwargs): Initialize the dataset with a COCO JSON annotation file. self.json_file json_file super().__init__(*args, data{channels: 3}, **kwargs) def get_img_files(self, img_path): Image paths are resolved from the JSON file, not from scanning a directory. self.fraction 1.0 # fraction is applied while scanning a directory, which this dataset skips return [] def cache_labels(self, pathPath(./labels.cache)): Parse COCO JSON and convert annotations to YOLO format. Results are saved to a .cache file. x {labels: []} with open(self.json_file) as f: coco json.load(f) categories {cat[id]: i for i, cat in enumerate(sorted(coco[categories], keylambda c: c[id]))} img_to_anns defaultdict(list) for ann in coco[annotations]: img_to_anns[ann[image_id]].append(ann) for img_info in TQDM(coco[images], descreading annotations): h, w img_info[height], img_info[width] im_file Path(self.img_path) / img_info[file_name] if not im_file.exists(): continue self.im_files.append(str(im_file)) bboxes [] for ann in img_to_anns.get(img_info[id], []): if ann.get(iscrowd, False): continue box np.array(ann[bbox], dtypenp.float32) box[:2] box[2:] / 2 box[[0, 2]] / w box[[1, 3]] / h if box[2] 0 or box[3] 0: continue cls categories[ann[category_id]] bboxes.append([cls, *box.tolist()]) lb np.array(bboxes, dtypenp.float32) if bboxes else np.zeros((0, 5), dtypenp.float32) x[labels].append( { im_file: str(im_file), shape: (h, w), cls: lb[:, 0:1], bboxes: lb[:, 1:], segments: [], normalized: True, bbox_format: xywh, } ) if not x[labels]: raise RuntimeError(fNo images listed in {self.json_file} were found in {self.img_path}) x[hash] get_hash([self.json_file, str(self.img_path)]) save_dataset_cache_file(self.prefix, path, x, DATASET_CACHE_VERSION) return x def get_labels(self): Load labels from .cache file if available, otherwise parse JSON and create the cache. cache_path Path(self.json_file).with_suffix(.cache) try: cache load_dataset_cache_file(cache_path) assert cache[version] DATASET_CACHE_VERSION assert cache[hash] get_hash([self.json_file, str(self.img_path)]) self.im_files [lb[im_file] for lb in cache[labels]] except (FileNotFoundError, AssertionError, AttributeError, KeyError, ModuleNotFoundError): cache self.cache_labels(cache_path) cache.pop(hash, None) cache.pop(version, None) return cache[labels] class COCOTrainer(DetectionTrainer): Trainer that uses COCODataset for direct COCO JSON training. def build_dataset(self, img_path, modetrain, batchNone): Build a COCODataset for the given split using the JSON file from the data config. json_file self.data[train_json] if mode train else self.data[val_json] return COCODataset( img_pathimg_path, json_filejson_file, imgszself.args.imgsz, batch_sizebatch, augmentmode train, hypself.args, rectself.args.rect or mode val, cacheself.args.cache or None, single_clsself.args.single_cls or False, strideint(self.model.stride.max()) if hasattr(self, model) and self.model else 32, pad0.0 if mode train else 0.5, prefixcolorstr(f{mode}: ), taskself.args.task, classesself.args.classes, fractionself.args.fraction if mode train else 1.0, ) model YOLO(yolo26n.pt) model.train(datadataset.yaml, epochs100, imgsz640, trainerCOCOTrainer)代码中的两个关键点build_dataset()只改一件事训练时用train_json、验证时用val_json取 JSON 路径。这两个键在 data 配置中都是必填的——训练和验证读取不同的图片目录训练 JSON 不能代替缺失的val_json。解析结果会写缓存标签解析完成后保存到 JSON 同目录的.cache文件例如instances_train.cache后续训练直接加载缓存跳过 JSON 解析。在 Windows 上以脚本方式启动训练时需要在训练调用前加if __name__ __main__:代码块否则会触发RuntimeError这是 Ultralytics 训练脚本的通用要求。配置 dataset.yamldataset.yaml使用标准的path、train、val字段定位图片目录再新增train_json、val_json两个字段指向 COCO 标注文件。注意与 转换指南 中的写法不同这里的path指向图片根目录所以train、val是裸的分片名而两个 JSON 路径字段不与path拼接必须写绝对路径。下例中的/path/to/my_dataset需替换为你数据集的实际绝对路径path: /path/to/my_dataset/images # root with train/ and val/ image subfolders train: train val: val # COCO JSON annotation files (use absolute paths; these custom keys are not resolved against path) train_json: /path/to/my_dataset/annotations/instances_train.json val_json: /path/to/my_dataset/annotations/instances_val.json names: 0: person 1: bicycle # ... remaining class namesnames必须按 JSONcategories数组按 ID 排序后的顺序列出类别名与代码中categories的重映射逻辑一致类别数量从names推导不需要单独设置nc。启动训练运行上面保存的脚本即可。与普通训练相比唯一的区别是model.train()中的trainerCOCOTrainer参数它告诉 Ultralytics 使用自定义数据集加载器。epochs100和imgsz640是文档示例中的取值可按需调整完整训练管线按标准流程运行包括训练中的验证、checkpoint 保存和指标记录详见 训练模式文档。验证结果与常见失败现象检查缓存文件。首次运行时JSON 同目录会生成instances_train.cache/instances_val.cache。后续运行直接加载该缓存说明解析结果已被复用。确认训练与验证都在正常跑指标。训练中的验证会走COCOTrainer.build_datasetmodeval解析val_json所以验证阶段能读到标签、正常计算指标。训练结束后按 训练文档 中描述的方式查看保存的 checkpoint 和记录的训练/验证指标即可。两个文档明确给出的失败现象如果 JSON 里列出的图片在img_path下一个都找不到cache_labels()会抛出RuntimeError: No images listed in json were found in img_path。此时检查path是否指向了包含train/、val/的图片根目录以及 JSON 中file_name的相对路径是否与该目录一致。独立的model.val()不走自定义 trainer只有训练中的验证经过COCOTrainer.build_dataset单独调用model.val()会构建标准YOLODataset扫描图片旁的.txt标签而找不到——它不会报错而是把图片全部计为背景验证跑完但所有指标为0并给出No labels found in ...和no labels found in detect set, cannot compute metrics without labels警告。如果你在训练之外单独验证模型需要按同样的build_dataset覆盖方式子类化 validator并通过model.val(validator...)传入。缓存陈旧陷阱。缓存的哈希基于 JSON 的文件大小和路径而不是内容。任何保持字节数不变的编辑——微调坐标、翻转iscrowd、替换两个等长类别名——都会让陈旧缓存原样保留训练会静默使用旧标注且无警告原地替换某张图片同理不可见。编辑标注或原地替换图片后删除对应的.cache文件。限制与扩展仅覆盖对象检测。需要实例分割时把 COCO 标注中的segmentation多边形数据写入每个标签字典的segments字段姿态估计则写入keypoints。处理 segments 的参考实现见内置GroundingDataset的 源码。fraction参数不生效。fraction在扫描图片目录时才应用COCODataset跳过了这一步代码里把它重置为1.0即该数据集只接受完整数据集不能按比例采样。无额外性能开销。JSON 只在首次训练时解析一次之后从.cache文件加载标注驻留内存训练速度与标准 YOLO 训练一致。如果之后需要永久性的 YOLO 格式标签例如换用其他框架改走 COCO to YOLO 转换指南中的convert_coco()一次性转换流程即可自定义数据集代码不再需要。下一步给cache_labels()扩展segments或keypoints以支持分割与姿态任务调参方面参考 Model Training Tips 中的超参数建议更多训练参数与多 GPU 配置见 训练模式文档数据集 API 细节见 YOLODataset 参考。【免费下载链接】ultralyticsUltralytics YOLO26, YOLO11, YOLOv8 — object detection, instance segmentation, semantic segmentation, image classification, pose estimation, object tracking项目地址: https://gitcode.com/GitHub_Trending/ul/ultralytics创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表