Transformers documentation

Phát hiện đối tượng zero-shot

You are viewing main version, which requires installation from source. If you'd like regular pip install, checkout the latest stable version (v5.22.2).
Hugging Face's logo
Join the Hugging Face community

and get access to the augmented documentation experience

to get started

Phát hiện đối tượng zero-shot

Truyền thống, các mô hình được sử dụng cho phát hiện đối tượng yêu cầu các bộ dữ liệu ảnh có nhãn để huấn luyện, và bị giới hạn trong việc phát hiện tập hợp các lớp từ dữ liệu huấn luyện.

Phát hiện đối tượng zero-shot là một tác vụ thị giác máy tính nhằm phát hiện các đối tượng và lớp của chúng trong hình ảnh, mà không cần bất kỳ quá trình huấn luyện hay kiến thức trước nào về các lớp đó. Các mô hình phát hiện đối tượng zero-shot nhận vào một hình ảnh, cùng với một danh sách các lớp ứng viên, và đưa ra các hộp bao (bounding box) cùng nhãn tại các vị trí mà đối tượng được phát hiện.

Hugging Face lưu trữ nhiều trình phát hiện đối tượng zero-shot có từ vựng mở như vậy.

Trong hướng dẫn này, bạn sẽ học cách sử dụng các mô hình như vậy:

  • để phát hiện các đối tượng dựa trên các câu lệnh văn bản
  • cho đối tượng phát hiện theo lô
  • cho phát hiện đối tượng có dẫn hướng bằng hình ảnh

Trước khi bắt đầu, hãy đảm bảo bạn đã cài đặt tất cả các thư viện cần thiết:

pip install -q transformers

Đường ống phát hiện đối tượng Zero-shot

Cách đơn giản nhất để thử nghiệm suy luận với các mô hình là sử dụng chúng trong một pipeline(). Khởi tạo một pipeline cho phát hiện đối tượng zero-shot từ một checkpoint trên Hugging Face Hub:

>>> from transformers import pipeline

>>> # Use any checkpoint from the hf.co/models?pipeline_tag=zero-shot-object-detection
>>> checkpoint = "iSEE-Laboratory/llmdet_large"
>>> detector = pipeline(model=checkpoint, task="zero-shot-object-detection")

Tiếp theo, hãy chọn một hình ảnh mà bạn muốn phát hiện các đối tượng trong đó. Ở đây, chúng ta sẽ sử dụng hình ảnh của phi hành gia Eileen Collins, một phần của bộ dữ liệu Great Images của NASA.

>>> from transformers.image_utils import load_image

>>> url = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/zero-sh-obj-detection_1.png"
>>> image = load_image(url)
>>> image
Astronaut Eileen Collins

Truyền vào pipeline hình ảnh và các nhãn đối tượng ứng viên cần tìm. Ở đây chúng ta truyền hình ảnh trực tiếp; các tùy chọn phù hợp khác bao gồm đường dẫn cục bộ đến một hình ảnh hoặc một url hình ảnh. Chúng ta cũng truyền các mô tả văn bản cho tất cả các mục mà chúng ta muốn truy vấn trên hình ảnh.

>>> predictions = detector(
...     image,
...     candidate_labels=["human face", "rocket", "nasa badge", "star-spangled banner"],
...     threshold=0.45,
... )
>>> predictions
[{'score': 0.8409242033958435,
  'label': 'human face',
  'box': {'xmin': 179, 'ymin': 74, 'xmax': 272, 'ymax': 179}},
 {'score': 0.7380027770996094,
  'label': 'rocket',
  'box': {'xmin': 353, 'ymin': 0, 'xmax': 466, 'ymax': 284}},
 {'score': 0.5850900411605835,
  'label': 'star-spangled banner',
  'box': {'xmin': 0, 'ymin': 0, 'xmax': 96, 'ymax': 511}},
 {'score': 0.5697067975997925,
  'label': 'human face',
  'box': {'xmin': 18, 'ymin': 15, 'xmax': 366, 'ymax': 511}},
 {'score': 0.47813931107521057,
  'label': 'star-spangled banner',
  'box': {'xmin': 353, 'ymin': 0, 'xmax': 459, 'ymax': 274}},
 {'score': 0.46597740054130554,
  'label': 'nasa badge',
  'box': {'xmin': 353, 'ymin': 0, 'xmax': 462, 'ymax': 279}},
 {'score': 0.4585932493209839,
  'label': 'nasa badge',
  'box': {'xmin': 132, 'ymin': 348, 'xmax': 208, 'ymax': 423}}]

