一文彻底解决YOLOv5训练找不到标签问题

YOLOv5 训练找不到标签, No labels found in /path/train.cache 问题的解决方法(亲测可用)

❤️ 网上绝大部分教程所述解决方法都不靠谱,也没有分析问题发生的原因,本文彻底解决了YOLOv5训练时找不到标签,出现 No labels found in /path/train.cache 的问题!希望通过本文,在配置环境的过程中,为各位解决一些不必要的麻烦。——©️ Sylvan Ding

版本系统YOLOv5 v6.1Linux

出现 No labels found 的原因主要有两点,一方面是因为网上下载的数据集只提供了其专属的标签格式,需要转换成YOLOv5格式的标签;另一方面则是因为项目目录的组织问题。本文重点探讨后者,即 由项目目录的组织问题而引起的找不到标签的问题,这类问题网上的解答较少。

标签格式有误

网上下载的数据集大多数只提供 VOC 格式的 .xml 标记文件,存放于 annotations 文件夹中,或是其他格式的标记文件。此时,就应当先编写程序,将标签转换成YOLOv5所需格式。

YOLOv5标签格式说明

After using a tool like Roboflow Annotate to label your images, export your labels to YOLO format, with one *.txt file per image (if no objects in image, no *.txt file is required). The *.txt file specifications are:

  • One row per object
  • Each row is class x_center y_center width height format.

  • Box coordinates must be in normalized xywh format (from 0 – 1). If your boxes are in pixels, divide x_center and width by image width, and y_center and height by image height.

  • Class numbers are zero-indexed (start from 0).

一文彻底解决YOLOv5训练找不到标签问题

一文彻底解决YOLOv5训练找不到标签问题

; convert VOC to YOLOv5

VOC到YOLOv5格式转换,可以参考 yolov5/data/VOC.yaml中,36行 convert_label(),其中 convert_box()提供了坐标转换功能。

def convert_label(path, lb_path, year, image_id):
    def convert_box(size, box):
        dw, dh = 1. / size[0], 1. / size[1]
        x, y, w, h = (box[0] + box[1]) / 2.0 - 1, (box[2] + box[3]) / 2.0 - 1, box[1] - box[0], box[3] - box[2]
        return x * dw, y * dh, w * dw, h * dh

    in_file = open(path / f'VOC{year}/Annotations/{image_id}.xml')
    out_file = open(lb_path, 'w')
    tree = ET.parse(in_file)
    root = tree.getroot()
    size = root.find('size')
    w = int(size.find('width').text)
    h = int(size.find('height').text)

    for obj in root.iter('object'):
        cls = obj.find('name').text
        if cls in yaml['names'] and not int(obj.find('difficult').text) == 1:
            xmlbox = obj.find('bndbox')
            bb = convert_box((w, h), [float(xmlbox.find(x).text) for x in ('xmin', 'xmax', 'ymin', 'ymax')])
            cls_id = yaml['names'].index(cls)
            out_file.write(" ".join([str(a) for a in (cls_id, *bb)]) + '\n')

注: convert_box(size, box), bb = convert_box((w, h), [float(xmlbox.find(x).text) for x in ('xmin', 'xmax', 'ymin', 'ymax')])

❤️ 具体实现细节可以参考其他博主的文章,这类文章比较多。

其他格式转换成YOLOv5

对其他不同格式的标记文件,需要手动编写程序以转换成YOLOv5格式标记。

yolov5/utils/general.py中的一些函数也许能给您提供一些启发,如 xyxy2xywh(), xywh2xyxy()… 他们负责坐标格式的转换。

项目目录的结构有误

在得到正确的标签格式后,仍出现 No labels found错误,这时考虑项目目录组织结构出现错误。

正确的目录结构

coco

⭐️ 先放结论,以COCO为例,正确的目录结构应当为:


../datasets/coco128/images/im0.jpg
../datasets/coco128/labels/im0.txt

path: ../datasets/coco
train: train2017.txt
val: val2017.txt
test: test-dev2017.txt

一文彻底解决YOLOv5训练找不到标签问题
  • datasets文件夹和 yolov5文件夹同级, datasets下建立各个数据集文件。以 coco为例, images文件夹 直接存放所有图片数据labels文件夹 直接存放图片对应的 *.txt标记文件。
.
├── images
│   ├── 20151127_114556.jpg
│   ├── 20151127_114946.jpg
│   └── 20151127_115133.jpg
├── labels
│   ├── 20151127_114556.txt
│   ├── 20151127_114946.txt
│   └── 20151127_115133.txt
  • 注意, imageslabels 文件夹的命名均不能改成别的!原因稍后再说。
  • train2017.txt, val2017.txt, test-dev2017.txt中存放训练集、验证集、测试集的图片文件路径,其内容如下所示:
./images/20151127_114556.jpg
./images/20151127_114946.jpg
./images/20151127_115133.jpg

coco128

如果你想用coco128的文件组织形式:


path: ../datasets/coco128
train: images/train2017
val: images/train2017
test:

datasets目录结构应当为:

coco128
├── images
│   ├── test
│   │   └── 20151127_115133.jpg
│   └── train2017
│       └── 20151127_114556.jpg
└── labels
    ├── test
    │   └── 20151127_115133.txt
    └── train2017
        └── 20151127_114556.txt
  • 注意, imageslabels 文件夹的命名均不能改成别的
  • imageslabels文件夹内,创建相互对应的文件夹用来存放训练集、验证集、测试集,文件夹名字要一致,没有要求,但需要在 coco128.yaml中设置。

错误原因探究

yolov5/utils/datasets.py 391行 img2label_paths(img_paths) 定义了图片路径到标签路径的映射,447行 self.label_files = img2label_paths(self.im_files) # labels 调用 img2label_paths() 以生成 label_files.

def img2label_paths(img_paths):

    sa, sb = os.sep + 'images' + os.sep, os.sep + 'labels' + os.sep
    return [sb.join(x.rsplit(sa, 1)).rsplit('.', 1)[0] + '.txt' for x in img_paths]

YOLOv5 locates labels automatically for each image by replacing the last instance of /images/ in each image path with /labels/.

即YOLOv5会自动将图片路径 ../datasets/coco128/images/*.jpg更改为 ../datasets/coco128/labels/*.txt,以寻找labels路径!

如何解决问题?

在上述 label_files 赋值后,打印 label_files,我们就能得到标记的路径,再根据打印出的路径修改自己项目的文件路径,方能解决一切问题!

一文彻底解决YOLOv5训练找不到标签问题

; 参考文献

Cannot find labels in train.cache custom dataset COCO #6158

Original: https://blog.csdn.net/IYXUAN/article/details/124339385
Author: Sylvan Ding
Title: 一文彻底解决YOLOv5训练找不到标签问题

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/624986/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球