Transformers 4.37 中文文档(五)(2)https://developer.aliyun.com/article/1565242
零样本目标检测
原文链接:
huggingface.co/docs/transformers/v4.37.2/en/tasks/zero_shot_object_detection
传统上,用于目标检测的模型需要标记的图像数据集进行训练,并且仅限于检测训练数据集中的类别集。
零样本目标检测由使用不同方法的 OWL-ViT 模型支持。OWL-ViT 是一个开放词汇的目标检测器。这意味着它可以基于自由文本查询在图像中检测对象,而无需在标记的数据集上对模型进行微调。
OWL-ViT 利用多模态表示执行开放词汇检测。它将 CLIP 与轻量级对象分类和定位头结合起来。通过将自由文本查询嵌入到 CLIP 的文本编码器中,并将其用作对象分类和定位头的输入,实现了开放词汇检测。关联图像及其相应的文本描述,ViT 将图像块作为输入进行处理。OWL-ViT 的作者首先从头开始训练 CLIP,然后使用二部匹配损失在标准目标检测数据集上端到端地微调 OWL-ViT。
通过这种方法,模型可以基于文本描述检测对象,而无需事先在标记的数据集上进行训练。
在本指南中,您将学习如何使用 OWL-ViT:
- 基于文本提示检测对象
- 用于批量目标检测
- 用于图像引导的目标检测
在开始之前,请确保已安装所有必要的库:
pip install -q transformers
零样本目标检测管道
尝试使用 OWL-ViT 进行推理的最简单方法是在 Hugging Face Hub 上的管道()中使用它。从Hugging Face Hub 上的检查点实例化一个零样本目标检测管道:
>>> from transformers import pipeline >>> checkpoint = "google/owlvit-base-patch32" >>> detector = pipeline(model=checkpoint, task="zero-shot-object-detection")
接下来,选择一个您想要检测对象的图像。这里我们将使用宇航员 Eileen Collins 的图像,该图像是NASA Great Images 数据集的一部分。
>>> import skimage >>> import numpy as np >>> from PIL import Image >>> image = skimage.data.astronaut() >>> image = Image.fromarray(np.uint8(image)).convert("RGB") >>> image
将图像和要查找的候选对象标签传递给管道。这里我们直接传递图像;其他合适的选项包括图像的本地路径或图像 url。我们还传递了所有要查询图像的项目的文本描述。
>>> predictions = detector( ... image, ... candidate_labels=["human face", "rocket", "nasa badge", "star-spangled banner"], ... ) >>> predictions [{'score': 0.3571370542049408, 'label': 'human face', 'box': {'xmin': 180, 'ymin': 71, 'xmax': 271, 'ymax': 178}}, {'score': 0.28099656105041504, 'label': 'nasa badge', 'box': {'xmin': 129, 'ymin': 348, 'xmax': 206, 'ymax': 427}}, {'score': 0.2110239565372467, 'label': 'rocket', 'box': {'xmin': 350, 'ymin': -1, 'xmax': 468, 'ymax': 288}}, {'score': 0.13790413737297058, 'label': 'star-spangled banner', 'box': {'xmin': 1, 'ymin': 1, 'xmax': 105, 'ymax': 509}}, {'score': 0.11950037628412247, 'label': 'nasa badge', 'box': {'xmin': 277, 'ymin': 338, 'xmax': 327, 'ymax': 380}}, {'score': 0.10649408400058746, 'label': 'rocket', 'box': {'xmin': 358, 'ymin': 64, 'xmax': 424, 'ymax': 280}}]
让我们可视化预测:
>>> 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
手动文本提示的零样本目标检测
现在您已经看到如何使用零样本目标检测管道,让我们手动复制相同的结果。
从Hugging Face Hub 上的检查点加载模型和相关处理器。这里我们将使用与之前相同的检查点:
>>> from transformers import AutoProcessor, AutoModelForZeroShotObjectDetection >>> model = AutoModelForZeroShotObjectDetection.from_pretrained(checkpoint) >>> processor = AutoProcessor.from_pretrained(checkpoint)
让我们选择不同的图像来改变一下。
>>> import requests >>> url = "https://unsplash.com/photos/oj0zeY2Ltk4/download?ixid=MnwxMjA3fDB8MXxzZWFyY2h8MTR8fHBpY25pY3xlbnwwfHx8fDE2Nzc0OTE1NDk&force=true&w=640" >>> im = Image.open(requests.get(url, stream=True).raw) >>> im
使用处理器为模型准备输入。处理器结合了一个图像处理器,通过调整大小和归一化来为模型准备图像,以及一个 CLIPTokenizer,负责处理文本输入。
>>> text_queries = ["hat", "book", "sunglasses", "camera"] >>> inputs = processor(text=text_queries, images=im, return_tensors="pt")
通过模型传递输入,后处理并可视化结果。由于图像处理器在将图像馈送到模型之前调整了图像的大小,因此您需要使用 post_process_object_detection()方法,以确保预测的边界框相对于原始图像具有正确的坐标:
>>> import torch >>> with torch.no_grad(): ... outputs = model(**inputs) ... target_sizes = torch.tensor([im.size[::-1]]) ... results = processor.post_process_object_detection(outputs, threshold=0.1, target_sizes=target_sizes)[0] >>> draw = ImageDraw.Draw(im) >>> scores = results["scores"].tolist() >>> labels = results["labels"].tolist() >>> boxes = results["boxes"].tolist() >>> for box, score, label in zip(boxes, scores, labels): ... xmin, ymin, xmax, ymax = box ... draw.rectangle((xmin, ymin, xmax, ymax), outline="red", width=1) ... draw.text((xmin, ymin), f"{text_queries[label]}: {round(score,2)}", fill="white") >>> im
批处理
您可以传递多组图像和文本查询以在多个图像中搜索不同(或相同)的对象。让我们一起使用宇航员图像和海滩图像。对于批处理,您应该将文本查询作为嵌套列表传递给处理器,并将图像作为 PIL 图像、PyTorch 张量或 NumPy 数组的列表。
>>> images = [image, im] >>> text_queries = [ ... ["human face", "rocket", "nasa badge", "star-spangled banner"], ... ["hat", "book", "sunglasses", "camera"], ... ] >>> inputs = processor(text=text_queries, images=images, return_tensors="pt")
以前,用于后处理的是将单个图像的大小作为张量传递,但您也可以传递一个元组,或者在有多个图像的情况下,传递一个元组列表。让我们为这两个示例创建预测,并可视化第二个示例(image_idx = 1
)。
>>> with torch.no_grad(): ... outputs = model(**inputs) ... target_sizes = [x.size[::-1] for x in images] ... results = processor.post_process_object_detection(outputs, threshold=0.1, target_sizes=target_sizes) >>> image_idx = 1 >>> draw = ImageDraw.Draw(images[image_idx]) >>> scores = results[image_idx]["scores"].tolist() >>> labels = results[image_idx]["labels"].tolist() >>> boxes = results[image_idx]["boxes"].tolist() >>> for box, score, label in zip(boxes, scores, labels): ... xmin, ymin, xmax, ymax = box ... draw.rectangle((xmin, ymin, xmax, ymax), outline="red", width=1) ... draw.text((xmin, ymin), f"{text_queries[image_idx][label]}: {round(score,2)}", fill="white") >>> images[image_idx]
Transformers 4.37 中文文档(五)(4)https://developer.aliyun.com/article/1565244