Hãy trực quan hóa các dự đoán:

>>> from PIL import ImageDraw

>>> draw = ImageDraw.Draw(image)

>>> for prediction in predictions:
...     box = prediction["box"]
...     label = prediction["label"]
...     score = prediction["score"]

...     xmin, ymin, xmax, ymax = box.values()
...     draw.rectangle((xmin, ymin, xmax, ymax), outline="red", width=1)
...     draw.text((xmin, ymin), f"{label}: {round(score,2)}", fill="white")

>>> image
Visualized predictions on NASA image

Phát hiện đối tượng zero-shot theo văn bản bằng tay

Giờ đây, khi bạn đã thấy cách sử dụng pipeline phát hiện đối tượng zero-shot, hãy cùng tái tạo lại kết quả tương tự một cách thủ công.

Bắt đầu bằng cách tải model và processor liên quan từ một checkpoint trên Hugging Face Hub. Ở đây chúng ta sẽ sử dụng cùng một checkpoint như trước đó:

>>> from transformers import AutoProcessor, AutoModelForZeroShotObjectDetection

>>> model = AutoModelForZeroShotObjectDetection.from_pretrained(checkpoint, device_map="auto")
>>> processor = AutoProcessor.from_pretrained(checkpoint)

Hãy thử một hình ảnh khác để thay đổi không khí.

>>> url = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/zero-sh-obj-detection_3.png"
>>> image = load_image(url)
>>> image
Beach photo

Sử dụng processor để chuẩn bị các đầu vào cho model.

>>> text_labels = ["hat", "book", "sunglasses", "camera"]
>>> inputs = processor(text=text_labels, images=image, return_tensors="pt").to(model.device)

Đưa các đầu vào qua mô hình, xử lý hậu kỳ và trực quan hóa kết quả. Vì bộ xử lý ảnh đã thay đổi kích thước ảnh trước khi đưa vào mô hình, bạn cần sử dụng phương thức post_process_object_detection để đảm bảo các khung bao dự đoán có tọa độ chính xác so với ảnh gốc:

>>> import torch

>>> with torch.inference_mode():
...     outputs = model(**inputs)

>>> results = processor.post_process_grounded_object_detection(
...    outputs, threshold=0.50, target_sizes=[(image.height, image.width)], text_labels=text_labels,
... )[0]

>>> draw = ImageDraw.Draw(image)

>>> scores = results["scores"]
>>> text_labels = results["text_labels"]
>>> boxes = results["boxes"]

>>> for box, score, text_label in zip(boxes, scores, text_labels):
...     xmin, ymin, xmax, ymax = box
...     draw.rectangle((xmin, ymin, xmax, ymax), outline="red", width=1)
...     draw.text((xmin, ymin), f"{text_label}: {round(score.item(),2)}", fill="white")

>>> image
Beach photo with detected objects

Xử lý theo lô

Bạn có thể truyền nhiều bộ ảnh và truy vấn văn bản để tìm kiếm các đối tượng khác nhau (hoặc giống nhau) trong nhiều ảnh. Hãy sử dụng cả ảnh phi hành gia và ảnh bãi biển cùng nhau. Để xử lý theo lô, bạn nên truyền các truy vấn văn bản dưới dạng danh sách lồng nhau vào bộ xử lý và truyền các ảnh dưới dạng danh sách ảnh PIL, tensor PyTorch, hoặc mảng NumPy.

>>> url1 = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/zero-sh-obj-detection_1.png"
>>> url2 = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/transformers/tasks/zero-sh-obj-detection_3.png"
>>> images = [load_image(url1), load_image(url2)]
>>> text_queries = [
...     ["human face", "rocket", "nasa badge", "star-spangled banner"],
...     ["hat", "book", "sunglasses", "camera", "can"],
... ]
>>> inputs = processor(text=text_queries, images=images, return_tensors="pt", padding=True)

