Florence-2 VLM简明教程

近年来,计算机视觉领域见证了基础模型的兴起,这些模型无需训练自定义模型即可进行图像注释。我们已经看到了用于分类的 CLIP [2]、用于对象检测的 GroundingDINO [3] 和用于分割的 SAM [4] 等模型——每个模型都在其领域表现出色。但是,如果我们有一个能够同时处理所有这些任务的单一模型会怎样?

在本教程中,我们将介绍 Florence-2 [1]——一种新颖的开源视觉语言模型 (VLM),旨在处理各种视觉和多模态任务,包括字幕、对象检测、分割和 OCR。

结合 Colab 笔记本,我们将探索 Florence-2 的零样本功能,以标注旧相机的图像。

1、Florence-2简介

Florence-2 由微软于 2024 年 6 月发布。它旨在在单个模型中执行多项视觉任务。它是一个开源模型,在 Hugging Face 上根据宽松的 MIT 许可证提供。

1.1 背景

尽管 Florence-2 的规模相对较小,但其版本参数分别为 0.23B 和 0.77B,实现了最先进 (SOTA) 的性能。其紧凑的尺寸使其能够在计算资源有限的设备上高效部署,同时确保快速的推理速度。

该模型在一个名为 FLD-5B 的庞大高质量数据集上进行了预训练,该数据集包含 1.26 亿张图像上的 5.4B 条注释。这使得 Florence-2 无需额外训练即可在许多任务上表现出色。

Florence-2 模型的原始开源权重支持以下任务:

任务类别 任务提示 描述 输入 输出
图像字幕
为图像生成基本字幕 图像 文本
<DETAILED_CAPTION> 为图像生成详细字幕 图像 文本
<MORE_DETAILED_CAPTION> 为图像生成非常详细的字幕 图像 文本
<REGION_TO_CATEGORY> 为指定边界框生成类别标签 图像,边界框 文本
<REGION_TO_DESCRIPTION> 为指定边界框生成描述 图像,边界框 文本
对象检测 检测对象并生成带标签的边界框 图像 边界框,文本
<DENSE_REGION_CAPTION> 检测对象并生成带字幕的边界框 图像 边界框,文本
<CAPTION_TO_PHRASE_GROUNDING> 使用边界框检测字幕中的短语并为其打上基础 图像,文本 边界框,文本
<OPEN_VOCABULARY_DETECTION> 根据提供的文本检测对象(开放词汇表) 图像、文本 边界框、文本
<REGION_PROPOSAL> 使用边界框提出感兴趣的区域 图像 边界框
分割 <REFERRING_EXPRESSION_SEGMENTATION> 根据文本描述生成分割多边形 图像、文本 多边形
<REGION_TO_SEGMENTATION> 为给定的边界框生成分割多边形 图像、边界框 多边形
OCR 从整个图像中提取文本 图像 文本
<OCR_WITH_REGION> 提取具有位置的文本(边界框或四边形框) 图像 文本、边界框

可以通过微调模型来添加其他不受支持的任务。

1.2 任务格式

受大型语言模型 (LLM) 的启发,Florence-2 被设计为序列到序列模型。它将图像和文本指令作为输入,并输出文本结果。输入或输出文本可能表示纯文本或图像中的区域。区域格式因任务而异:

  • 边界框:用于对象检测任务的 <X1><Y1><X2><Y2>。标记表示框左上角和右下角的坐标。
  • 四边形框:用于文本检测的 <X1><Y1><X2><Y2><X3><Y3><X4><Y4>’,使用包围文本的四个角的坐标。
  • 多边形:用于分割任务的 <X1><Y1>...,<Xn><Yn>,其中坐标按顺时针顺序表示多边形的顶点。

1.3 架构

Florence-2 使用标准编码器-解码器转换器架构构建。以下是该过程的工作原理:

  • 输入图像由 DaViT 视觉编码器 [5] 嵌入。
  • 文本提示使用 BART [6] 嵌入,利用扩展的标记器和字嵌入层。
  • 视觉和文本嵌入都是连接的。
  • 这些串联嵌入由基于转换器的多模态编码器-解码器处理以生成响应。
  • 在训练过程中,该模型会最小化交叉熵损失,类似于标准语言模型。
