编译:ronghuaiyang

导读

在这篇指南中,我们将深入理解这款由微软发布的名为Florence-2的模型,它旨在办理多种不同的视觉任务。

弁言

原始Transformer的引入为当前的大型措辞模型铺平了道路。
同样,在引入变换器模型之后,视觉变换器(ViT)也被提出。
就像善于理解文本和根据相应天生文本的变换器一样,视觉变换器模型被开拓出来以理解图像并根据图像供应信息。
这些发展导致了视觉措辞模型的涌现,这些模型善于理解图像。
微软在此根本上又迈出了一步,推出了一款能够用单一模型完成多种视觉任务的模型。
在这篇指南中,我们将深入理解这款由微软发布的名为Florence-2的模型,它旨在办理多种不同的视觉任务。

若何运用Florence2来做计算机视觉责任

学习目标先容Florence-2,一款视觉措辞模型。
理解Florence-2演习所利用的数据。
理解Florence-2家族中的不同模型。
学习如何下载Florence-2。
编写代码以利用Florence-2实行不同的打算机视觉任务。
什么是Florence-2?

Florence-2是由微软团队开拓的一款视觉措辞模型(VLM)。
Florence-2有两种大小版本:一种是0.23B版本,另一种是0.77B版本。
这两个模型的尺寸都较小,使得每个人都可以在CPU上运行这些模型。
Florence-2的设计理念是单个模型能够办理多种问题。
Florence-2被演习来办理不同的任务,包括物体检测、物体分割、图像标题天生(乃至是天生详细的标题)、短语分割、OCR(光学字符识别),以及这些任务的组合。

Florence-2视觉措辞模型是在FLD 5B数据集上演习的。
这个FLD-5B数据集是由微软团队创建的。
该数据集包含大约1.26亿张图像上的54亿条文本注释。
个中包括13亿条文本区域注释、5亿条文本注释和36亿条文本短语区域注释。
Florence-2接管文本指令和图像输入,为诸如OCR、物体检测或图像标题天生等任务天生文本结果。

该架构包含一个视觉编码器,随后是一个Transformer编码解码器块;对付丢失函数,它们采取标准的交叉熵丢失。
Florence-2模型实行三种类型的区域检测:用于物体检测的框表示、用于OCR文本检测的四边形框表示以及用于分割任务的多边形表示。

利用Florence-2进行图像标题天生

图像标题天生是一项视觉措辞任务,给定一张图像,深度学习模型将输出关于该图像的标题。
这个标题可以是简短的也可以是非常详细的,取决于模型的演习情形。
实行此类任务的模型是在大量的图像标题数据上进行演习的,在这里它们学习如何根据给定的图像输出文本。
它们演习的数据越多,就越能更好地描述图像。

下载和安装

我们将从下载和安装一些我们须要运行Florence视觉模型的库开始。

!pip install -q -U transformers accelerate flash_attn einops timmtransformers: HuggingFace 的 Transformers 库供应了多种用于不同任务的深度学习模型,您可以下载这些模型。
accelerate: HuggingFace 的 Accelerate 库通过GPU加速模型推理韶光,从而提高模型做事的速率。
flash_attn: Flash Attention 库实现了比原始算法更快的把稳力机制,并在 Florence-2 模型中利用。
einops: Einstein Operations 简化了矩阵乘法的表示,并在 Florence-2 模型中实现。
下载Florence-2模型

现在,我们须要下载Florence-2模型。
为此,我们将利用以下代码。

from transformers import AutoProcessor, AutoModelForCausalLMmodel_id = 'microsoft/Florence-2-large-ft'model = AutoModelForCausalLM.from_pretrained(model_id, trust_remote_code=True).eval().cuda()processor = AutoProcessor.from_pretrained(model_id, trust_remote_code=True, device_map="cuda")我们首先导入 AutoModelForCausalLM 和 AutoProcessor。
然后我们将模型名称存储在变量 model_name 中。
在这里,我们将利用 Florence-2 大型微调模型。
接着我们通过调用 .from_pretrained() 函数并传入模型名称以及设置 trust_remote_code=True 来创建 AutoModelForCausalLM 的实例,这将从 HuggingFace 仓库下载模型。
然后我们通过调用 .eval() 将模型设置为评估模式,并通过调用 .cuda() 将其发送到 GPU。
接下来我们通过调用 .from_pretrained() 并传入模型名称以及设置 device_map 为 cuda 来创建 AutoProcessor 的实例。

AutoProcessor 类似于 AutoTokenizer。
但是 AutoTokenizer 类处理文本和文本分词。
而 AutoProcessor 则处理文本和图像分词,由于 Florence-2 处理图像数据,以是我们利用 AutoProcessor。

现在,让我们选取一张图像:

from PIL import Imageimage = Image.open("/content/beach.jpg")

