YOLOv5 トレーニングでラベルが見つからない、/path/train.cache にラベルが見つからない問題解決策 (個人テストに利用可能)
❤️ インターネット上のチュートリアルで説明されている解決策のほとんどは信頼性が低く、問題の原因の分析はありません。この記事は、YOLOv5 トレーニングでラベルが見つからない場合に、/path/train.cache にラベルが見つかりませんという問題を完全に解決します。 !この記事を通じて、環境構築の過程で不要なトラブルを解決できれば幸いです。——©️シルバン・ディン
バージョン | システム |
---|---|
YOLOv5 v6.1 | Linux |
これには主に 2 つの理由がありますNo labels found
。1 つは、インターネットからダウンロードしたデータ セットは独自のラベル形式しか提供していないため、YOLOv5 形式のラベルに変換する必要があるためです。もう 1 つは、プロジェクトの構成のためです。ディレクトリ。この記事では、後者、つまりプロジェクト ディレクトリの構成に起因するタグが見つからない問題に焦点を当てますが、この種の問題に対するオンライン上での回答はほとんどありません。
ラベルの形式が間違っています
インターネットからダウンロードされたデータ セットのほとんどは、フォルダーに保存されているVOC
形式のラベル付きファイル、または他の形式のラベル付きファイルのみを提供します。このとき、まずタグを YOLOv5 で必要な形式に変換するプログラムを作成する必要があります。.xml
annotations
YOLOv5 タグ形式の説明
Roboflow Annotateなどのツールを使用して画像にラベルを付けた後、画像ごとに1 つのファイルでラベルをYOLO 形式
*.txt
でエクスポートします(画像内にオブジェクトがない場合、*.txt
ファイルは必要ありません)。ファイル*.txt
の仕様は次のとおりです。
- オブジェクトごとに 1 行
- 各行は
class x_center y_center width height
フォーマットされます。- ボックス座標は正規化された xywh形式 (0 ~ 1) である必要があります。ボックスがピクセル単位の場合、
x_center
と をwidth
画像の幅で、 とy_center
をheight
画像の高さで割ります。- クラス番号にはゼロのインデックスが付けられます (0 から始まります)。
VOC を YOLOv5 に変換
VOC から YOLOv5 形式への変換については、座標変換関数を提供する36yolov5/data/VOC.yaml
行目を参照してください。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) # 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')])
❤️ 具体的な実装の詳細については、他のブロガーの記事を参照してください。
他の形式を YOLOv5 に変換する
異なる形式の他のマーク ファイルの場合は、それらを YOLOv5 形式のマークに変換するプログラムを手動で作成する必要があります。
yolov5/utils/general.py
その中のいくつかの関数は、次のようなインスピレーションを与えるかもしれませんxyxy2xywh()
...xywh2xyxy()
これらは座標形式の変換を担当します。
プロジェクトディレクトリの構造が間違っています
正しいラベル形式を取得した後もNo labels found
エラーが発生するため、この時点では、プロジェクト ディレクトリの構成構造にエラーがあると考えてください。
正しいディレクトリ構造
ココ
⭐️ 結論を先に言いますと、COCO を例にすると、正しいディレクトリ構造は次のようになります。
# 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
フォルダーと同階層にあり、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
-
images
名前もlabels
フォルダー名も他のものに変更できないことに注意してください。その理由については後述します。 -
train2017.txt
トレーニング セット、検証セット、テスト セットのイメージ ファイル パスは 、 に保存され、その内容は次のとおりval2017.txt
です。test-dev2017.txt
./images/20151127_114556.jpg ./images/20151127_114946.jpg ./images/20151127_115133.jpg
ココ128
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
ディレクトリ構造は次のようになります。
coco128
├── images
│ ├── test
│ │ └── 20151127_115133.jpg
│ └── train2017
│ └── 20151127_114556.jpg
└── labels
├── test
│ └── 20151127_115133.txt
└── train2017
└── 20151127_114556.txt
images
名前もlabels
フォルダー名も他のものに変更できないことに注意してください。images
およびlabels
フォルダーの場合は、トレーニング セット、検証セット、およびテスト セットを保存するための対応するフォルダーを作成します。フォルダー名は一貫している必要があります。要件はありませんが、 で設定する必要がありますcoco128.yaml
。
エラー原因調査
yolov5/utils/datasets.py
行 391 は、img2label_paths(img_paths)
ラベル パスへのイメージ パスのマッピングを定義し、self.label_files = img2label_paths(self.im_files) # labels
行447 は、 img2label_paths()
generate を呼び出します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]
/images/
YOLOv5 は、各イメージ パス内のの最後のインスタンスをに置き換えることにより、各イメージのラベルを自動的に見つけます/labels/
。
つまり、YOLOv5 はラベル パスを見つけるために画像パスを自動的に../datasets/coco128/images/*.jpg
変更します。../datasets/coco128/labels/*.txt
問題を解決するにはどうすればよいですか?
上記のlabel_files
割り当てと印刷の後label_files
、マークされたパスを取得し、印刷されたパスに基づいてプロジェクトのファイル パスを変更することで、すべての問題を解決できます。