Florence-2 架构图

1.4 代码实现

加载 Florence-2 模型和示例图像

安装并导入必要的库后(如随附的 Colab 笔记本中所示),我们首先加载 Florence-2 模型、处理器和相机的输入图像:

#Load model:
model_id = ‘microsoft/Florence-2-large’
model = AutoModelForCausalLM.from_pretrained(model_id, trust_remote_code=True, torch_dtype='auto').eval().cuda()
processor = AutoProcessor.from_pretrained(model_id, trust_remote_code=True)

#Load image:
image = Image.open(img_path)
辅助函数

在本教程中,我们将使用几个辅助函数。最重要的是 run_example 核心函数,它从 Florence-2 模型生成响应。

run_example 函数将任务提示与任何其他文本输入(如果提供)组合成单个提示。使用处理器,它生成文本和图像嵌入作为模型的输入。神奇的事情发生在 model.generate 步骤中,在此生成模型的响应。以下是一些关键参数的细分:

  • max_new_tokens=1024:设置输出的最大长度,允许详细响应。
  • do_sample=False:确保确定性响应。
  • num_beams=3:在每个步骤中使用前 3 个最有可能的标记实现波束搜索,探索多个潜在序列以找到最佳整体输出。
  • early_stopping=False:确保波束搜索持续进行,直到所有波束达到最大长度或生成序列末尾的标记。

最后,使用processor.batch_decode和processor.post_process_generation对模型的输出进行解码和后处理,以生成最终的文本响应,由run_example函数返回。

def run_example(image, task_prompt, text_input=''):

    prompt = task_prompt + text_input

    inputs = processor(text=prompt, images=image, return_tensors=”pt”).to(‘cuda’, torch.float16)

    generated_ids = model.generate(
        input_ids=inputs[“input_ids”].cuda(),
        pixel_values=inputs[“pixel_values”].cuda(),
        max_new_tokens=1024,
        do_sample=False,
        num_beams=3,
        early_stopping=False,
    )

    generated_text = processor.batch_decode(generated_ids, skip_special_tokens=False)[0]
    parsed_answer = processor.post_process_generation(
        generated_text,
        task=task_prompt,
        image_size=(image.width, image.height)
    )

    return parsed_answer

此外,我们利用辅助函数来可视化结果(draw_bbox、draw_ocr_bboxes 和 draw_polygon)并处理边界框格式之间的转换(convert_bbox_to_florence-2 和 convert_florence-2_to_bbox)。这些可以在随附的 Colab 笔记本中探索。

2、任务

Florence-2 可以执行各种视觉任务。让我们探索它的一些功能,从图像字幕开始。

2.1 字幕生成相关任务

生成字幕

Florence-2 可以使用 <CAPTION><DETAILED_CAPTION><MORE_DETAILED_CAPTION>任务提示生成不同细节级别的图像字幕。

print (run_example(image, task_prompt='<CAPTION>'))
# Output: 'A black camera sitting on top of a wooden table.'

print (run_example(image, task_prompt='<DETAILED_CAPTION>'))
# Output: 'The image shows a black Kodak V35 35mm film camera sitting on top of a wooden table with a blurred background.'

print (run_example(image, task_prompt='<MORE_DETAILED_CAPTION>'))
# Output: 'The image is a close-up of a Kodak VR35 digital camera. The camera is black in color and has the Kodak logo on the top left corner. The body of the camera is made of wood and has a textured grip for easy handling. The lens is in the center of the body and is surrounded by a gold-colored ring. On the top right corner, there is a small LCD screen and a flash. The background is blurred, but it appears to be a wooded area with trees and greenery.'

该模型准确地描述了图像及其周围环境。它甚至识别了相机的品牌和型号,展示了其 OCR 能力。然而,在“<MORE_DETAILED_CAPTION>”任务中存在轻微的不一致,这是零样本模型的预期结果。

