One-Shot Learning
ワンショット学習は、通常は埋め込みを比較することで、ラベル付きの例を1つだけ使って新しいクラスを認識します。シャムネットワーク、用途、コードを解説します。
ワンショット学習とは、ラベル付きのサンプル1つから新しいクラスを認識するタスクです。従来の画像分類モデルでは、クラスごとに数百枚のラベル付き画像が必要で、クラスを追加するたびに再学習が必要ですが、人は新しい顔や商品を一度見ただけで認識できることがよくあります。ワンショットシステムは、以前に学習した多くのクラスから知識を再利用することで、その能力に近づきます。そうしたクラスで学習したネットワークは、画像を埋め込みに変換し、同じ物の画像が近くに配置されるため、1つのサンプルだけで新しいクラスの位置を示せます。顔認証、署名照合、商品認識はすべてこの方法で動作します。また、大規模言語モデル(LLM)では、ワンショットプロンプトにタスクの実例を1つ含めます。
ワンショット学習の仕組み#
ほとんどのワンショットシステムは、分類を比較に置き換えます。ニューラルネットワークが保存済みサンプルと新しい各クエリに対して特徴抽出を行い、ユークリッド距離やコサイン類似度などで2つの埋め込み間の距離を測定して、一致するかどうかを判断します。シャムニューラルネットワークは、同じ重みを共有する2つのブランチを用いてこの仕組みを形式化します。Jane Bromley、Yann LeCunらは1993年に署名照合でこれを使用し、Gregory Kochらは2015年に、各アルファベットの例を1つ見ただけで新しいアルファベットの手書き文字を分類するネットワークを学習しました。
埋め込みネットワークは、他の多くのクラスを使って事前に学習されます。コントラスト損失やトリプレット損失によって同じクラスの画像を近づけ、異なるクラスの画像を遠ざけるため、学習した距離は後から現れるクラスにも汎化します。メタ学習やMatching Networksなどの手法では、クラスごとに1つの例を持つ複数クラスのワンショットタスクを何千個もシミュレーションして学習し、モデルが実際に直面する問題をそのまま練習します。
埋め込みを使ったワンショット分類#
Ultralytics YOLO26の分類モデルは、分類ヘッドの前のレイヤーの出力をプーリングして画像ごとに1つのベクトルにまとめ、embed()を通じて画像埋め込みを返します。この例では、埋め込みからCIFAR-10の10クラスワンショット分類器を構築します。保存する画像はクラスごとに1枚だけで、それが唯一のラベル付きデータです。各クエリには、最も類似した保存済み画像のラベルを割り当てます。
from pathlib import Path
import torch
import torch.nn.functional as F
from torchvision.datasets.utils import download_and_extract_archive
from ultralytics import YOLO
# CIFAR-10 test images, one folder per class
download_and_extract_archive("https://github.com/ultralytics/assets/releases/download/v0.0.0/cifar10.zip", "data")
images = [sorted(folder.glob("*.png")) for folder in sorted(Path("data/cifar10/test").iterdir()) if folder.is_dir()]
model = YOLO("yolo26n-cls.pt")
# Support set: the first image of each class is its only labeled example (one shot)
shots = torch.stack([model.embed(paths[0], verbose=False)[0] for paths in images])
# Query set: the next 50 images of each class, each labeled with the class of its most similar shot
correct = 0
for label, paths in enumerate(images):
for path in paths[1:51]:
query = model.embed(path, verbose=False)[0]
correct += F.cosine_similarity(shots, query.unsqueeze(0)).argmax().item() == label
print(f"10-way 1-shot accuracy: {correct / 500:.1%} (random guessing: 10%)")モデルはCIFAR-10で学習していないため、表示される精度は、クラスごとに1つの例でYOLO26の埋め込み空間内のクラスをどれほど適切に定義できるかを測定します。11番目のクラスを追加するには、埋め込みをもう1つ保存するだけです。
用途#
- 顔認証: 自動国境ゲートは、ライブカメラの画像とパスポートのチップに保存された写真1枚を照合します。また、スマートフォンや入退室管理システムは、試行のたびに登録時の顔と照合します。
- 小売商品の認識: 店舗では商品が絶えず追加されますが、商品ごとにカタログ写真が1枚あれば、再学習せずに棚の商品を認識できます。
- ワンショット模倣学習: ロボットは、ブロックを新しい順序で積むなど、新しいタスクの実行例を1回見るだけで、そのタスクを実行するように学習します。
課題#
サンプル1つではクラスの多様性を示せないため、照明が悪い場所や見慣れない角度で撮影した写真、または物体の一部が隠れた写真を参照にすると、その後のすべての比較で基準が不適切になります。一致判定のしきい値は誤受け入れと誤拒否のバランスを決めるため、用途ごとに検証用ペアで調整する必要があります。また、日常写真など1つのドメインで学習した埋め込みは、医療画像など別のドメインではクラスをうまく分離できません。
ワンショット学習と関連用語#
- 少数ショット学習: クラスごとに少数のラベル付きサンプルから学習する一般的な問題です。ワンショット学習はサンプルが正確に1つの場合で、N-way K-shot表記では1-shotと記します。
- ゼロショット学習: 例を一切使わず、テキストまたは属性の説明からクラスを認識します。
- 転移学習: 事前学習済みモデルを新しいタスクに再利用し、通常は多くのラベル付きサンプルでファインチューニングします。ワンショットシステムも転移された特徴を利用しますが、重みを更新せずに特徴を直接比較します。
- 異常検知: 正常な状態を学習し、そこから大きく外れたものにフラグを付けます。対象がどのクラスに属するかではなく、異常かどうかを判定します。










