Florence-2:使用单个VLM模型推进多项视觉任务

2024年10月16日 由 alex 发表 31 0

简介

近年来,计算机视觉领域兴起了一些基础模型,这些模型无需训练自定义模型即可实现图像标注。我们已经看到了用于分类的 CLIP 模型、用于物体检测的 GroundingDINO 模型和用于分割的 SAM 模型。它们都在各自的领域中表现出色。但是,如果我们有一个能够同时处理所有这些任务的单一模型会怎样呢?


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


Florence-2


背景介绍

Florence-2 由微软于 2024 年 6 月发布。它的设计目的是在单个模型内执行多项视觉任务。它是一个开源模型,可根据 MIT 许可在 Hugging Face 上获取。


尽管 Florence-2 的体积相对较小,只有 0.23B 和 0.77B 两个参数版本,但它却实现了最先进的(SOTA)性能。该模型体积小巧,可在计算资源有限的设备上高效部署,同时确保快速推理。


该模型在一个名为 FLD-5B 的大型高质量数据集上进行了预训练,该数据集由 1.26 亿张图片上的 54 亿个注释组成。这使得 Florence-2 不需要额外的训练,就能在许多任务中实现出色的零误差性能。


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


15

16

17


通过对模型进行微调,可以添加更多不支持的任务。


任务格式

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

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


结构

Florence-2 采用标准的编码器-解码器转换器架构。具体流程如下:

  1. 输入图像由 DaViT 视觉编码器嵌入[5]。
  2. 文本提示使用 BART [6],利用扩展标记器和单词嵌入层进行嵌入。
  3. 视觉嵌入和文本嵌入都是串联的。
  4. 这些串联的嵌入信息由基于变压器的多模态编码器-解码器处理,以生成响应。
  5. 在训练过程中,该模型会尽量减少交叉熵损失,这与标准语言模型类似。


18


代码执行

加载 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=假: 确保响应的确定性。
  • num_beams=3:执行波束搜索,每一步选取前 3 个最可能的标记,探索多个潜在序列,以找到最佳的整体输出。
  • early_stopping=假: 确保波束搜索持续到所有波束达到最大长度或产生序列末端标记为止。


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


def run_example(image, task_prompt, text_input=''):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)。


任务

Florence-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>''<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>''<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. 物体检测相关任务:


为物体生成边框和文本

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


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


要提取带标题的包围盒,请使用“<DENSE_REGION_CAPTION>”任务提示:


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


19


基于文本的目标检测

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


task_prompt = '<CAPTION_TO_PHRASE_GROUNDING>''<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>'])


20


3. 分割相关任务:

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


results = run_example(image, task_prompt='<REFERRING_EXPRESSION_SEGMENTATION>', text_input=”camera”)'<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>")'<REGION_TO_SEGMENTATION>', text_input="<loc_345><loc_417><loc_648><loc_845>")
draw_polygons(output_image, results['<REGION_TO_SEGMENTATION>'])


21


4. OCR 相关任务:

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


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


22


总结

Florence-2 是一种多功能视觉语言模型(VLM),能够在一个模型中处理多种视觉任务。在图像字幕、物体检测、分割和光学字符识别等多种任务中,它的零拍摄能力令人印象深刻。虽然 Florence-2 在开箱即用的情况下表现出色,但额外的微调可以使模型进一步适应新任务,或提高其在独特的自定义数据集上的性能。


文章来源:https://medium.com/towards-data-science/florence-2-mastering-multiple-vision-tasks-with-a-single-vlm-model-435d251976d0
欢迎关注ATYUN官方公众号
商务合作及内容投稿请联系邮箱:bd@atyun.com
评论 登录
热门职位
Maluuba
20000~40000/月
Cisco
25000~30000/月 深圳市
PilotAILabs
30000~60000/年 深圳市
写评论取消
回复取消