为给定的边界框生成标题

Florence-2 可以为边界框定义的图像特定区域生成标题。为此,它将边界框位置作为输入。您可以使用 <REGION_TO_CATEGORY>提取类别,或使用 <REGION_TO_DESCRIPTION>提取描述。

为了方便起见,我在 Colab 笔记本中添加了一个小部件,使您可以在图像上绘制边界框,并编写代码将其转换为 Florence-2 格式。

task_prompt = '<REGION_TO_CATEGORY>'
box_str = '<loc_335><loc_412><loc_653><loc_832>'
results = run_example(image, task_prompt, text_input=box_str)
# Output: 'camera lens'
task_prompt = '<REGION_TO_DESCRIPTION>'
box_str = '<loc_335><loc_412><loc_653><loc_832>'
results = run_example(image, task_prompt, text_input=box_str)
# Output: 'camera'

在这种情况下, <REGION_TO_CATEGORY> 识别了镜头,而 <REGION_TO_DESCRIPTION> 则不太具体。但是,这种性能可能会因不同的图像而异。

2.2 物体检测相关任务

为物体生成边界框和文本

Florence-2 可以识别图像中密集的区域,并提供它们的边界框坐标及其相关标签或标题。要提取带有标签的边界框,请使用“”任务提示:

results = run_example(image, task_prompt='<OD>')
draw_bbox(image, results['<OD>'])

要提取带有标题的边界框,请使用 <DENSE_REGION_CAPTION>任务提示:

task_prompt results = run_example(image, task_prompt= '<DENSE_REGION_CAPTION>')
draw_bbox(image, results['<DENSE_REGION_CAPTION>'])
左图显示“”任务提示的结果,右图演示“<DENSE_REGION_CAPTION>”
基于文本的物体检测

Florence-2 还可以执行基于文本的物体检测。通过提供特定的物体名称或描述作为输入,Florence-2 可以检测指定物体周围的边界框。

task_prompt = '<CAPTION_TO_PHRASE_GROUNDING>'
results = run_example(image,task_prompt, text_input=”lens. camera. table. logo. flash.”)
draw_bbox(image, results['<CAPTION_TO_PHRASE_GROUNDING>'])
CAPTION_TO_PHRASE_GROUNDING 任务,文本输入为:“lens. camera. table. logo. flash。”

Florence-2 还可以生成以文本 ( <REFERRING_EXPRESSION_SEGMENTATION>) 或边界框 ( <REGION_TO_SEGMENTATION>) 为基础的分割多边形:

results = run_example(image, task_prompt='<REFERRING_EXPRESSION_SEGMENTATION>', text_input=”camera”)
draw_polygons(image, results[task_prompt])
results = run_example(image, task_prompt='<REGION_TO_SEGMENTATION>', text_input="<loc_345><loc_417><loc_648><loc_845>")
draw_polygons(output_image, results['<REGION_TO_SEGMENTATION>'])
左图显示了 REFERRING_EXPRESSION_SEGMENTATION 任务的结果,其中“相机”文本作为输入。右图演示了 REGION_TO_SEGMENTATION 任务,其中镜头周围的边界框作为输入

2.​​4  OCR 相关任务

Florence-2 展示了强大的 OCR 功能。它可以使用“”任务提示从图像中提取文本,并使用“<OCR_WITH_REGION>”提取文本及其位置:

results = run_example(image,task_prompt)
draw_ocr_bboxes(image, results['<OCR_WITH_REGION>'])

3、结束语

Florence-2 是一种多功能的视觉语言模型 (VLM),能够在单个模型中处理多个视觉任务。其零样本能力在图像字幕、对象检测、分割和 OCR 等各种任务中都令人印象深刻。虽然 Florence-2 开箱即用,但额外的微调可以进一步使模型适应新任务或提高其在独特自定义数据集上的性能。


原文链接:Florence-2: Advancing Multiple Vision Tasks with a Single VLM Model

BimAnt翻译整理,转载请标明出处