Trước đây, để xử lý hậu xử lý, bạn truyền kích thước của một ảnh duy nhất dưới dạng tensor, nhưng bạn cũng có thể truyền một tuple, hoặc, trong trường hợp có nhiều ảnh, một danh sách các tuple. Hãy tạo các dự đoán cho hai ví dụ và trực quan hóa ví dụ thứ hai (image_idx = 1).

>>> with torch.no_grad():
>>>     outputs = model(**inputs)

>>> target_sizes = [(image.height, image.width) for image in images]
>>> results = processor.post_process_grounded_object_detection(
...     outputs, threshold=0.3, target_sizes=target_sizes, text_labels=text_labels,
... )

Hãy trực quan hóa kết quả:

>>> image_idx = 1
>>> draw = ImageDraw.Draw(images[image_idx])

>>> scores = results[image_idx]["scores"].tolist()
>>> text_labels = results[image_idx]["text_labels"]
>>> boxes = results[image_idx]["boxes"].tolist()

>>> for box, score, text_label in zip(boxes, scores, text_labels):
>>>     xmin, ymin, xmax, ymax = box
>>>     draw.rectangle((xmin, ymin, xmax, ymax), outline="red", width=1)
>>>     draw.text((xmin, ymin), f"{text_label}: {round(score,2)}", fill="white")

>>> images[image_idx]
Beach photo with detected objects

Phát hiện đối tượng có hướng dẫn bằng hình ảnh

Ngoài việc phát hiện đối tượng zero-shot bằng truy vấn văn bản, các mô hình như OWL-ViT và OWLv2 còn cung cấp phát hiện đối tượng có sự dẫn dắt của hình ảnh. Điều này có nghĩa là bạn có thể sử dụng truy vấn hình ảnh để tìm các đối tượng tương tự trong hình ảnh đích.

>>> from transformers import AutoProcessor, AutoModelForZeroShotObjectDetection

>>> checkpoint = "google/owlv2-base-patch16-ensemble"
>>> model = AutoModelForZeroShotObjectDetection.from_pretrained(checkpoint, device_map="auto")
>>> processor = AutoProcessor.from_pretrained(checkpoint)

Khác với truy vấn văn bản, chỉ cho phép một hình ảnh ví dụ duy nhất.

Hãy lấy một hình ảnh có hai con mèo trên ghế sofa làm hình ảnh đích, và một hình ảnh có một con mèo duy nhất làm truy vấn:

>>> url = "http://images.cocodataset.org/val2017/000000039769.jpg"
>>> image_target = Image.open(requests.get(url, stream=True).raw)

>>> query_url = "http://images.cocodataset.org/val2017/000000524280.jpg"
>>> query_image = Image.open(requests.get(query_url, stream=True).raw)

Hãy cùng xem nhanh các hình ảnh:

>>> import matplotlib.pyplot as plt

>>> fig, ax = plt.subplots(1, 2)
>>> ax[0].imshow(image_target)
>>> ax[1].imshow(query_image)
>>> fig.show()
Cats

Trong bước tiền xử lý, thay vì truy vấn văn bản, bạn giờ cần sử dụng query_images:

>>> inputs = processor(images=image_target, query_images=query_image, return_tensors="pt")

Đối với dự đoán, thay vì truyền các đầu vào vào mô hình, hãy truyền chúng vào image_guided_detection(). Vẽ các dự đoán như trước, ngoại trừ giờ đây không còn nhãn.

>>> with torch.no_grad():
...     outputs = model.image_guided_detection(**inputs)
...     target_sizes = torch.tensor([image_target.size[::-1]])
...     results = processor.post_process_image_guided_detection(outputs=outputs, target_sizes=target_sizes)[0]

>>> draw = ImageDraw.Draw(image_target)

>>> scores = results["scores"].tolist()
>>> boxes = results["boxes"].tolist()

>>> for box, score in zip(boxes, scores):
...     xmin, ymin, xmax, ymax = box
...     draw.rectangle((xmin, ymin, xmax, ymax), outline="white", width=4)

>>> image_target
Cats with bounding boxes
Update on GitHub