车辆图像结构化数据抽取

想象一下,在检查点有一个摄像头监控汽车,你的任务是记录复杂的车辆细节——类型、车牌号、品牌、型号和颜色。这项任务具有挑战性——经典的计算机视觉方法难以应对各种模式,而监督式深度学习需要集成多个专门的模型、大量标记数据和繁琐的训练。预训练多模态 LLM (MLLM) 领域的最新进展提供了快速灵活的解决方案,但要将它们调整为结构化输出则需要进行调整。

在本教程中,我们将构建一个车辆文档系统,从车辆图像中提取重要细节。这些细节将以结构化格式提取,以便进一步供下游使用。我们将使用 OpenAI 的 GPT-4 提取数据,使用 Pydantic 构造输出,并使用 LangChain 编排管道。最后,您将拥有一个实用的管道,用于将原始图像转换为结构化、可操作的数据。

本教程面向有兴趣使用 LLM 执行视觉任务的计算机视觉从业者、数据科学家和开发人员。完整代码以易于使用的 Colab 笔记本的形式提供,以帮助你逐步学习。

技术栈
  • GPT-4 视觉模型:GPT-4 是由 OpenAI 开发的多模态模型,能够理解文本和图像 [1]。经过大量多模态数据的训练,它可以以零样本方式推广到各种任务,通常无需微调。虽然 GPT-4 的确切架构和大小尚未公开披露,但其功能是该领域最先进的。GPT-4 可通过 OpenAI API 以付费代币方式获得。在本教程中,我们使用 GPT-4 来获得其出色的零样本性能,但代码允许您根据需要轻松地与其他模型交换。
  • LangChain:为了构建管道,我们将使用 LangChain。LangChain 是一个功能强大的框架,可简化复杂的工作流程,确保代码的一致性,并可轻松在 LLM 模型之间切换 [2]。在我们的案例中,Langchain 将帮助我们链接加载图像、生成提示、调用 GPT 模型以及将输出解析为结构化数据的步骤。
  • Pydantic:Pydantic 是一个功能强大的 Python 数据验证库 [3]。我们将使用 Pydantic 来定义 GPT-4 模型预期输出的结构。这将帮助我们确保输出一致且易于使用。

1、数据集概述

为了模拟车辆检查站的数据,我们将使用来自“车牌”Kaggle 数据集  的车辆图像样本。此数据集在 Apache 2.0 许可下可用。你可以查看以下图像:

在深入实际实施之前,我们需要做一些准备工作:

  • 生成 OpenAI API 密钥 — OpenAI API 是一项付费服务​​。要使用该 API,您需要注册一个 OpenAI 帐户并生成与付费计划关联的秘密 API 密钥(了解更多)。
  • 配置你的 OpenAI — 在 Colab 中,你可以将 API 密钥安全地存储为环境变量(秘密),位于左侧边栏(🔑)。创建一个名为 OPENAI_API_KEY 的秘密,将您的 API 密钥粘贴到值字段中,然后打开“笔记本访问”。
  • 安装并导入所需的库。

2、管道架构

在此实现中,我们将使用 LangChain 的链抽象将管道中的一系列步骤链接在一起。我们的管道链由 4 个组件组成:图像加载组件、提示生成组件、MLLM 调用组件和解析器组件,用于将 LLM 的输出解析为结构化格式。链中每个步骤的输入和输出通常被构造为字典,其中键表示参数名称,值是实际数据。让我们看看它是如何工作的。

2.1 图像加载组件

链中的第一步是加载图像并将其转换为 base64 编码,因为 GPT-4 要求图像采用基于文本 (base64) 的格式。

def image_encoding(inputs):
    """Load and Convert image to base64 encoding"""

    with open(inputs["image_path"], "rb") as image_file:
        image_base64 = base64.b64encode(image_file.read()).decode("utf-8")
    return {"image": image_base64}

inputs 参数是包含图像路径的字典,输出是包含 based64 编码图像的字典。

2.2 使用 Pydantic 定义输出结构

我们首先使用从 Pydantic 的 BaseModel 继承的名为 Vehicle 的类来定义所需的输出结构。每个字段(例如,类型、许可证、品牌、型号、颜色)都使用 Field 定义,这使我们能够:

  • 指定输出数据类型(例如,str、int、list 等)。
  • 为 LLM 提供字段描述。
  • 包括示例以指导 LLM。

每个字段中的 ...(省略号)表示该字段是必需的,不能省略。

该类如下所示:

class Vehicle(BaseModel):

    Type: str = Field(
        ...,
        examples=["Car", "Truck", "Motorcycle", 'Bus'],
        description="Return the type of the vehicle.",
    )

    License: str = Field(
        ...,
        description="Return the license plate number of the vehicle.",
    )

    Make: str = Field(
        ...,
        examples=["Toyota", "Honda", "Ford", "Suzuki"],
        description="Return the Make of the vehicle.",
    )

    Model: str = Field(
        ...,
        examples=["Corolla", "Civic", "F-150"],
        description="Return the Model of the vehicle.",
    )

    Color: str = Field(
        ...,
        example=["Red", "Blue", "Black", "White"],
        description="Return the color of the vehicle.",
    )