天生标题

现在我们将这张图像供应给 Florence-2 视觉措辞模型,并哀求它天生一个标题。

PROMPT = "<CAPTION>"inputs = processor(text=PROMPT, images=image, return_tensors="pt").to("cuda")generated_ids = model.generate( input_ids=inputs["input_ids"], pixel_values=inputs["pixel_values"], max_new_tokens=512, do_sample=False,)text_generations = processor.batch_decode(generated_ids, skip_special_tokens=False)[0]result = processor.post_process_generation(text_generations, task=PROMPT, image_size=(image.width, image.height))print(result[PROMPT])

我们首先创建提示。
然后,我们将提示和图像一起供应给处理器类,并返回 PyTorch 张量。
我们将它们发送到 GPU,由于模型位于 GPU 上,并将其存储在变量 inputs 中。
inputs 变量包含 input_ids(即token ID)和图像的像素值。
然后我们调用模型的 generate 函数,并传入 input_ids 和图像像素值。
我们将最大天生token数设置为 512,将采样设置为 False,并将天生的token存储在 generated_ids 中。
然后我们调用处理器的 .batch_decode 函数,传入 generated_ids 并将 skip_special_tokens 标志设置为 False。
这将返回一个列表,因此我们须要列表的第一个元素。
末了,我们通过调用 .post_process_generated 并传入天生的文本、任务类型以及图像尺寸作为元组来对天生的文本进行后处理。

运行代码并查看上面的输出图片,我们可以看到模型为这张图像天生的标题是“An umbrella and lounge chair on a beach with the ocean in the background”。
上面的图像标题非常简短。

供应提示

我们可以进一步通过供应其他提示,如 <DETAILED_CAPTION> 和 <MORE_DETAILED_CAPTION> 来考试测验。

考试测验这种方法的代码如下:

PROMPT = "<DETAILED_CAPTION>"inputs = processor(text=PROMPT, images=image, return_tensors="pt").to("cuda")generated_ids = model.generate( input_ids=inputs["input_ids"], pixel_values=inputs["pixel_values"], max_new_tokens=512, do_sample=False,)text_generations = processor.batch_decode(generated_ids, skip_special_tokens=False)[0]result = processor.post_process_generation(text_generations, task=PROMPT, image_size=(image.width, image.height))print(result[PROMPT])

PROMPT = "<MORE_DETAILED_CAPTION>"inputs = processor(text=PROMPT, images=image, return_tensors="pt").to("cuda")generated_ids = model.generate( input_ids=inputs["input_ids"], pixel_values=inputs["pixel_values"], max_new_tokens=512, do_sample=False,)text_generations = processor.batch_decode(generated_ids, skip_special_tokens=False)[0]result = processor.post_process_generation(text_generations, task=PROMPT, image_size=(image.width, image.height))print(result[PROMPT])

在这里,我们利用了 <DETAILED_CAPTION> 和 <MORE_DETAILED_CAPTION> 作为任务类型,并可以在上面的图片中看到运行代码后的结果。
<DETAILED_CAPTION> 产生了输出 “In this image we can see a chair, table, umbrella, water, ships, trees, building and sky with clouds.”,而 <MORE_DETAILED_CAPTION> 提示产生了输出 “An orange umbrella is on the beach. There is a white lounge chair next to the umbrella. There are two boats in the water.” 因此,通过这两个提示,我们可以在图像标题天生中得到更多的细节,而不是常规的提示。

利用Florence-2进行物体检测

物体检测是打算机视觉中一个广为人知的任务。
它涉及到根据一张图像找到某个物体。
在物体检测中,模型识别图像并供应环绕物体的边界框的 X 和 Y 坐标。
Florence-2 视觉措辞模型非常能够根据图像检测物体。

让我们考试测验利用下面这张图像:

image = Image.open("/content/van.jpg")

在这里,我们有一张图像,图中是一辆通亮的橙色面包车在路上行驶,背景是一座白色的建筑。

向Florence-2视觉措辞模型供应图像

现在让我们将这张图像供应给 Florence-2 视觉措辞模型。

PROMPT = "<OD>"inputs = processor(text=PROMPT, images=image, return_tensors="pt").to("cuda")generated_ids = model.generate( input_ids=inputs["input_ids"], pixel_values=inputs["pixel_values"], max_new_tokens=512, do_sample=False,)text_generations = processor.batch_decode(generated_ids, skip_special_tokens=False)[0]results = processor.post_process_generation(text_generations, task=PROMPT, image_size=(image.width, image.height))

物体检测的过程与我们刚刚完成的图像标题任务非常相似。
唯一的差异是我们将提示改为 <OD>,意味着物体检测。
因此,我们将这个提示连同图像一起供应给处理器工具,以获取标记化的输入。
然后我们将这些标记化的输入以及图像像素值供应给 Florence-2 视觉措辞模型以天生输出。
然后解码这个输出。

