当前位置: 首页 > news >正文

Flickr30k_Entities数据集

Flickr30k_Entities 数据集包含 24.4 万个共指链(coreference chains)和 27.6 万个为原始数据集中每张图片(共 31,783 张)及其对应的英文标题(每张图片 5 个,共 158,915 个)手动标注的边界框(bounding boxes)。

要获取此数据集的图像,请访问 Flickr30K 网页 并填写页面底部的链接表单。

共指链 (Coreference Chains)

数据集中的每张图片在 “Sentences” 文件夹中都有一个对应的 .txt 文件。该文件的每一行包含一个带有标注短语的标题,这些短语被方括号括起来。每个标注都遵循以下格式:
[/EN#<链ID>/<类型1>/<类型2>.../<类型n> <单词1> <单词2> ... <单词n>]

属于同一个共指链的短语共享相同的链ID (chain id)。每个短语都关联一个或多个类型,这些类型对应于我们论文中描述的大致类别。类型为 “notvisual”(非视觉内容)的短语其链 ID 为空值 “0”,并且应被视为一组独立的单例共指链,因为这些短语未被进行共指标注。

边界框 (Bounding Boxes) 或 场景/无框 (Scene/No Box)

数据集中的每张图片在 “Annotations” 文件夹中都有一个对应的 .xml 文件,其格式与 PASCAL VOC 数据集类似。这些文件包含 <object> 标签,其中或者包含由 <xmin>, <ymin>, <xmax>, <ymax> 标签定义的边界框,或者包含在 <scene><nobndbox> 标签中的场景/无框二元标志。

每个 <object> 标签还包含一个或多个 <name> 标签,其中包含了该物体所引用的链ID

无关标题 (Unrelated Captions)

我们在 UNRELATED_CAPTIONS 文件中提供了一个列表,其中包含了数据集中与图像本身内容无关的标题。这个列表可能不完整。

数据集划分 (Dataset Splits)

Flickr30K 数据集已在多种不同的划分方式下进行过评估,因此我们在 train.txt, test.txt, 和 val.txt 文件中提供了我们实验中所使用的图像划分(训练集、测试集、验证集)。

Flickr30K Entities 这个数据集是在著名的 Flickr30K 数据集(包含 3 万多张图片及对应的标题)的基础上进行了扩展,增加了更丰富的标注信息,主要用于连接自然语言描述(标题)视觉内容(图片中的物体)

1. 核心构成
  • 原始数据: 基础是 Flickr30K 数据集,包含 31,783 张图片,每张图片有 5 个由人工编写的英文标题。
  • 核心标注: 此扩展数据集的核心价值在于两个新增的标注:
    • 共指链 (Coreference Chains): 标注了标题中的哪些词组指向的是现实世界中的同一个实体或概念。
    • 边界框 (Bounding Boxes): 在图片中框出了这些实体或概念的具体位置。
2. 共指链 (Coreference Chains) - 连接语言
  • 目标: 解决代词指代和名词短语指代问题。例如,在一个标题 “A man is walking his dog. He looks happy and the pet is running ahead.” 中,“A man” 和 “He” 指的是同一个人,“his dog” 和 “the pet” 指的是同一只动物。
  • 实现方式:
    • 标注格式: [/EN#<链ID> ...]。所有指向同一个实体的短语(如 “A man” 和 “He”)会被赋予相同的 链ID
    • 文件结构: 每张图片对应一个 .txt 文件,里面是 5 个被标注过的标题。
    • 特殊类型: “notvisual” 类型指的是标题中无法在图片里找到对应实体的词语(如抽象概念 “happiness”),它们的链 ID 为 “0”,不参与主要的共指分析。
3. 边界框 (Bounding Boxes) - 连接视觉
  • 目标: 将语言中提到的实体与图片中的具体像素区域对应起来。
  • 实现方式:
    • 文件格式: 采用计算机视觉领域常用的 PASCAL VOC .xml 格式。
    • 关联机制: 每个 <object>(即图片中的一个物体/区域)标签内部,会有一个 <name> 标签,其内容就是上面提到的 链ID
    • 工作流程: 这就建立了一个桥梁:标题中的短语 -> 链ID -> 图片中的边界框。通过这个链条,模型可以学习到文字描述和视觉对象的精确对应关系。
    • 特殊情况: scenenobndbox 标志用于描述那些无法用一个简单的矩形框表示的实体,比如 “天空”、“草地” 或一些无法框出的场景元素。
4. 数据集划分与评估
  • 标准化: 提供 train.txt, test.txt, val.txt 文件是为了让所有使用该数据集的研究者都在相同的训练集、验证集和测试集上进行实验。这保证了不同研究成果之间的公平比较

这个数据集是一个高质量的多模态(视觉+语言)研究资源。它通过共指链边界框,将图片中的具体物体和文本描述中的指代词语精确地关联起来。研究人员可以利用它来训练和评估能够理解图像与文本深层语义关系的模型,例如:

  • 视觉定位 (Visual Grounding): 根据文本描述在图片中找到对应的物体。
  • 图像标题生成 (Image Captioning): 生成更精确、更具细节的图像描述。
  • 多模态机器学习的研究。

数据实例

我们以 Flickr30K 数据集中的图片 1000092795.jpg 为例。

1. 标题与共指链文件 (1000092795.txt)

这个文件位于 Sentences 文件夹下。它包含了对这张图片的五个描述,并且文本中的实体短语已经被标注。

[/EN#1/person A man] in [/EN#2/body_part a black jacket] and [/EN#3/clothing a modern orange helmet] is riding [/EN#4/vehicle a motorbike] on [/EN#5/scene a road] with [/EN#6/scene a grassy hill] in the background .
[/EN#1/person A man] wearing [/EN#3/clothing a hard-hat] is on [/EN#4/vehicle a motorcycle] .
[/EN#1/person A guy] wearing [/EN#3/clothing a red helmet] is on [/EN#4/vehicle a motorcycle] on [/EN#5/scene a road] .
[/EN#1/person a man] in [/EN#3/clothing a helmet] riding [/EN#4/vehicle a motorcycle] down [/EN#5/scene a paved road] .
[/EN#1/person The man] on [/EN#4/vehicle the motorcycle] is wearing [/EN#3/clothing a helmet] and [/EN#2/clothing a black jacket] .

解析:

  • 共指链 (Coreference Chain): 注意看 [/EN#<ID>/<类型> ...] 里的 ID
    • 链ID #1: A man, A guy, a man, The man 都指向同一个人,所以它们的链ID都是 1
    • 链ID #3: a modern orange helmet, a hard-hat, a red helmet, a helmet 都指向同一个头盔(尽管描述略有不同),所以它们的链ID都是 3
    • 链ID #4: a motorbike, a motorcycle 都指向同一辆摩托车,链ID为 4
  • 实体类型: 每个标注还包含了实体的粗略类型,如 person, clothing, vehicle, scene
2. 边界框标注文件 (1000092795.xml)

这个文件位于 Annotations 文件夹下。它定义了图片中物体的边界框,并通过 name 标签与上面的链ID关联起来。

<annotation><folder>Flickr30k</folder><filename>1000092795.jpg</filename><source><database>The Flickr30k Database</database><annotation>Flickr30k</annotation><image>flickr</image></source><size><width>500</width><height>333</height><depth>3</depth></size><segmented>0</segmented><object><name>1</name><bndbox><xmin>83</xmin><ymin>20</ymin><xmax>452</xmax><ymax>332</ymax></bndbox></object><object><name>2</name><bndbox><xmin>129</xmin><ymin>70</ymin><xmax>332</xmax><ymax>229</ymax></bndbox></object><object><name>3</name><bndbox><xmin>161</xmin><ymin>21</ymin><xmax>235</xmax><ymax>93</ymax></bndbox></object><object><name>4</name><bndbox><xmin>84</xmin><ymin>154</ymin><xmax>451</xmax><ymax>332</ymax></bndbox></object><object><name>5</name><scene>1</scene><nobndbox>1</nobndbox></object><object><name>6</name><scene>1</scene><nobndbox>1</nobndbox></object>
</annotation>

解析:

  • 关联:
    • 第一个 <object><name>1。这对应了 .txt 文件中所有链ID为 1 的短语(即"那个男人")。这个 <object> 里的 <bndbox> (xmin: 83, ymin: 20, …) 就框出了图片中那个男人的位置。
    • 第三个 <object><name>3。这对应了链ID为 3 的短语(即"那个头盔"),其 <bndbox> 框出了头盔的位置。
  • 场景/无框:
    • 链ID为 5 (a road) 和 6 (a grassy hill) 的物体,没有具体的 <bndbox>。它们被标记为 <scene>1</scene><nobndbox>1</nobndbox>,表示它们是场景的一部分,无法用一个简单的矩形框来界定。

代码处理示例

下面的 Python 代码演示了如何解析这两个文件,并将文本短语和它们的视觉位置(边界框)关联起来。

为了运行这段代码,你需要安装 xml 解析库(Python 内置)和一个用于处理标注文本的正则表达式库 re

import xml.etree.ElementTree as ET
import re
from pprint import pprintdef parse_flickr30k_entities(image_id, sentences_path, annotations_path):"""解析给定 image_id 的标题和标注文件,并返回一个整合了信息的结构。Args:image_id (str): 图片的ID (例如 '1000092795')。sentences_path (str): 'Sentences' 文件夹的路径。annotations_path (str): 'Annotations' 文件夹的路径。Returns:dict: 一个包含了所有实体及其对应边界框和描述的字典。"""# --- 1. 解析标题和共指链 (.txt 文件) ---sentence_file = f"{sentences_path}/{image_id}.txt"coref_chains = {} # 存储每个链ID对应的所有短语# 正则表达式来匹配标注格式# [/EN#<ID>/<类型> <短语>]pattern = re.compile(r'\[/EN#(\d+)/([\w\s/]+)\s([^\]]+)\]')with open(sentence_file, 'r', encoding='utf-8') as f:for line in f:matches = pattern.finditer(line)for match in matches:chain_id = match.group(1)entity_type = match.group(2).split('/')phrase = match.group(3)if chain_id not in coref_chains:coref_chains[chain_id] = {'phrases': set(), 'types': set()}coref_chains[chain_id]['phrases'].add(phrase.strip())coref_chains[chain_id]['types'].update(entity_type)# --- 2. 解析边界框 (.xml 文件) ---annotation_file = f"{annotations_path}/{image_id}.xml"tree = ET.parse(annotation_file)root = tree.getroot()# 将解析出的边界框信息整合到 coref_chains 字典中for obj in root.findall('object'):is_scene = obj.find('scene') is not None# 获取这个物体对应的所有链IDchain_ids = [name.text for name in obj.findall('name')]for chain_id in chain_ids:if chain_id in coref_chains:if is_scene:coref_chains[chain_id]['bbox'] = 'scene'else:bndbox_elem = obj.find('bndbox')bbox = {'xmin': int(bndbox_elem.find('xmin').text),'ymin': int(bndbox_elem.find('ymin').text),'xmax': int(bndbox_elem.find('xmax').text),'ymax': int(bndbox_elem.find('ymax').text)}coref_chains[chain_id]['bbox'] = bboxreturn coref_chains# --- 使用示例 ---
# 假设你的文件在以下路径
# 注意:你需要先下载数据集才能获得这些文件
# sentences_folder = './Flickr30kEntities/Sentences'
# annotations_folder = './Flickr30kEntities/Annotations'
# image_id_to_process = '1000092795'# 由于我们无法直接访问本地文件,这里使用前面提供的文本内容作为模拟输入
# 在真实场景中,你会从文件中读取
sentences_folder_mock = '.'
annotations_folder_mock = '.'# 创建模拟文件
with open(f"{sentences_folder_mock}/1000092795.txt", "w") as f:f.write("""
[/EN#1/person A man] in [/EN#2/body_part a black jacket] and [/EN#3/clothing a modern orange helmet] is riding [/EN#4/vehicle a motorbike] on [/EN#5/scene a road] with [/EN#6/scene a grassy hill] in the background .
[/EN#1/person A man] wearing [/EN#3/clothing a hard-hat] is on [/EN#4/vehicle a motorcycle] .
[/EN#1/person A guy] wearing [/EN#3/clothing a red helmet] is on [/EN#4/vehicle a motorcycle] on [/EN#5/scene a road] .
[/EN#1/person a man] in [/EN#3/clothing a helmet] riding [/EN#4/vehicle a motorcycle] down [/EN#5/scene a paved road] .
[/EN#1/person The man] on [/EN#4/vehicle the motorcycle] is wearing [/EN#3/clothing a helmet] and [/EN#2/clothing a black jacket] .""")with open(f"{annotations_folder_mock}/1000092795.xml", "w") as f:f.write("""
<annotation><filename>1000092795.jpg</filename><object><name>1</name><bndbox><xmin>83</xmin><ymin>20</ymin><xmax>452</xmax><ymax>332</ymax></bndbox></object><object><name>2</name><bndbox><xmin>129</xmin><ymin>70</ymin><xmax>332</xmax><ymax>229</ymax></bndbox></object><object><name>3</name><bndbox><xmin>161</xmin><ymin>21</ymin><xmax>235</xmax><ymax>93</ymax></bndbox></object><object><name>4</name><bndbox><xmin>84</xmin><ymin>154</ymin><xmax>451</xmax><ymax>332</ymax></bndbox></object><object><name>5</name><scene>1</scene><nobndbox>1</nobndbox></object><object><name>6</name><scene>1</scene><nobndbox>1</nobndbox></object>
</annotation>""")# 调用函数进行处理
linked_entities = parse_flickr30k_entities('1000092795', sentences_folder_mock, annotations_folder_mock
)# 打印结果,看看数据是如何被整合的
pprint(linked_entities)
代码输出结果
{'1': {'bbox': {'xmax': 452, 'xmin': 83, 'ymax': 332, 'ymin': 20},'phrases': {'A man', 'The man', 'a man', 'A guy'},'types': {'person'}},'2': {'bbox': {'xmax': 332, 'xmin': 129, 'ymax': 229, 'ymin': 70},'phrases': {'a black jacket'},'types': {'body_part', 'clothing'}}, # 注意类型可以是多个'3': {'bbox': {'xmax': 235, 'xmin': 161, 'ymax': 93, 'ymin': 21},'phrases': {'a modern orange helmet', 'a helmet', 'a hard-hat', 'a red helmet'},'types': {'clothing'}},'4': {'bbox': {'xmax': 451, 'xmin': 84, 'ymax': 332, 'ymin': 154},'phrases': {'a motorcycle', 'a motorbike', 'the motorcycle'},'types': {'vehicle'}},'5': {'bbox': 'scene','phrases': {'a road', 'a paved road'},'types': {'scene'}},'6': {'bbox': 'scene','phrases': {'a grassy hill'},'types': {'scene'}}}

这个最终的 linked_entities 字典就是我们想要的数据结构。它以链ID为键,将所有描述同一个实体的文本短语(phrases)、实体类型(types)和它在图片中的位置(bbox)完美地整合在了一起。这就是进行多模态学习任务(如视觉定位)所需的核心数据。

视觉定位(Visual Grounding)是计算机视觉与自然语言处理交叉领域中的关键任务,旨在将文本描述与图像中的特定区域对应起来。该任务主要包括两类子任务:指代表达理解(Referring Expression Comprehension, REC)和短语定位(Phrase Grounding)。以下分别提供每类任务的专业示例:

指代表达理解(Referring Expression Comprehension, REC)

任务定义:给定一张图像和一段自然语言描述,模型需要定位出图像中与该描述对应的单个目标区域。

示例

  • 输入图像:一张室内场景的照片,包含两位穿着不同颜色衣服的女性分别坐在沙发上。
  • 文本描述:“穿红色连衣裙的女士”。
  • 模型输出:在图像中框选出穿红色连衣裙的女性所在的区域。

技术实现

Chen 等人提出的 Single-Stage Grounding Network(SSG)模型,通过端到端的方式,在不依赖候选区域提议的情况下,实现了实时的指代表达理解。该模型在 RefCOCO、RefCOCO+ 和 RefCOCOg 数据集上表现出色,显著提升了定位速度和准确性 。(arXiv)

短语定位(Phrase Grounding)

任务定义:给定一张图像和包含多个实体的句子,模型需要将句子中的每个实体短语与图像中的对应区域进行匹配。

示例

  • 输入图像:一张公园里的照片,包含一个男孩在踢足球,旁边有一只狗在奔跑。
  • 文本描述:“一个男孩在踢足球,旁边有一只狗在奔跑”。
  • 模型输出:分别框选出图像中“男孩”、“足球”和“狗”对应的区域。

技术实现

短语定位任务通常涉及将句子中的名词短语与图像中的区域进行对齐。该任务在图像理解和多模态任务(如视觉问答、图像字幕生成等)中具有重要应用价值 。(Roboflow Blog)

Flickr30k Entities 是一个广泛用于短语定位(Phrase Grounding)任务的权威数据集。它在原始的 Flickr30k 图像和描述基础上,进一步提供了短语级别的实体注释和对应的图像区域(bounding boxes)。以下是一个准确的示例,展示了该数据集中一张图像的注释方式:(arXiv,Papers with Code)

示例图像描述与短语定位
  • 图像编号:1000092795.jpg
  • 英文描述:“A little girl in a pink dress is climbing up a set of stairs in an entry way.”
  • 中文翻译:“一个穿着粉红色连衣裙的小女孩正在入口处的一组楼梯上攀爬。”([GitHub][3])

在 Flickr30k Entities 数据集中,该句子中的名词短语被标注并与图像中的区域对应。例如:

  • “a little girl” → 对应图像中小女孩的边界框(bounding box)
  • “a pink dress” → 对应小女孩所穿粉红色连衣裙的边界框
  • “a set of stairs” → 对应楼梯的边界框
  • “an entry way” → 对应入口区域的边界框

这些短语在数据集中以特定的标注格式表示,例如:

[/EN#18/people A little girl] in [/EN#19/clothing a pink dress] is climbing up [/EN#20/other a set of stairs] in [/EN#23/scene an entry way].

其中,EN#18EN#19 等是实体的唯一标识符,后续的类别标签(如 peopleclothing)表示实体的类型。每个实体在图像中对应一个或多个边界框,这些信息存储在与图像对应的 XML 注释文件中。GitHub

数据集统计信息
  • 图像数量:31,783 张
  • 描述数量:158,915 条(每张图像 5 条)
  • 实体短语数量:244,035 个共指链(coreference chains)
  • 边界框数量:275,775 个手工注释的边界框

Flickr30k Entities 数据集为短语定位任务提供了丰富的训练和评估资源,广泛应用于图像字幕生成、视觉问答和多模态理解等研究领域。您可以在 GitHub - BryanPlummer/flickr30k_entities 上获取该数据集的详细信息和下载链接。

这两类任务在多模态人工智能领域中具有广泛的应用前景,涵盖人机交互、辅助驾驶、智能监控等多个方向。

下面是一个典型的 PyTorch 伪代码案例,来演示研究者们通常如何使用 Flickr30K Entities 数据集来评测一个模型在视觉定位(Visual Grounding),特别是 短语定位(Phrase Grounding) 任务上的性能。

1. 任务背景:短语定位 (Phrase Grounding)

  • 目标:给定一张图片和一个描述该图片的句子,模型需要为句子中的每一个指代性短语(如 “a man in a black jacket”)在图片中定位出其对应的区域(即预测一个边界框 Bounding Box)。
  • 数据集的作用:Flickr30K Entities 提供了这种“短语-边界框”的配对,是该任务最权威的评测基准之一。
  • 核心评测指标Recall@k (R@k)

2. 核心评测指标:Recall@1 (R@1)

在短语定位任务中,最常用的指标是 Recall@1。它的计算逻辑如下:

  1. 对于一个给定的短语,模型会预测出一个最可能的边界框(BBox_pred)。
  2. 数据集中,这个短语对应一个或多个真实的、人工标注的边界框(BBox_gt)。
  3. 计算模型预测的 BBox_pred 和 所有 对应的 BBox_gt 之间的 交并比 (Intersection over Union, IoU)
  4. 如果 BBox_pred 与 任何一个 BBox_gt 的 IoU 值 大于等于 0.5,那么这次预测就被认为是 正确 (Correct Hit)
  5. Recall@1 = (模型正确预测的短语数量) / (数据集中所有需要定位的短语总数)。

这个指标衡量了模型在给出唯一最佳预测时,有多大的概率能正确定位到目标。

3. PyTorch 评测伪代码示例

下面的代码模拟了一个典型的评测流程。它包含了数据加载、模型推理、IoU计算和最终指标统计的全过程。

假设:

  • 你已经有一个预训练好的模型 grounding_model
  • 这个模型接收一张预处理过的图片张量 (image_tensor) 和一个文本短语 (phrase) 作为输入。
  • 模型输出一个预测的边界框,格式为 [x_min, y_min, x_max, y_max]
import torch
import torchvision.transforms as transforms
from torch.utils.data import Dataset, DataLoader
from PIL import Image
import os
import json # 通常会预处理数据集信息到一个json文件中,方便读取# ===============================================================
#  1. 工具函数:计算 IoU
# ===============================================================
def calculate_iou(box_a, box_b):"""计算两个边界框的IoU。 box_a是预测框, box_b是真实框。"""# 确定相交区域的坐标 (x1, y1, x2, y2)x1 = max(box_a[0], box_b[0])y1 = max(box_a[1], box_b[1])x2 = min(box_a[2], box_b[2])y2 = min(box_a[3], box_b[3])# 计算相交区域面积inter_area = max(0, x2 - x1) * max(0, y2 - y1)if inter_area == 0:return 0.0# 计算两个框各自的面积box_a_area = (box_a[2] - box_a[0]) * (box_a[3] - box_a[1])box_b_area = (box_b[2] - box_b[0]) * (box_b[3] - box_b[1])# 计算并集面积union_area = float(box_a_area + box_b_area - inter_area)return inter_area / union_area# ===============================================================
#  2. 数据集类:Flickr30k Entities Test Set
# ===============================================================
class Flickr30kEntitiesDataset(Dataset):def __init__(self, data_file, image_dir, transform=None):"""Args:data_file (str): 一个预处理好的json文件路径,包含了所有测试样本。image_dir (str): 存放Flickr30k图片的文件夹。transform (callable, optional): 应用于图片的转换。"""# 在实际研究中,通常会写一个脚本预处理XML和TXT文件,# 将测试集的所有 (image_id, phrase, ground_truth_boxes) 组合提取出来存成一个列表。# 这里我们假设 `data.json` 的格式是:# [#   {"image_id": "123.jpg", "phrase": "a man", "gt_boxes": [[x,y,x,y], ...]},#   {"image_id": "123.jpg", "phrase": "a dog", "gt_boxes": [[x,y,x,y]]},#   ...# ]print("Loading test data...")with open(data_file, 'r') as f:self.data = json.load(f)self.image_dir = image_dirself.transform = transform if transform else transforms.ToTensor()def __len__(self):return len(self.data)def __getitem__(self, idx):item = self.data[idx]image_path = os.path.join(self.image_dir, item['image_id'])try:image = Image.open(image_path).convert("RGB")except FileNotFoundError:print(f"Warning: Image file not found {image_path}, skipping.")# 返回一个空样本或占位符return None, None, Nonephrase = item['phrase']gt_boxes = torch.tensor(item['gt_boxes'], dtype=torch.float32)if self.transform:image_tensor = self.transform(image)return image_tensor, phrase, gt_boxes# ===============================================================
#  3. 评测主函数
# ===============================================================
def evaluate(model, dataloader, device, iou_threshold=0.5):"""在Flickr30k Entities测试集上评测模型性能。Args:model: 预训练好的视觉定位模型。dataloader: 测试集的数据加载器。device: 'cuda' or 'cpu'.iou_threshold (float): 判断预测是否正确的IoU阈值。"""model.eval()  # 设置为评估模式correct_hits = 0total_phrases = 0with torch.no_grad(): # 评测时不需要计算梯度for batch in dataloader:# Dataloader可能会返回None,需要过滤掉if batch[0] is None:continue# 假设batch_size=1,这是评测时最常见的做法image_tensor, phrase, gt_boxes_list = batch# 将数据移动到指定设备image_tensor = image_tensor.to(device)# Dataloader会把字符串和列表包装在列表中,所以需要解包phrase = phrase[0] gt_boxes = gt_boxes_list[0].to(device)# -----------------------------------------------------# >> 核心步骤 1: 模型预测 <<# -----------------------------------------------------# 模型需要接收图片和文本短语,输出一个预测框# pred_box 的格式应为 [x_min, y_min, x_max, y_max]pred_box = model(image_tensor, phrase) # -----------------------------------------------------# >> 核心步骤 2: IoU 计算与匹配 <<# -----------------------------------------------------# 一个短语可能对应多个真实边界框(例如,一个短语'the people'可能对应图中多个人)# 我们需要计算预测框与所有真实框的IoU,并取最大值max_iou = 0for gt_box in gt_boxes:iou = calculate_iou(pred_box.cpu().numpy(), gt_box.cpu().numpy())if iou > max_iou:max_iou = iou# -----------------------------------------------------# >> 核心步骤 3: 计分 <<# -----------------------------------------------------if max_iou >= iou_threshold:correct_hits += 1total_phrases += 1# 打印进度if total_phrases % 500 == 0:print(f"Processed {total_phrases} phrases...")# -----------------------------------------------------# >> 核心步骤 4: 计算最终指标 <<# -----------------------------------------------------recall_at_1 = correct_hits / total_phrasesreturn recall_at_1# ===============================================================
#  4. 主程序入口
# ===============================================================
if __name__ == '__main__':# --- 配置 ---DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu")IMAGE_DIR = "/path/to/flickr30k-images"# 这个 preprocessed_test_data.json 文件需要你自己编写脚本生成TEST_DATA_FILE = "/path/to/preprocessed_test_data.json" MODEL_PATH = "/path/to/your/best_model.pth"# --- 加载模型 (伪代码) ---print("Loading model...")# 这里的 `GroundingModel` 是你自己定义的模型架构# grounding_model = GroundingModel(...) # grounding_model.load_state_dict(torch.load(MODEL_PATH))# grounding_model.to(DEVICE)# 为了能运行,我们创建一个模拟模型class MockGroundingModel(torch.nn.Module):def forward(self, image, phrase):# 这是一个虚拟模型,它总是返回一个固定的随机框# 真实模型会在这里进行复杂的图文交互计算print(f"  Model processing phrase: '{phrase}'")return torch.tensor([50, 50, 150, 150]) # 返回 [xmin, ymin, xmax, ymax]grounding_model = MockGroundingModel().to(DEVICE)# --- 准备数据 ---# 定义图片预处理(通常和训练时保持一致)transform = transforms.Compose([transforms.Resize((800, 800)),transforms.ToTensor(),transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])])# 创建数据集和加载器# 注意:这里的 collate_fn 用于处理数据集中可能出现的None值test_dataset = Flickr30kEntitiesDataset(TEST_DATA_FILE, IMAGE_DIR, transform)test_dataloader = DataLoader(test_dataset, batch_size=1, # 评测时 batch size 通常为 1shuffle=False,collate_fn=lambda x: x[0] if x[0][0] is not None else (None, None, None))# --- 执行评测 ---print("\nStarting evaluation...")recall = evaluate(grounding_model, test_dataloader, DEVICE)print("\n" + "="*30)print(f"Evaluation Finished!")print(f"Recall@1 on Flickr30K Entities: {recall:.4f}")print("="*30)

如何理解和使用这个框架?

  1. 数据预处理是关键:上面代码的核心依赖于一个 preprocessed_test_data.json 文件。在实际研究中,你需要编写一个一次性的脚本来解析 Flickr30K Entities 的所有 .xml.txt 文件,抽取出所有有效的“短语-边界框”对,并保存成一个易于读取的格式(如JSON),这是所有后续工作的基础。
  2. 评测的原子操作:整个评测流程可以分解为对数据集中每一个“短语”的单独评测。evaluate 函数中的 for 循环就是这个过程,它依次处理每个短语,判断其定位是否正确。
  3. 模型接口:你的模型 GroundingModel 必须有一个清晰的接口,能接收图片和文本,输出边界框。这是连接你的模型和评测脚本的桥梁。

相关文章:

  • Axure组件即拖即用:横向拖动菜单(支持左右拖动选中交互)
  • WSL2 安装与Docker安装
  • 使用lighttpd和开发板进行交互
  • Azure devops 系统之五-部署ASP.NET web app
  • 【计算机网络】Linux下简单的UDP服务器(超详细)
  • Chrome 通过FTP,HTTP 调用 Everything 浏览和搜索本地文件系统
  • [蓝桥杯]剪格子
  • [蓝桥杯]螺旋折线
  • 43. 远程分布式测试实现
  • 搜索引擎2.0(based elasticsearch6.8)设计与实现细节(完整版)
  • 03 APP 自动化-定位元素工具元素定位
  • iOS —— UI 初探
  • docker、ctr、crictl命令简介与使用
  • PostgreSQL优化实践:从查询到架构的性能提升指南
  • DOCKER使用记录
  • 一个完整的日志收集方案:Elasticsearch + Logstash + Kibana+Filebeat (一)
  • 计算机网络 TCP篇常见面试题总结
  • 邂逅Webpack和打包过程
  • 十四、【测试执行篇】让测试跑起来:API 接口测试执行器设计与实现 (后端执行逻辑)
  • 基于springboot的益智游戏系统的设计与实现
  • wordpress 代码 工具/东莞关键词seo优化
  • 天津网站优化收费/百度官网认证多少钱一年
  • 区块链技术网站开发/百度账号设置
  • 填写网站备案信息/培训seo去哪家机构最好
  • 网站备案掉了/百度旗下的所有产品
  • 株洲营销型网站建设/seo服务建议