2.3 解析器组件

要确保 LLM 输出符合我们预期的格式,我们使用以 Vehicle 类初始化的 JsonOutputParser。此解析器验证输出是否遵循我们定义的结构,验证字段、类型和约束。如果输出与预期格式不匹配,解析器将引发验证错误。

parser.get_format_instructions() 方法根据 Vehicle 类的架构生成一串指令。这些指令将成为提示的一部分,并将指导模型如何构造其输出以便对其进行解析。您可以在 Colab 笔记本中查看指令变量内容。

parser = JsonOutputParser(pydantic_object=Vehicle)
instructions = parser.get_format_instructions()

2.4 提示生成组件

我们管道中的下一个组件是构建提示。提示由系统提示和人工提示组成:

  • 系统提示:在 SystemMessage 中定义,我们使用它来建立 AI 的角色。
  • 人类提示:在 HumanMessage 中定义,由 3 部分组成:1) 任务描述 2) 我们从解析器中提取的格式说明,3) base64 格式的图像,以及图像质量细节参数。

detail参数控制模型如何处理图像并生成其文本理解 [5]。它有三个选项:低、高或自动:

  • 低:该模型处理低分辨率(512 x 512 像素)版本的图像,并使用 85 个令牌的预算表示图像。这允许 API 返回更快的响应并消耗更少的输入令牌。
  • 高:该模型首先分析低分辨率图像(85 个令牌),然后使用每 512 x 512px 图块 170 个令牌创建详细裁剪。
  • 自动:默认设置,其中低或高设置由图像大小自动选择。

对于我们的设置,低分辨率就足够了,但其他应用程序可能会受益于高分辨率选项。

以下是提示创建步骤的实现:

@chain
def prompt(inputs):
    """Create the prompt"""
    
    prompt = [
    SystemMessage(content="""You are an AI assistant whose job is to inspect an image and provide the desired information from the image. If the desired field is not clear or not well detected, return none for this field. Do not try to guess."""),
    HumanMessage(
        content=[
            {"type": "text", "text": """Examine the main vehicle type, make, model, license plate number and color."""},
            {"type": "text", "text": instructions},
            {"type": "image_url", "image_url": {"url": f"data:image/jpeg;base64,{inputs['image']}", "detail": "low", }}]
        )
    ]
    return prompt

@chain 装饰器用于指示此函数是 LangChain 管道的一部分,此函数的结果可以传递到其中到工作流程中的步骤。

2.5 MLLM 组件

管道中的下一步是使用 MLLM_response 函数调用 MLLM 从图像中生成信息。

首先,我们使用 ChatOpenAI 初始化多模态 GTP-4 模型,配置如下:

  • model 指定 GPT-4 模型的确切版本。
  • temperature 设置为 0.0 以确保确定性响应。
  • max_token 将输出的最大长度限制为 1024 个 token。

接下来,我们使用 model.invoke 调用 GPT-4 模型,其中包含组装的输入,其中包括图像和提示。该模型处理输入并返回来自图像的信息。

2.6 构建管道链

定义所有组件后,我们用 | 运算符将它们连接起来以构建管道链。此运算符按顺序将一个步骤的输出链接到下一个步骤的输入,从而创建流畅的工作流程。

3、对单个图像进行推理

现在到了有趣的部分!

我们可以通过将包含图像路径的字典传递给 pipeline.invoke方法,从车辆图像中提取信息。 工作原理如下:

output = pipeline.invoke({"image_path": f"{img_path}"})

输出是包含车辆详细信息的字典:

为了进一步与数据库或API响应集成,我们可以轻松地将输出字典转换为JSON:

json_output = json.dumps(output)

4、对图像批进行推理

LangChain通过允许你同时处理多幅图像来简化批量推理。为此,你应该传递包含图像路径的字典列表,并使用 pipeline.batch调用管道:

# Prepare a list of dictionaries with image paths:
batch_input = [{"image_path": path} for path in image_paths]

# Perform batch inference:
output = pipeline.batch(batch_input)

生成的输出字典可以轻松转换为表格数据,例如 Pandas DataFrame:

df = pd.DataFrame(output)

我们可以看到,GPT-4 模型正确识别了车辆类型、车牌、品牌、型号和颜色,提供了准确且结构化的信息。如果细节不清晰可见,例如摩托车图像,它会按照提示中的指示返回“无”。

5、结束语

在本教程中,我们学习了如何从图像中提取结构化数据并使用它来构建车辆文档系统。相同的原则也可以适用于其他各种应用。我们使用了 GPT-4 模型,该模型在识别车辆细节方面表现出色。但是,我们基于 LangChain 的实现非常灵活,可以轻松与其他 MLLM 模型集成。虽然我们取得了良好的结果,但重要的是要时刻注意基于 LLM 的模型可能出现的潜在分配。

从业者在实施类似系统时还应考虑潜在的隐私和安全风险。虽然默认情况下不会使用 OpenAI API 平台中的数据来训练模型 [6],但处理敏感数据需要遵守适当的规定。


原文链接:Extracting Structured Vehicle Data from Images

汇智网翻译整理,转载请标明出处