LAVIS 中 Flickr30K 跨模态检索实战指南:数据集、评测指标、排行榜与 BLIP 复现全流程
【免费下载链接】LAVISLAVIS - A One-stop Library for Language-Vision Intelligence项目地址: https://gitcode.com/gh_mirrors/la/LAVIS
本文聚焦 LAVIS(A One-stop Library for Language-Vision Intelligence)中基于Flickr30K 数据集的跨模态检索(Cross-modal Retrieval)任务,系统讲解数据集的构成与下载方式、TR/IR 评测指标的定义、官方排行榜的参考水平,并结合仓库源码给出基于 BLIP 模型的训练与评测命令、核心配置参数及底层实现原理。读完本文,你将能够在 LAVIS 中完成从数据获取、模型微调到 Recall@K 指标复现与解读的完整闭环。
Flickr30K 数据集概述
Flickr30K 是一个经典的多模态检索基准数据集,LAVIS 的数据集卡片文档(dataset_card/flickr_retrieval.md)将其描述为:包含 31,000+ 张从 Flickr 采集的图片,每张图片由人类标注者提供 5 句参考描述句子(reference sentences)。这一"图片 + 5 句人工描述"的标注结构,使它成为图像-文本对齐研究的核心数据源。
从仓库配置看,LAVIS 针对 Flickr30K 提供了 train / val / test 三份标注文件(lavis/configs/datasets/flickr30k/defaults.yaml):
datasets: flickr30k: data_type: images build_info: annotations: train: url: https://storage.googleapis.com/sfr-vision-language-research/datasets/flickr30k_train.json storage: flickr30k/annotations/train.json val: url: https://storage.googleapis.com/sfr-vision-language-research/datasets/flickr30k_val.json storage: flickr30k/annotations/val.json test: url: https://storage.googleapis.com/sfr-vision-language-research/datasets/flickr30k_test.json storage: flickr30k/annotations/test.json images: storage: flickr30k/images每条标注记录中,image_id唯一标识一张图片,caption为对应的描述文本,instance_id标识具体的"图-文"配对实例。这些字段会在数据集加载与评测环节被直接使用(详见下文"评测原理"部分)。
任务定义:双向跨模态检索
Flickr30K 在 LAVIS 中承担的是**跨模态检索(Cross-modal Retrieval)**任务,包含两个方向:
- 图像→文本检索(image-text,文档中记作 TR):以一张图片为查询(query),从文本库(gallery)中检索与之最匹配的句子;
- 文本→图像检索(text-image,文档中记作 IR):以一句文本为查询,从图像库中检索最匹配的图片。
两个方向共同检验模型是否真正学会了跨模态的对齐能力——即视觉特征与语义特征是否被投影到同一个可比较的度量空间中。
评测指标:Recall@K 与 TR/IR 记法
文档明确指出,该任务通用的评测指标是recall@k,其含义为:在进行 k 次检索尝试后,正确结果出现在召回集合中的比例(recall score)。LAVIS 使用两个缩写来区分检索方向:
- TR:image-text retrieval recall score(图像→文本方向);
- IR:text-image retrieval score(文本→图像方向)。
排行榜按TR@1从高到低排序。以 TR@1 为例,它表示"用每张图片作为查询,在全部文本中检索,模型给出的 Top-1 结果命中该图片 5 句参考句子中任意一句的比例"。
源码中的指标计算逻辑
指标的具体计算可以在检索任务实现(lavis/tasks/retrieval.py)中看到完整逻辑。评测时模型会先生成两个相似度矩阵score_i2t(图像→文本)与score_t2i(文本→图像),然后:
- 图像→文本(TR):对每张图片的得分向量降序排序,遍历该图片的 5 个参考句子,找到它们各自在排序结果中的最小排名
rank;TR@1/5/10分别统计rank < 1/5/10的图片占比再乘以 100:ranks = np.zeros(scores_i2t.shape[0]) for index, score in enumerate(scores_i2t): inds = np.argsort(score)[::-1] rank = 1e20 for i in img2txt[index]: tmp = np.where(inds == i)[0][0] if tmp < rank: rank = tmp ranks[index] = rank tr1 = 100.0 * len(np.where(ranks < 1)[0]) / len(ranks) - 文本→图像(IR):每条文本只有一个对应的目标图片,因此直接取该文本目标图片在降序排序中的排名:
for index, score in enumerate(scores_t2i): inds = np.argsort(score)[::-1] ranks[index] = np.where(inds == txt2img[index])[0][0] ir1 = 100.0 * len(np.where(ranks < 1)[0]) / len(ranks)
评测结果会以 JSON 形式输出txt_r1/txt_r5/txt_r10、img_r1/img_r5/img_r10、各自的均值(txt_r_mean、img_r_mean)、总均值r_mean与聚合指标agg_metrics,并追加写入输出目录下的evaluate.txt文件。
数据集的图-文映射结构
上述计算依赖txt2img与img2txt两个映射,它们在评测数据集类中构建(lavis/datasets/datasets/retrieval_datasets.py 中的RetrievalEvalDataset):遍历每条标注,将每张图片的 5 条 caption 展开成 5 条独立文本,建立img2txt[img_id] -> [txt_id...]与txt2img[txt_id] -> img_id的双向索引。训练数据集RetrievalDataset则负责为每条"图-文"实例返回经过视觉/文本处理器处理后的样本(image、text_input、image_id、instance_id)。LAVIS 通过 lavis/datasets/builders/retrieval_builder.py 中的Flickr30kBuilder(注册名为flickr30k)将配置与上述数据集类串联起来。
官方排行榜(Leaderboard)
文档给出的排行榜按 TR@1 排序,反映了该任务上的主流模型水平(Flickr30K 测试集):
| Rank | Model | TR@1 | TR@5 | TR@10 | IR@1 | IR@5 | IR@10 |
|---|---|---|---|---|---|---|---|
| 1 | BLIP | 97.2 | 99.9 | 100.0 | 87.5 | 97.7 | 98.9 |
| 2 | X-VLM | 97.1 | 100.0 | 100.0 | 86.9 | 97.3 | 98.7 |
| 3 | ALBEF | 95.9 | 99.8 | 100.0 | 85.6 | 97.5 | 98.9 |
| 4 | ALIGN | 95.3 | 99.8 | 100.0 | 84.9 | 97.4 | 98.6 |
| 5 | VILLA | 87.9 | 97.5 | 98.8 | 76.3 | 94.2 | 96.8 |
| 6 | UNITER | 87.3 | 98.0 | 99.2 | 75.6 | 94.1 | 96.8 |
可以看到,榜单前四名(BLIP、X-VLM、ALBEF、ALIGN)的 TR@1 均超过 95%,且 TR@10 几乎触顶 100%;相比之下,较早的 UNITER、VILLA 等模型在 TR@1 上约为 87%~88%,差距主要来自预训练数据规模与训练目标的设计。值得说明的是,该表为数据集卡片文档收录的公开结果,实际复现时建议以仓库内模型配置对应的官方 checkpoint 评测值为准。
数据集自动下载
文档提供了 Flickr30K 的自动下载命令(需要 Kaggle 账号与 API Key):
cd lavis/datasets/download_scripts && python download_flickr.py下载脚本 lavis/datasets/download_scripts/download_flickr.py 的实现细节如下:
- 数据源为 Kaggle 上的
hsankesara/flickr-image-dataset,脚本会提示你先在 Kaggle API 文档 创建账号与 API Token; - 脚本读取
configs/datasets/flickr30k/defaults.yaml中的build_info.images.storage得到图片存储目录,并将其父目录下的download作为下载暂存目录; - 通过
opendatasets下载后,把flickr30k_images目录移动为storage_dir / "flickr30k-images",随后清理暂存目录; - 若存储目录已存在,脚本会直接提示 "Dataset already exists" 并退出,避免重复下载。
图片与标注(train/val/test 三份 JSON)下载完成后,分别落在配置中storage字段指定的相对路径下,LAVIS 的缓存机制(lavis.common.utils.get_cache_path)会将其解析到实际的缓存根目录。
在 LAVIS 中复现 BLIP 检索
Flickr30K 是 BLIP(Bootstrapping Language-Image Pre-training)检索模型的典型评测场景。仓库为 BLIP 检索提供了完整的训练与评测脚本,命令均基于torch.distributed.run多卡启动。
评测(Evaluation)
评测脚本 run_scripts/blip/eval/eval_ret_flickr.sh:
python -m torch.distributed.run --nproc_per_node=8 evaluate.py --cfg-path lavis/projects/blip/eval/ret_flickr_eval.yaml对应评测配置 lavis/projects/blip/eval/ret_flickr_eval.yaml 的关键项:
model: arch: blip_retrieval model_type: flickr datasets: flickr30k: vis_processor: eval: name: "blip_image_eval" image_size: 384 text_processor: eval: name: "blip_caption" run: task: retrieval num_workers: 4 batch_size_eval: 64 test_splits: ["test"] device: "cuda" k_test: 128 seed: 42 output_dir: "output/Retrieval_Flickr30k" evaluate: True要点说明:
k_test: 128控制评测时的候选规模。k_test会传递给模型中的compute_sim_matrix(见 lavis/models/blip_models/blip_retrieval.py),在计算相似度矩阵时只对每个查询的 Top-k 候选做细粒度的图文匹配(ITM)重排,从而在保持精度的同时显著降低计算量;- 视觉处理器使用
blip_image_eval(输入尺寸 384),文本处理器使用blip_caption,与模型配置 lavis/configs/models/blip_retrieval_flickr.yaml 中的预处理设置一致; evaluate: True表示只做评测;评测完成后指标写入output/Retrieval_Flickr30k/evaluate.txt。
微调训练(Fine-tuning)
训练脚本 run_scripts/blip/train/train_retrieval_flickr.sh:
python -m torch.distributed.run --nproc_per_node=8 train.py --cfg-path lavis/projects/blip/train/retrieval_flickr_ft.yaml对应训练配置 lavis/projects/blip/train/retrieval_flickr_ft.yaml 的关键项:
model: arch: blip_retrieval model_type: flickr load_finetuned: False queue_size: 57600 negative_all_rank: False run: task: retrieval lr_sched: "linear_warmup_cosine_lr" init_lr: 1e-5 min_lr: 0 weight_decay: 0.05 max_epoch: 6 num_workers: 4 batch_size_train: 32 batch_size_eval: 64 train_splits: ["train"] valid_splits: ["val", "test"] test_splits: ["test"] k_test: 128 amp: False evaluate: False要点说明:
- 训练阶段
load_finetuned: False,模型从预训练权重出发;queue_size: 57600是 ITC(Image-Text Contrastive)损失中使用的动量队列大小,配合negative_all_rank: False控制负样本的构造方式; - 优化器采用 warmup + cosine 学习率调度,初始学习率
1e-5,权重衰减0.05,训练 6 个 epoch; - 训练时使用
blip_image_train视觉处理器(训练增强,输入尺寸同样为 384); - 与评测一致,
k_test: 128同时用于训练过程中的验证集指标计算。
底层实现与调用链
结合源码可以梳理出 Flickr30K 检索任务在 LAVIS 中的完整调用链:
- 任务注册:
RetrievalTask通过@registry.register_task("retrieval")注册(lavis/tasks/retrieval.py),配置中run.task: retrieval即指向它; - 数据构建:
Flickr30kBuilder(lavis/datasets/builders/retrieval_builder.py)根据datasets.flickr30k配置构建RetrievalDataset(训练)与RetrievalEvalDataset(评测); - 相似度计算:评测时
RetrievalTask.evaluation调用model.compute_sim_matrix(data_loader, task_cfg=self.cfg),BLIP 检索模型内部以k_test为候选规模生成score_i2t与score_t2i两个相似度矩阵(lavis/models/blip_models/blip_retrieval.py); - 指标报告:
_report_metrics利用数据集提供的img2txt/txt2img映射,计算 TR@K 与 IR@K 并落盘evaluate.txt。
模型权重方面,评测配置 lavis/configs/models/blip_retrieval_flickr.yaml 指向官方在 Flickr30K 上微调好的权重(finetuned字段),并给出image_size: 384、vit_type: "base"、embed_dim: 256、queue_size: 57600、alpha: 0.4等模型超参数,其中alpha用于平衡 ITC 与 ITM 两种训练目标的损失权重。此外,vit_grad_ckpt: True与vit_ckpt_layer: 4表明视觉编码器使用了梯度检查点与分层冻结策略以节省显存。
进一步探索
- 对比同仓库中 COCO 检索数据卡片 dataset_card/coco_retrieval.md,可了解更大规模(33 万+ 图片、150 万+ 描述)的图文检索基准及其榜单水平;
- 若需了解 ALBEF 在 Flickr30K 上的检索配置,可参考 lavis/configs/models/albef_retrieval_flickr.yaml 与 run_scripts/albef/eval/eval_flickr30k_retrieval.sh;
- 数据集的浏览器工具 app/dataset_browser.py 可用于可视化检索样本,帮助快速定位数据问题。
【免费下载链接】LAVISLAVIS - A One-stop Library for Language-Vision Intelligence项目地址: https://gitcode.com/gh_mirrors/la/LAVIS
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考