YOLOv5 訓(xùn)練找不到標(biāo)簽, No labels found in /path/train.cache 問(wèn)題的解決方法(親測(cè)可用)
?? 網(wǎng)上絕大部分教程所述解決方法都不靠譜,也沒(méi)有分析問(wèn)題發(fā)生的原因,本文徹底解決了YOLOv5訓(xùn)練時(shí)找不到標(biāo)簽,出現(xiàn) No labels found in /path/train.cache 的問(wèn)題!希望通過(guò)本文,在配置環(huán)境的過(guò)程中,為各位解決一些不必要的麻煩。——?? Sylvan Ding
版本 | 系統(tǒng) |
---|---|
YOLOv5 v6.1 | Linux |
出現(xiàn) No labels found
的原因主要有兩點(diǎn),一方面是因?yàn)榫W(wǎng)上下載的數(shù)據(jù)集只提供了其專屬的標(biāo)簽格式,需要轉(zhuǎn)換成YOLOv5格式的標(biāo)簽;另一方面則是因?yàn)轫?xiàng)目目錄的組織問(wèn)題。本文重點(diǎn)探討后者,即由項(xiàng)目目錄的組織問(wèn)題而引起的找不到標(biāo)簽的問(wèn)題,這類問(wèn)題網(wǎng)上的解答較少。
標(biāo)簽格式有誤
網(wǎng)上下載的數(shù)據(jù)集大多數(shù)只提供 VOC
格式的 .xml
標(biāo)記文件,存放于 annotations
文件夾中,或是其他格式的標(biāo)記文件。此時(shí),就應(yīng)當(dāng)先編寫程序,將標(biāo)簽轉(zhuǎn)換成YOLOv5所需格式。
YOLOv5標(biāo)簽格式說(shuō)明
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
andwidth
by image width, andy_center
andheight
by image height.- Class numbers are zero-indexed (start from 0).
convert VOC to YOLOv5
VOC到Y(jié)OLOv5格式轉(zhuǎn)換,可以參考yolov5/data/VOC.yaml
中,36行convert_label()
,其中convert_box()
提供了坐標(biāo)轉(zhuǎn)換功能。
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) # class id
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')])
?? 具體實(shí)現(xiàn)細(xì)節(jié)可以參考其他博主的文章,這類文章比較多。
其他格式轉(zhuǎn)換成YOLOv5
對(duì)其他不同格式的標(biāo)記文件,需要手動(dòng)編寫程序以轉(zhuǎn)換成YOLOv5格式標(biāo)記。
yolov5/utils/general.py
中的一些函數(shù)也許能給您提供一些啟發(fā),如xyxy2xywh()
, xywh2xyxy()
… 他們負(fù)責(zé)坐標(biāo)格式的轉(zhuǎn)換。
項(xiàng)目目錄的結(jié)構(gòu)有誤
在得到正確的標(biāo)簽格式后,仍出現(xiàn)No labels found
錯(cuò)誤,這時(shí)考慮項(xiàng)目目錄組織結(jié)構(gòu)出現(xiàn)錯(cuò)誤。
正確的目錄結(jié)構(gòu)
coco
?? 先放結(jié)論,以COCO為例,正確的目錄結(jié)構(gòu)應(yīng)當(dāng)為:
# path example
../datasets/coco128/images/im0.jpg # image
../datasets/coco128/labels/im0.txt # label
# yolov5/data/coco.yaml
path: ../datasets/coco # dataset root dir
train: train2017.txt # train images (relative to 'path')
val: val2017.txt # val images
test: test-dev2017.txt
-
datasets
文件夾和yolov5
文件夾同級(jí),datasets
下建立各個(gè)數(shù)據(jù)集文件。以coco
為例,images
文件夾直接存放所有圖片數(shù)據(jù),labels
文件夾直接存放圖片對(duì)應(yīng)的*.txt
標(biāo)記文件。. ├── images │ ├── 20151127_114556.jpg │ ├── 20151127_114946.jpg │ └── 20151127_115133.jpg ├── labels │ ├── 20151127_114556.txt │ ├── 20151127_114946.txt │ └── 20151127_115133.txt
-
注意,
images
和labels
文件夾的命名均不能改成別的!原因稍后再說(shuō)。 -
train2017.txt
,val2017.txt
,test-dev2017.txt
中存放訓(xùn)練集、驗(yàn)證集、測(cè)試集的圖片文件路徑,其內(nèi)容如下所示:./images/20151127_114556.jpg ./images/20151127_114946.jpg ./images/20151127_115133.jpg
coco128
如果你想用coco128的文件組織形式:
# yolov5/data/coco128.yaml
path: ../datasets/coco128 # dataset root dir
train: images/train2017 # train images (relative to 'path') 128 images
val: images/train2017 # val images (relative to 'path') 128 images
test: # test images (optional)
則datasets
目錄結(jié)構(gòu)應(yīng)當(dāng)為:
coco128
├── images
│ ├── test
│ │ └── 20151127_115133.jpg
│ └── train2017
│ └── 20151127_114556.jpg
└── labels
├── test
│ └── 20151127_115133.txt
└── train2017
└── 20151127_114556.txt
- 注意,
images
和labels
文件夾的命名均不能改成別的! -
images
和labels
文件夾內(nèi),創(chuàng)建相互對(duì)應(yīng)的文件夾用來(lái)存放訓(xùn)練集、驗(yàn)證集、測(cè)試集,文件夾名字要一致,沒(méi)有要求,但需要在coco128.yaml
中設(shè)置。
錯(cuò)誤原因探究
yolov5/utils/datasets.py
391行 img2label_paths(img_paths)
定義了圖片路徑到標(biāo)簽路徑的映射,447行 self.label_files = img2label_paths(self.im_files) # labels
調(diào)用 img2label_paths()
以生成 label_files
.
def img2label_paths(img_paths):
# Define label paths as a function of image paths
sa, sb = os.sep + 'images' + os.sep, os.sep + 'labels' + os.sep # /images/, /labels/ substrings
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會(huì)自動(dòng)將圖片路徑../datasets/coco128/images/*.jpg
更改為../datasets/coco128/labels/*.txt
,以尋找labels路徑!
如何解決問(wèn)題?
在上述 label_files
賦值后,打印 label_files
,我們就能得到標(biāo)記的路徑,再根據(jù)打印出的路徑修改自己項(xiàng)目的文件路徑,方能解決一切問(wèn)題!
文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-453232.html
參考文獻(xiàn)
Cannot find labels in train.cache custom dataset COCO #6158文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-453232.html
到了這里,關(guān)于一文徹底解決YOLOv5訓(xùn)練找不到標(biāo)簽問(wèn)題的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!