データセット
LibreYOLOのデータセットは、ルート、分割、クラス名を指定するYAMLファイルです。ラベルファイルの保存場所を含むその他の情報は、規則に従ってこのファイルから導出されます。
学習にデータセットを指定する
data=はYAMLパス、またはパッケージに同梱された構成の名前を受け取ります。
from libreyolo import LibreYOLO model = LibreYOLO("LibreYOLO9s.pt") # 同梱名、相対パス、絶対パスのすべてを使用できます。model.train(data="coco8.yaml", epochs=10)libreyolo train model=LibreYOLO9s.pt data=coco8.yaml epochs=10名前は固定順序で解決されます。存在する絶対パス、作業ディレクトリを基準に指定どおりの名前、.yamlを追加した同じ名前、同梱の構成ディレクトリの順です。一致するものがない場合、検索したすべてのディレクトリと同梱構成の一覧がエラーに表示されます。
同梱構成
パッケージ内のlibreyolo/config/datasets/には13個のデータセット構成が同梱されています。
| 構成 | タスク | 注記 |
|---|---|---|
coco8.yaml | detect | 8枚の画像。通常のURLからダウンロード |
coco128.yaml | detect | 128枚の画像 |
coco1000.yaml | detect | 学習800枚、検証200枚 |
coco5000.yaml | detect | 学習4000枚、検証1000枚 |
coco.yaml | detect | 完全なCOCO 2017 |
coco-val-only.yaml | detect | val2017のみ |
coco8-pose.yaml | pose | 8枚の画像。COCO-17キーポイント |
coco-pose.yaml | pose | COCO 2017キーポイント |
ade20k.yaml | semantic | 150クラス |
cityscapes.yaml | semantic | 19クラス。手動でダウンロード |
cocostuff.yaml | semantic | 182クラス。手動でダウンロード |
gopro.yaml | restore | ぶれ画像と正解画像の組 |
sr8.yaml | restore | 超解像用の組 |
通常のダウンロードURLを持つのはcoco8.yamlとcoco128.yamlだけです。それ以外は、後述する明示的な許可が必要なPythonダウンロードブロックを持つか、データがすでにディスク上にあることを前提とします。
データセットの保存場所
YAMLのpathキーはデータセットルートを指定します。絶対pathはそのまま使われます。相対パスは最初にデータセットディレクトリの下、次にYAMLファイル自体の隣で検索されます。ダウンロード予定のデータセットはデータセットディレクトリの下に保存されます。
そのディレクトリは~/datasetsで、LIBREYOLO_DATASETS_DIR環境変数により上書きできます。設定ファイルはありません。
YAMLのキー
path: my-dataset # データセットルート
train: images/train # 学習に必須
val: images/val # 検証に必須
test: images/test # 任意
nc: 3 # 任意。namesと一致する必要がある
names:
0: person
1: helmet
2: vest
download: https://example.com/my-dataset.zip # 任意train、val、testはそれぞれ、画像ディレクトリ、1行に1つの画像パスを記載した.txtファイル、または両方を混在させたリストを受け付けます。.txtリストの行は相対パスでもよく、その場合はリストファイル自身のディレクトリを基準に解決されます。#で始まる行はスキップされます。
namesにはリストまたは整数をキーとするマッピングを指定できます。ncは任意です。両方が存在して一致しない場合、doctorはエラーとして報告します。
ディレクトリ構成とラベルファイル
物体検出、セグメンテーション、姿勢推定、方向付きボックスは同じ構成を使用します。ラベルパスは、画像パス内のimagesディレクトリ要素をlabelsへ書き換え、拡張子を.txtへ変更して導出されます。
my-dataset/
images/train/0001.jpg -> labels/train/0001.txt
images/val/0002.jpg -> labels/val/0002.txt完全なimagesパス要素だけを書き換えるため、images_oldという名前のディレクトリは変更されません。
物体検出の1行は5フィールドで、すべて元画像の幅と高さに対して[0, 1]へ正規化されます。
<class_id> <cx> <cy> <w> <h>ラベルファイルがないか空の場合は物体がない画像を意味し、例外を発生させず背景として学習します。5フィールドを超える行はポリゴンとして読み取られ、その外接範囲がボックスになります。このため、セグメンテーション用のエクスポートを物体検出の学習に使用しても問題なく読み込まれます。doctorはこの経路で処理された行数を報告します。
その他のタスク
セグメンテーションは同じ構成を維持し、少なくとも3点を持つ<class_id> <x1> <y1> ... <xN> <yN>のポリゴン行を使用します。5フィールドの物体検出行も受け付け、長方形インスタンスを意味します。
姿勢推定では、YAMLにkpt_shape: [K, D]と任意のflip_idx順列を追加します。各行は正確に5 + K * Dフィールドで、ボックスに続き、x yまたはx y vで表すK個のキーポイントを並べます。可視性は0、1、2のいずれかです。
方向付きボックスは正確に9フィールドで、クラスの後に正規化座標の4つの角点を並べます。角度はファイルに保存しません。
セマンティックセグメンテーションでは、各画像を同じ解像度のシングルチャンネルマスクと組み合わせます。imagesをmasks_dir(デフォルトはmasks)へ置き換えて解決します。ピクセル値255は無視を意味します。label_mappingは読み込み時にソースIDを学習IDへ再マッピングします。
画像分類はラベルファイルではなくImageFolderツリーを使用し、train/とval/のそれぞれにクラスごとのディレクトリを置きます。クラスからインデックスへのマッピングは、フォルダー名の並べ替え順です。
画像復元では、input_dirとtarget_dirを通じて、劣化した入力と同一解像度の正解ターゲットを組み合わせます。深度、表面法線、エッジでは、それぞれ固有のディレクトリキーを通じて画像と密なマップを組み合わせます。
深度スケールの規則やpanopticのsegment-id PNGエンコーディングを含むタスク別の完全な仕様は、ライブラリリポジトリのdocs/dataset_schema.mdにあります。
ネイティブCOCO JSON
COCO JSONアノテーションファイルを直接使用できます。annotationsマッピングを追加すると、分割パスが画像ルートになります。
path: my-dataset
train: images/train
val: images/val
annotations:
train: annotations/train.json
val: annotations/val.jsonnamesがある場合、JSONのカテゴリー名と一致する必要があり、namesがモデルの予測するラベルIDを定義します。namesがなければ、COCOカテゴリーIDを並べ替え、0..N-1へ密にマッピングします。
この経路では分割ごとに1つの画像ディレクトリを前提とします。パスのリストや.txt画像リストを指定すると、通知なく別のセットを読み込まず、例外が発生します。
自動ダウンロード
trainまたはvalパスが空ではないディレクトリか既存ファイルへ解決されると、データセットは存在すると見なされます。存在せず、YAMLにdownloadキーがある場合、その値によって次の処理が決まります。
httpまたはhttpsのURLは取得され、zipの場合はデータセットルートへ展開されます。それ以外は埋め込みPythonスクリプトとして扱われ、allow_download_scripts=Trueの場合だけ実行されます。指定がなければ、警告とともにスクリプトをスキップし、ディスク上にあるデータを使って学習を続行します。
libreyolo train model=LibreYOLO9s.pt data=coco.yaml allow_download_scripts=trueこのフラグはコード実行のゲートであり、ネットワークのゲートではありません。URLのダウンロードはどちらの場合も行われ、許可が必要なのはdownload: |ブロックです。フラグが有効な場合、CLIは警告を表示します。doctorが有効にすることはありません。
学習前にデータセットを検査する
libreyolo doctorは物体検出データセットを読み取り、GPUを使う前に問題になる箇所を報告します。エラーがあると終了コード1を返すため、CIゲートとして使用できます。
libreyolo doctor my-dataset.yamllibreyolo doctor my-dataset.yaml strict=true json=true# ラベルとYAMLだけを読み取ります。破損、重複、分割間のデータ漏洩の# 検査にはピクセルが必要なので、すべてスキップされます。libreyolo doctor my-dataset.yaml fast=truefrom libreyolo import doctor report = doctor.diagnose("my-dataset.yaml", imgsz=640) for finding in report.findings: print(finding.severity.value, finding.check_id, finding.message) raise SystemExit(report.exit_code(strict=False))検査は6つのファミリーに分かれます。
| ファミリー | 検査対象 |
|---|---|
config | namesの欠落、namesと一致しないnc、分割の欠落または空、重複クラス名 |
files | ラベルファイルのない画像、画像のないラベル、分割に記載された画像の欠落、stemの衝突 |
labels | 不正な行、[0, nc)の範囲外にあるクラスID、[0, 1]の範囲外にある座標、面積ゼロのボックス、極小または巨大なボックス、重複ボックス、バイト単位で同一のラベルファイル |
balance | インスタンス数がゼロまたは少ないクラス、クラス不均衡率、1つの分割だけに存在するクラス、背景画像の割合 |
images | デコードできないファイル、EXIF回転、異常なチャンネル構成、単一色の画像、完全または近似重複 |
splits | 2つの分割に完全またはほぼ同一の画像が存在すること |
--onlyと--skipは検査IDまたはファミリープレフィックスを受け取るため、skip=images,labels.tiny_objectも有効です。--fastはピクセルのデコードが必要な検査をすべて除外します。対象はimagesとsplitsファミリーです。
知っておくべき動作が2つあります。--strictはエラーだけでなく警告でも終了コードを失敗にします。また、doctorが対象とするのは物体検出データセットだけです。姿勢推定、セグメンテーション、方向付きボックスのデータセットは、誤った仕様で検査せず、検出した形式を示すメッセージとともに拒否されます。
関連項目
- データを準備した後に
train()が受け取る引数についてはハイパーパラメーターを参照してください。 valまたはtest分割で評価する方法については検証と指標を参照してください。