データを追加して準備する
アップロード前にローカルでデータセットを確認し、動画を意図的にサンプリングして、最初の試行でプラットフォームのデータセットをReadyにします。
アップロード前に見つけたデータセットの不具合が、最もコストのかからない不具合です。Pascal VOCのラベルは通知なくスキップされ、28ピクセル未満の画像は拒否され、30分の動画からはわずか100フレームしか抽出されず、その大半は何もないシーンを映しています。このレッスンでは、アップロード前に2分間のチェックを行い、動画を意図的にサンプリングし、プラットフォームの処理状況を示すシグナルを確認して、トレーニングデータを完全な状態で取り込みます。
実践的
データセットを作成する#

サイドバーでAnnotateを開き、New Datasetをクリックします。ダイアログでは、ソース、名前、タスクタイプ、任意のライセンス、顔ぼかし、公開範囲を指定します。

| データソース | 使用するケース | 計画 |
|---|---|---|
| アップロード | ファイルが手元にある場合:画像、動画、アーカイブ、NDJSONエクスポート | すべて |
| URL | 公開されている.zip、.tar、.tar.gz、.tgz、または.ndjsonのリンクがある場合。プラットフォームがサーバー側でダウンロードします | すべて |
| クラウド | データがすでにGoogle Cloud Storage、Amazon S3、またはAzure Blob Storageにあり、そこに保持する必要がある場合 | Pro、Enterprise |
| オンプレミス | 画像データをマシンの外に出せない場合 | Enterprise |
判断基準:このコースではコピーをアップロードしてください。CloudおよびOn Premiseのデータセットでは画像データがプラットフォームの外部に置かれるため、スマートアノテーション、クラスタリング、複製、バージョンスナップショットは利用できません。
タスクタイプによって、利用できるツールとモデルが決まります。プラットフォームは、Ultralytics YOLOの7つすべてのタスクに対応しています。
| タスク | ラベル付け方法 |
|---|---|
| 検出 | 矩形、またはSAMとYOLOによるスマートアノテーション |
| セグメンテーション | ポリゴン、またはSAMとYOLOによるスマートアノテーション |
| セマンティック | ポリゴン、またはSAMとYOLOによるスマートアノテーション。PNGマスクを直接インポートできます |
| 姿勢推定 | 組み込みまたはカスタムのスケルトン上のキーポイント。スマートアノテーションにはYOLOの姿勢推定モデルを使用 |
| OBB | 方向付きボックス、またはSAMとYOLOによるスマートアノテーション |
| 分類 | サイドバーのクラスセレクター |
| 深度 | 作図なし:深度マップとペアになった画像をアップロードしてください(アップロードまたはURLのみ) |
実例:アップロード前にデータセットを確認する#
Platformは、最大50 MBで短辺が28 px以上のJPEG、PNG、WebP、BMP、TIFF、HEIC、AVIF、JP2、DNG、MPO画像を受け付け、YOLO、COCO、LabelMe、UltralyticsまたはLabelbox NDJSON、セマンティックPNGマスクのラベルを読み取ります。Pascal VOC XMLは検出されますが、インポートはされません。このスクリプトは、公開されている医薬品データセットを使って、ローカルのYOLOデータセットがこれらのルールに準拠しているか確認します。
from collections import Counter
from pathlib import Path
from PIL import Image
from ultralytics.data.utils import check_det_dataset
ACCEPTED = {".jpg", ".jpeg", ".png", ".webp", ".bmp", ".tif", ".tiff", ".heic", ".avif", ".jp2", ".dng", ".mpo"}
data = check_det_dataset("medical-pills.yaml") # your local dataset YAML
root = Path(data["path"])
problems = Counter()
for split in ("train", "val", "test"):
if not data.get(split):
continue
files = [p for p in Path(data[split]).rglob("*") if p.is_file()]
images = [p for p in files if p.suffix.lower() in ACCEPTED]
labeled = 0
for img in images:
label = Path(str(img).replace("images", "labels")).with_suffix(".txt")
labeled += label.exists() and label.stat().st_size > 0
if min(Image.open(img).size) < 28:
problems["under 28 px (rejected)"] += 1
if img.stat().st_size > 50 * 1024**2:
problems["over 50 MB (rejected)"] += 1
problems["unsupported files (skipped)"] += len(files) - len(images)
print(f"{split:<5} {len(images):>4} images, {labeled:>4} labeled, {len(images) - labeled:>3} background")
problems["Pascal VOC .xml labels (not imported)"] += len(list(root.rglob("*.xml")))
print("classes:", data["names"])
print("problems:", {k: v for k, v in problems.items() if v} or "none")train 92 images, 92 labeled, 0 background
val 23 images, 23 labeled, 0 background
classes: {0: 'pill'}
problems: none出力の見方:
- 分割ごとの件数。
train/、val/、test/フォルダー内の画像は、アップロード後もその分割に保持されるため、この数値がPlatformに表示されます。valの行がない場合、Platformがランダムな検証用分割を自動で作成します(以下の落とし穴を参照)。 - 背景画像(ラベルファイルなし)は、適度な数であれば問題ありません。「ここには何もない」状態をモデルに学習させるのに役立ちます。数百枚もある場合は、通常、ラベルのエクスポートに失敗しています。
problems: noneは、すべての画像が処理されることを意味します。ここに表示される件数は、Errorsタブに入るか、まったく取り込まれないファイルの数です。
データセットフォルダーをdata.yamlと一緒にZIP圧縮し、アーカイブをギャラリーにドラッグします。Platformは形式を自動検出し、同一画像は1つだけ保存します。また、データセット内の既存画像とアップロード画像が重複した場合は、スキップ、両方を保持、置換のいずれかを選択できます。
実例:Platformに任せる前に動画をサンプリングする#
Platformは各動画を1秒あたり1フレームでサンプリングし、最大100フレームを保持します。100秒を超えるクリップでは、間隔を広げます。
| クリップの長さ | 保持されるフレーム数 | 間隔 |
|---|---|---|
| 60秒 | 60 | 1秒 |
| 100秒 | 100 | 1秒 |
| 30分(30 fpsで54,000フレーム) | 100 | 18秒 |
手早く確認するには適していますが、ほとんどの実プロジェクトには不十分です。30分のシフト記録も100フレームになり、その多くは何もない通路の映像です。長時間の映像は自分でサンプリングして、フレームをアップロードしてください。
均等にサンプリングするなら、FFmpegで十分です。
mkdir -p frames
ffmpeg -i source.mp4 -vf fps=1 frames/%06d.jpgイベントに応じてサンプリングするには、事前学習済みのUltralytics YOLOモデルを使い、対象物が含まれるフレームだけを保持します。
from pathlib import Path
import cv2
from ultralytics import YOLO
model = YOLO("yolo26n.pt") # or your latest fine-tune
out = Path("frames")
out.mkdir(exist_ok=True)
source = "https://github.com/ultralytics/assets/releases/download/v0.0.0/solutions_ci_demo.mp4"
seen = kept = 0
for i, result in enumerate(model.predict(source, stream=True, vid_stride=5, classes=[0], conf=0.5, verbose=False)):
seen += 1
if len(result.boxes): # keep only frames where a person was detected
cv2.imwrite(str(out / f"frame_{i:05d}.jpg"), result.orig_img)
kept += 1
print(f"Kept {kept} of {seen} sampled frames")Kept 12 of 12 sampled framesvid_stride=5は5フレームごとに確認し、classes=[0]は人物に検出対象を限定し、conf=0.5は信頼度の低い予測を無視します。この動きの多いデモクリップでは、サンプリングされたすべてのフレームに人物がいます。ほとんど何もないシーンの記録では、保持される割合が大幅に低下し、ラベリング費用も抑えられます。保持された隣接フレームが同じに見えなくなるまで、vid_strideの値を上げてください。
Platformの処理状況を確認する#
アップロード後、Platformは検証、正規化(4,096 pxを超える画像はリサイズ)、サムネイル生成、ラベル解析、統計計算を行います。次の3か所を確認してください。