输出存储在名为 results 的变量中。
变量 results 的格式为 { ": { 'bboxes': [[x1, y1, x2, y2], ...], 'labels': ['label1', 'label2', ...] } }。
因此,Florence-2 视觉模型为每个标签输出边界框的 X、Y 坐标,即为图像中检测到的每个物体。

在图像上绘制边界框

现在,我们将利用我们得到的坐标在图像上绘制这些边界框。

import matplotlib.pyplot as pltimport matplotlib.patches as patchesfig, ax = plt.subplots()ax.imshow(image)for bbox, label in zip(results[PROMPT]['bboxes'], results[PROMPT]['labels']): x1, y1, x2, y2 = bbox rect_box = patches.Rectangle((x1, y1), x2-x1, y2-y1, linewidth=1, edgecolor='r', facecolor='none') ax.add_patch(rect_box) plt.text(x1, y1, label, color='white', fontsize=8, bbox=dict(facecolor='red', alpha=0.5))ax.axis('off')plt.show()

为了在图像周围绘制矩形边界框,我们利用 matplotlib 库。
我们首先创建一个图形和一个轴,然后显示我们供应给 Florence-2 视觉措辞模型的图像。
这里,模型输出的边界框是一个包含 X 和 Y 坐标的列表,在终极输出中,有一个边界框列表,也便是说每个标签都有自己的边界框。
因此,我们遍历边界框列表。
然后我们解包边界框的 X 和 Y 坐标。
然后我们利用上一步解包的坐标绘制一个矩形。
末了,我们将这个矩形添加到我们正在显示的图像上。
我们还须要在边界框上添加一个标签,以指示边界框包含什么物体。
末了,我们移除轴。

运行这段代码并查看图片,我们可以看到 Florence-2 视觉措辞模型为我们供应的面包车图像天生了大量的边界框。
我们看到模型检测到了面包车、窗户和轮子,并且能够为每个标签给出精确的坐标。

标题到短语定位

接下来,我们有一个被称为“标题到短语定位”的任务,这是 Florence-2 模型支持的。
模型的事情办法是,给定一张图像和它的标题,短语定位的任务是找出标题中提到的每个/最干系的实体/工具对应图像中的区域。

我们可以通过以下代码来看看这个任务:

PROMPT = "<CAPTION_TO_PHRASE_GROUNDING> An orange van parked in front of a white building"task_type = "<CAPTION_TO_PHRASE_GROUNDING>"inputs = processor(text=PROMPT, images=image, return_tensors="pt").to("cuda")generated_ids = model.generate( input_ids=inputs["input_ids"], pixel_values=inputs["pixel_values"], max_new_tokens=512, do_sample=False,)text_generations = processor.batch_decode(generated_ids, skip_special_tokens=False)[0]results = processor.post_process_generation(text_generations, task=task_type, image_size=(image.width, image.height))

在这里,对付提示,我们给出的是 “<CAPTION_TO_PHRASE_GROUNDING> An orange van parked in front of a white building”,个中任务是 “<CAPTION_TO_PHRASE_GROUNDING>”,短语是 “An orange van parked in front of a white building”。
Florence 模型试图为从给定短语中提取的工具/实体天生边界框。
让我们通过绘制结果来看看终极输出。

import matplotlib.pyplot as pltimport matplotlib.patches as patchesfig, ax = plt.subplots()ax.imshow(image)for bbox, label in zip(results[task_type]['bboxes'], results[task_type]['labels']): x1, y1, x2, y2 = bbox rect_box = patches.Rectangle((x1, y1), x2-x1, y2-y1, linewidth=1, edgecolor='r', facecolor='none') ax.add_patch(rect_box) plt.text(x1, y1, label, color='white', fontsize=8, bbox=dict(facecolor='red', alpha=0.5))ax.axis('off')plt.show()

在这里,我们可以看到 Florence-2 视觉措辞模型能够从中提取两个实体。
一个是橙色的面包车,另一个是白色的建筑。
然后 Florence-2 为这些实体天生了边界框。
这样,给定一个标题,模型可以从标题中提取干系实体/工具,并能够为这些工具天生相应的边界框。

利用Florence-2进行分割

分割是一个过程,个中取一张图像并为图像的多个部分天生掩码。
每个掩码都是一个物体。
分割是物体检测的下一阶段。
在物体检测中,我们只找到图像的位置并天生边界框。
但在分割中,不是天生矩形边界框,而是天生与物体形状相匹配的掩码,就像为那个物体创建一个掩码一样。
这很有帮助,由于我们不仅知道物体的位置,还知道物体的形状。
幸运的是,Florence-2 视觉措辞模型支持分割。

对图像进行分割

我们将考试测验对我们的面包车图像进行分割。

PROMPT = "<REFERRING_EXPRESSION_SEGMENTATION>two black tires"task_type = "<REFERRING_EXPRESSION_SEGMENTATION>"inputs = processor(text=PROMPT, images=image, return_tensors="pt").to("cuda")generated_ids = model.generate( input_ids=inputs["input_ids"], pixel_values=inputs["pixel_values"], max_new_tokens=512, do_sample=False,)text_generations = processor.batch_decode(generated_ids, skip_special_tokens=False)[0]results = processor.post_process_generation(text_generations, task=task_type, image_size=(image.width, image.height))这里的过程类似于图像标题天生和物体检测任务。
我们首先供应提示。
这里的提示是 “<REFERRING_EXPRESSION_SEGMENTATION>two black tires”,个中任务是分割。
分割将基于供应的文本输入,这里是 “two black tires”。
因此,Florence-2 模型将考试测验天生与这个文本输入和供应的图像紧密干系的掩码。

这里的结果变量格式为 {": { 'Polygons': [[[polygon]], ...], 'labels': ['', '', ...] }}",个中每个工具/掩码由一组多边形表示。
每个多边形的形式为 [x1,y1,x2,y2,...xn,yn]。

创建掩码并在实际图像上叠加

现在,我们将创建这些掩码并在实际图像上叠加,以便更好地可视化它们。

import copyimport numpy as npfrom IPython.display import displayfrom PIL import Image, ImageDraw, ImageFontoutput_image = copy.deepcopy(image)res = results[task_type]draw = ImageDraw.Draw(output_image)scale = 1for polygons, label in zip(res['polygons'], res['labels']): fill_color = "blue" for _polygon in polygons: _polygon = np.array(_polygon).reshape(-1, 2) if len(_polygon) < 3: print('Invalid polygon:', _polygon) continue _polygon = (_polygon scale).reshape(-1).tolist() draw.polygon(_polygon, outline="indigo", fill=fill_color) draw.text((_polygon[0] + 8, _polygon[1] + 2), label, fill="indigo")display(output_image)

阐明

首先,我们从 PIL 库导入各种工具用于图像处理。
我们创建原始图像的一个深拷贝,并将 “<REFERRING_EXPRESSION_SEGMENTATION>” 的值存储在一个新变量中。
接下来,我们通过调用 .Draw() 方法并传入实际图像的副本创建一个 ImageDraw 实例来加载图像。
然后,我们遍历多边形和标签值的组合。
对付每个多边形,我们遍历单个多边形 _polygon 并对其进行重塑。
此时 _polygon 是一个多维列表。
我们知道一个多边形至少有三个顶点,这样才能连接起来。
因此,我们检讨有效性条件,确保 _polygon 列表至少有三个列表项。
末了,我们通过调用 .polygon() 方法并传入 _polygon 来在实际图像的副本上绘制该多边形。
同时我们还指定轮廓颜色和添补颜色。
如果 Florence-2 视觉措辞模型为这些多边形天生了标签,那么我们还可以通过调用 .text() 函数并传入标签来在实际图像的副本上绘制这些文本。
末了,在绘制完 Florence-2 模型天生的所有多边形之后,我们通过调用 IPython 库的 display 函数来输出图像。

Florence-2 视觉措辞模型成功地理解了我们的查询 “two black tires”,并且推断出图像中包含了一辆具有可见玄色轮胎的车辆。
模型为这些轮胎天生了多边形表示,并用蓝色进行了遮罩。
由于 Microsoft 团队精心准备的强大演习数据,该模型在多样化的打算机视觉任务中表现出色。

结论

Florence-2 是由 Microsoft 团队从零开始创建和演习的视觉措辞模型。
与其他视觉措辞模型不同,Florence-2 实行各种打算机视觉任务,包括物体检测、图像标题天生、短语物体检测、OCR、分割以及这些任务的组合。
在这篇指南中,我们理解了如何下载 Florence-2 大型模型以及如何利用不同的提示与 Florence-2 进行不同的打算机视觉任务。

关键要点Florence-2 模型有两个版本。
一种是根本版,拥有 0.23 亿参数;另一种是大型版,拥有 0.7 亿参数。
Microsoft 团队在 FLD 5B 数据集上演习了 Florence-2 模型,这是一个包含不同图像任务的图像数据集,由 Microsoft 团队创建。
Florence-2 接管图像和提示作为输入。
提示定义了 Florence-2 视觉模型应实行的任务类型。
每个任务都会天生不同的输出,所有这些输出都以文本格式天生。
Florence-2 是一个开源模型,采取 MIT 容许证,因此可以用于商业运用。

—END—

英文原文:https://www.analyticsvidhya.com/blog/2024/07/how-to-perform-computer-vision-tasks-with-florence-2/