Errorsタブは、ファイルの処理に失敗した場合にのみ表示されます。破損ファイル、未対応形式、28 px未満の画像、CMYKやインデックスカラーの画像などが表示され、それぞれに修正のヒントが示されます。再エクスポートまたは再アップロードしてください。Chartsタブには、分割の内訳、上位クラス、画像サイズ、ファイルサイズ、アノテーションの位置、ボックスのサイズ、画像あたりのオブジェクト数が表示されます。出現頻度が極端に低いクラス、小さすぎる画像、特定の隅に集中したボックスがないか確認してください。- バッジは、処理が完了し、データセットに
train画像が1枚以上、valまたはtest画像が1枚以上、ラベル付き画像が1枚以上あると、データセットのヘッダーにReadyと表示されます。Not Readyをクリックすると、満たされていない条件を確認できます。

公開データセットから始める#

まだデータがありませんか?Exploreページには、公式データセットとコミュニティデータセットが掲載されています。データセットを複製すると、画像、アノテーション、クラスがワークスペースにコピーされ、ストレージを使用します。デフォルトでは元データセットと同じ公開範囲が引き継がれるため、機密情報を追加する場合はダイアログのスイッチを切り替えてください。
よくある落とし穴#
症状: アップロードは成功しますが、すべての画像がラベルなしで取り込まれます。 対処: PlatformはPascal VOC XMLを検出しますが、インポートしません。先にYOLOの.txtラベルまたはCOCO JSONに変換してください。アップロード前のチェックでは.xmlファイルの数が表示されるため、アップロード前に問題を把握できます。
症状: 検証mAPは非常に高いのに、デプロイしたモデルの性能は良くありません。 対処: 分割を選ばずにアップロードし、valが空の場合、Platformは学習画像の約20%をランダムにvalへ移動します。動画フレームでは、この方法により非常によく似た隣接フレームが両方の分割に入ります。代わりにtrain/とval/フォルダーに分け、動画またはカメラ単位で分割してアップロードしてください(レッスン4)。
症状: ポリゴンツールやキーポイントが見つかりません。 対処: タスクの種類によってツールが決まります。データセットのヘッダーからタスクの種類を変更してください。各画像にはすべてのタスクのラベルが保存されているため、切り替えによって他のタスクのラベルが非表示になるだけで、削除されることはありません。
解答を表示
医薬品データセットと4分間のラインカメラ動画を使った解答例です。アップロード前の確認結果は、train画像92枚、val画像23枚で、すべてラベル付き、問題はありません。動画は240秒で100秒を超えるため、間隔はceil(240 / 100) = 3秒に広がり、Platformは80フレームを保持します(0秒、3秒、…、237秒のフレーム)。予想されるギャラリーの画像数は、92 + 23 + 80 = 195枚です。動画フレームはラベルなしで、ギャラリーフィルターで選択されている分割に追加されるため、valに入らないように動画を追加する前にTrainを選択してください。train、val、ラベル付き画像がすべて存在するため、バッジにはReadyと表示されます。動画だけをアップロードした場合は、ラベル付き画像がないため、バッジにはNot Readyと表示されます。