- 多模态
- 人工智能
- 深度学习
- NLP
- 计算机视觉
- 预训练
【免费下载链接】mmf
A modular framework for vision & language multimodal research from Facebook AI Research (FAIR)
导读
VinVL 是微软提出的视觉-语言预训练模型,其核心贡献在于重新审视了**图像区域特征(image region features)**在视觉-语言(VL)模型中的关键作用——通过更强的目标检测表征显著提升下游 VL 任务表现。MMF 仓库完整集成了 VinVL 的 PyTorch 实现(源自 microsoft/Oscar 代码库),并提供了从特征提取、数据集包装到训练/微调的整套工具链。阅读本文后,你将掌握:VinVL 在 MMF 中的模型结构与数据流原理、如何用 MMF 脚本为任意图像目录提取 VinVL 特征、如何借助vinvl数据集包装器在任意数据集上做微调与预训练,以及两条可直接运行的训练命令。
一、VinVL 是什么:模型背景与论文定位
VinVL(论文标题VinVL: Revisiting Visual Representations in Vision-Language Models,Zhang, P. 等人,CVPR 2021)的核心理念是:在视觉-语言模型中,视觉表征的质量比模型架构本身更能决定最终性能。VinVL 使用基于 Visual Genome(VG)目标检测标签训练出的属性感知检测器(AttrRCNN)来提取图像区域特征,再将这些特征与 BERT 文本编码融合完成预训练与下游微调。
在 MMF 中,VinVL 模型的 PyTorch 实现最初发布在 microsoft/Oscar 仓库,随后被移植进 MMF,作为独立的vinvl模型注册。使用时请引用以下两篇论文:
- Zhang, P., Li, X., Hu, X., Yang, J., Zhang, L., Wang, L., ... & Gao, J. (2021).VinVL: Revisiting visual representations in vision-language models. In Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition (pp. 5579-5588).
- Li, X., Yin, X., Li, C., Hu, X., Zhang, P., Zhang, L., Wang, L., Hu, H., Dong, L., Wei, F., Choi, Y., Gao, J. (2020).Oscar: Object-Semantics Aligned Pre-training for Vision-Language Tasks. ECCV 2020.
对应的 BibTeX 条目也完整保留在仓库文档 website/docs/projects/vinvl.md 中,可直接复制引用。
二、安装环境
VinVL 模型的运行依赖 MMF 框架本身及其 BERT/Transformer 相关组件。安装方式与 MMF 通用安装流程一致,请参考仓库内的安装指南 website/docs/getting_started/installation.mdx 完成环境配置。需要特别注意的是:
- 特征提取脚本依赖微软的
scene_graph_benchmark(AttrRCNN)代码库,需要单独克隆并安装(详见下文"特征提取"一节); - 模型代码对
transformers库做了兼容处理:优先尝试transformers3.modeling_bert,失败则回退到transformers.modeling_bert(见 mmf/models/vinvl.py),请确保安装的 transformers 版本满足要求。
三、核心特性:用更好的视觉表征喂饱 VL 模型
VinVL 的主要贡献在于证明了图像区域特征对 VL 模型性能的巨大影响。在 MMF 中使用 VinVL 特征有两条路径:
3.1 路径一:下载预提取特征并重映射
如果目标数据集是热门数据集(如 COCO、VQA2),可以直接下载官方预提取的 VinVL 特征,然后将它们重映射(remapping)到 MMF 数据集格式。这种方式的优点是不需要本地跑检测模型,开箱即用。
3.2 路径二:用 MMF 脚本并行提取特征
对于任意图像目录,可以运行 MMF 自带的特征提取脚本 tools/scripts/features/extract_features_vinvl.py:
python mmf/tools/scripts/features/extract_features_vinvl.py \ --model_name X-152-C4 \ --image_dir /path/to/image/directory \ --output_folder /path/to/output该脚本基于 scene-graph-benchmark 仓库的tools/demo/demo_image.py改造而来(对应 commit8e14944,oscar/vinvl 仓库版本4788a74),其核心流程如下:
- 自动下载检测模型与配置:脚本内置了
X-152-C4模型的下载地址(见 tools/scripts/features/extract_features_vinvl.py),也可通过--model_file/--config_file指定本地权重; - 构建 AttrRCNN 检测模型:通过
AttrRCNN(cfg)加载权重,开启MODEL.ATTRIBUTE_ON、TEST.OUTPUT_FEATURE、TEST.OUTPUT_RELATION_FEATURE等配置,输出 region 的类别、置信度、box 特征与关系特征(见 tools/scripts/features/extract_features_vinvl.py); - 批量推理:将
--batch_size张图像组成 image list 送入模型,默认每张图提取--num_features=100个区域特征; - 特征归一化与落盘:
_norm_box将 bbox 归一化到 [0,1] 区间并拼接宽高差,随后将box_features与归一化 bbox 拼接(torch.cat([box_features, bbox], dim=1),见 tools/scripts/features/extract_features_vinvl.py),最终每个区域特征维度为2054(2048 视觉特征 + 6 维 bbox 信息),这正是 VinVL 模型默认img_feature_dim=2054的来源。每个图像输出<name>.npy(特征)与<name>_info.npy(图像信息,含 labels、attr_labels、bbox 等字段)。
脚本常用参数:
| 参数 | 默认值 | 说明 |
|---|---|---|
--model_name | X-152-C4 | 使用的检测模型 |
--model_file/--config_file | None | 指定本地权重与配置,覆盖 model_name |
--image_dir | 必填 | 图像目录或单个图像文件 |
--output_folder | ./output | 特征输出目录 |
--batch_size | 2 | 推理批大小 |
--num_features | 100 | 每张图提取的区域特征数 |
--start_index/--end_index | 0/None | 支持分片处理 |
--exclude_list | ./list | 排除文件列表(每行一个图像名) |
--background | 关闭 | 是否输出背景类预测 |
提取完成后,将 mmf/configs/datasets/ 下对应数据集的defaults.yaml中features路径指向新特征目录即可。例如 VQA2 的配置位于 mmf/configs/datasets/vqa2/defaults.yaml,把features.train/val/test指向 VinVL 特征即可。更详细的分步教程可参考仓库文档 website/docs/tutorials/image_feature_extraction_vinvl.md。
四、VinVL 数据集:为任意数据集注入标签与属性信号
4.1 设计动机
VinVL 在微调(finetuning)和预训练(pretraining)阶段需要通用数据集不支持的独特输入:目标检测标签文本、属性文本,以及用于 3-way 对比损失的随机负样本。MMF 的解法是引入一个名为vinvl的数据集包装器——它本身不包含新图像或新文本,而是在已有数据集(称为 base dataset)之上做样本增强。
例如,base dataset 是 VQA2,普通情况下返回样本{image, text};而 VinVL 数据集请求一个样本时会返回:
{image, text', rand_caption, rand_label}其中:
text' = text + labels:原始问题文本拼接上该图的目标检测标签/属性文本;rand_caption:从数据集中随机抽取的另一个样本的文本(用作对比学习的负样本候选);rand_label:随机样本的目标检测标签文本。
4.2 使用前提与假设
VinVL 数据集对 base dataset 和配置有以下硬性假设(见 mmf/datasets/builders/vinvl/dataset.py):
- base dataset 返回的样本中包含字符串键
"text"; - 数据集配置中存在
label_map的 JSON 文件路径,该 JSON 包含idx_to_attribute与idx_to_label两个映射(VinVL OD 使用 VG 标签,映射文件为VG-SGG-dicts-vgoi6-clipped.json,可从 VinVL model zoo 获取,配置文件中的示例路径见 mmf/configs/datasets/vinvl/defaults.yaml); features_db指向由 VinVL 特征提取脚本生成的特征。
4.3 底层实现:Builder 与 Dataset 的协作模式
从源码结构看,vinvl的实现采用了一种新设计模式来解决"处理器无法访问数据库"的问题:
- VinVLBuilder(mmf/datasets/builders/vinvl/builder.py):
load()方法会实例化两个数据集——先根据base_dataset_name从 registry 获取 base dataset 的 builder 并构建 base dataset 实例,然后将 VinVL 配置中的text_processor(vinvl_text_tokenizer)与label_map写回 base 配置,最后调用vinvl_dataset.set_base_dataset(base_dataset)完成包装; - VinVLDataset(mmf/datasets/builders/vinvl/dataset.py):
load_item(idx)先让 base dataset 加载原始样本,再构造text_processor的输入参数{text, text_b, random_captions, random_labels};其中text_b由get_label_str()生成——它读取样本image_info_0中的labels与attr_labels字段,通过idx_to_label和idx_to_attribute映射拼成标签字符串(见 mmf/datasets/builders/vinvl/dataset.py)。
注意:add_tags标志在测试集(test)下为 False,即测试阶段不注入标签与随机负样本,避免评测被污染。
五、配置文件全解:从数据集到模型
5.1 数据集配置
MMF 为 VinVL 提供了开箱即用的数据集配置 mmf/configs/datasets/vinvl/defaults.yaml,它通过includes引入 VQA2 的默认配置作为 base dataset:
includes: - ../vqa2/defaults.yaml dataset_config: vinvl: base_dataset_name: vqa2 label_map: /private/home/ryanjiang/winoground/pretrained_models/VG-SGG-dicts-vgoi6-clipped.json base_dataset: ${dataset_config.vqa2} processors: text_processor: type: vinvl_text_tokenizer params: mask_probability: 0关键字段:
| 字段 | 说明 |
|---|---|
base_dataset_name | base dataset 的注册名,用于在 registry 中查找其 builder |
label_map | 含idx_to_attribute/idx_to_label的 JSON 路径 |
base_dataset | base dataset 的完整 YAML 配置(这里用${dataset_config.vqa2}引用) |
processors.text_processor | 必须为vinvl_text_tokenizer,其参数继承自 MaskedTokenProcessor 的配置模式 |
5.2 文本处理器:VinVLTextTokenizer
vinvl_text_tokenizer是 VinVL 专用的文本处理器(注册名为vinvl_text_tokenizer,见 mmf/datasets/processors/bert_processors.py),它在 MaskedTokenProcessor 的基础上增加了:
- 双句拼接:通过
get_pair_text_tokens将text(问题)与text_b(标签文本)以[CLS] A [SEP] B [SEP]形式拼接(见 mmf/datasets/processors/bert_processors.py); - MLM 掩码:
mask_probability控制随机[MASK]替换概率,输出input_ids_masked与lm_label_ids供 MLM 头使用; - 对比学习输入:当
corrupt_probability > 0时,从random_captions/random_labels中按corrupt_caption_probability构造损坏样本,输出input_ids_corrupt、input_mask_corrupt、segment_ids_corrupt与contrastive_label(3 分类:0=匹配,1=损坏文本,2=损坏标签,见 mmf/datasets/processors/bert_processors.py)。若不使用对比损失,将corrupt_probability设为 0 即可。
常用参数:from_pretrained(默认bert-base-uncased)、max_seq_length(默认 70)、mask_probability(默认 0)、corrupt_probability(默认 0)。
5.3 模型配置
模型默认配置位于 mmf/configs/models/vinvl/defaults.yaml:
model_config: vinvl: heads: test: type: mlp freeze: false lr_multiplier: 1.0 in_dim: 768 hidden_size: 1536 num_labels: 3129 pooler_name: bert_pooler bert_model_name: bert-base-uncased img_feature_dim: 2054 img_feature_type: 'frcnn' use_img_layernorm: 1 img_layer_norm_eps: 1e-12 max_img_seq_len: 70与源码中VinVL.Config数据类(mmf/models/vinvl.py)一一对应:
| 配置项 | 默认值 | 源码含义 |
|---|---|---|
bert_model_name | bert-base-uncased | 基础 BERT 权重,用于初始化文本侧与预训练 |
img_feature_dim | 2054 | 图像特征维度(2048 视觉特征 + 6 维 bbox) |
img_feature_type | frcnn | 特征类型标识 |
use_img_layernorm | True | 图像嵌入投影后是否加 LayerNorm |
img_layer_norm_eps | 1e-12 | 图像 LayerNorm 的 epsilon |
max_img_seq_len | 70 | 最大图像区域序列长度 |
do_pretraining | False | 切换分类微调 / 预训练两种构建路径 |
5.4 完整训练配置示例
VQA2 的完整训练配置在 projects/vinvl/configs/vqa2/defaults.yaml,要点:
model_config: vinvl: do_pretraining: false heads: vqa2: type: mlp num_labels: 3129 dataset_config: vinvl: base_dataset_name: vqa2 processors: text_processor: type: vinvl_text_tokenizer params: from_pretrained: bert-base-uncased corrupt_probability: 0 tokenizer_config: type: bert-base-uncased params: do_lower_case: true mask_probability: 0 training: clip_gradients: false lr_scheduler: true max_updates: 44000 checkpoint_interval: 4000 evaluation_interval: 4000 batch_size: 256 # 32 per GPU * 8 GPU find_unused_parameters: false log_interval: 1000 optimizer: type: adam_w params: lr: 1e-4 eps: 1e-8 weight_decay: 1e-2 scheduler: type: warmup_cosine params: num_warmup_steps: 4400 num_training_steps: ${training.max_updates} evaluation: metrics: - type: vqa_accuracy datasets: - vqa2要点解读:
do_pretraining: false表示走分类微调路径,heads.vqa2配置 MLP 分类头,num_labels: 3129对应 VQA2 的答案类别数;corrupt_probability: 0表示微调阶段不启用对比学习负采样;- 训练采用 AdamW + warmup cosine 调度,共 44000 步更新,batch size 256(8 卡 × 32);
- 评估指标为 VQA 准确率。
六、训练与微调实战
6.1 从零训练
完成特征提取并重定向数据集配置后,在 VQA2.0 上从头训练 VinVL:
mmf_run config=projects/vinvl/configs/vqa2/defaults.yaml run_type=train dataset=vinvl model=vinvl6.2 微调预训练模型
从 MMF 模型动物园加载预训练权重并微调:
mmf_run config=projects/vinvl/configs/vqa2/defaults.yaml run_type=train dataset=vinvl model=vinvl checkpoint.resume_zoo=vinvl.pretrainedcheckpoint.resume_zoo=vinvl.pretrained会从模型动物园 mmf/configs/zoo/models.yaml 拉取vinvl.pretrained资源(版本1.0_2020_11_29)。动物园中还提供了vinvl.finetuned.coco_ir(COCO 图像检索微调权重)可作为对照。
七、源码级原理:模型如何消费这些特征
7.1 VinVLBase:BERT 编码器的"视觉化"包装
VinVLBase(mmf/models/vinvl.py)是 VinVL 的核心骨干,本质是对BertEncoder的薄包装,额外处理图像特征输入:
- 图像嵌入投影:
nn.Linear(img_dim, hidden_size)将 2054 维区域特征投影到 BERT hidden size(768),可选叠加 LayerNorm 与 Dropout(use_img_layernorm); - 序列拼接:
embedding_output = torch.cat((text_embedding_output, img_embedding_output), 1)将文本与图像特征拼接成一个序列送入 BERT encoder——这正是"文本 + 图像区域"联合建模的关键一步; - 掩码扩展:
_get_attention_mask(mmf/models/vinvl.py)将文本 padding mask 与图像有效区域 mask(由image_info.max_features生成)拼接,保证注意力只作用在真实 token 与有效区域上。
从测试用例 tests/models/test_vinvl.py 可以看到,当img_feature_dim=2054、batch 8 时,输出张量形状为[8, 95, 768](95 = 25 文本 token + 70 图像区域)。
7.2 双模式:分类微调与预训练
VinVL模型类(mmf/models/vinvl.py)根据do_pretraining构建两种子模型:
- VinVLForClassification:
VinVLBase+ MLP 分类头,交叉熵损失;forward输出scores与losses.ce; - VinVLForPretraining:
VinVLBase+MLM 头+ThreeWayContrastive 头。MLM 头负责掩码语言建模(对文本 token 计算 masked LM loss,图像位置标签置 -1),ThreeWayContrastive 头做 3-way 对比分类——0 表示图文匹配、1 表示文本被损坏、2 表示标签被损坏(见 mmf/models/vinvl.py)。预训练前向需要同时提供input_ids_masked(MLM 用)与input_ids_corrupt(对比用)。
测试 tests/models/test_vinvl.py 验证了预训练前向会同时产出masked_lm_loss与three_way_contrastive_loss。
7.3 一条完整的推荐链路
综合上述内容,在 MMF 中使用 VinVL 的推荐流程为:
- 用 tools/scripts/features/extract_features_vinvl.py 为目标图像集提取 2054 维区域特征;
- 修改 mmf/configs/datasets/ 下对应数据集的
defaults.yaml,将features指向新特征目录; - 以
vinvl为 dataset 名(底层由 mmf/datasets/builders/vinvl/builder.py 完成对 base dataset 的包装),配置label_map与vinvl_text_tokenizer; - 运行
mmf_run进行从头训练或checkpoint.resume_zoo=vinvl.pretrained微调。
八、测试与验证
仓库为 VinVL 提供了较完整的单元测试,可作为验证环境与理解行为的参考:
- tests/models/test_vinvl.py:覆盖
VinVLBase前向输出形状、分类前向(含ce损失)、预训练前向(含masked_lm_loss与three_way_contrastive_loss)、以及通过配置构建VinVL模型的全流程; - tests/datasets/test_bert_processors.py:覆盖
vinvl_text_tokenizer的 tokenization、MLM 掩码输出、corrupt_probability=0时无 corrupt 字段等行为。
这些测试同时印证了前文对配置字段、输入张量结构与损失组成的描述,读者可据此快速搭建自己的 VinVL 实验。
- 多模态
- 人工智能
- 深度学习
- NLP
- 计算机视觉
- 预训练
【免费下载链接】mmf
A modular framework for vision & language multimodal research from Facebook AI Research (FAIR)
相关推荐
为什么OCR总是认错字?uvdoc-npu昇腾NPU文档图像矫正模型完全入门指南
为什么OCR总是认错字?uvdoc npu昇腾NPU文档图像矫正模型完全入门指南 uvdoc npu 是一个可以直接在华为昇腾 NPU 上运行的 文档图像矫正模
人工智能计算机视觉图像处理OCRAscendMMF 中的 ViLT 模型:无卷积与区域监督的视觉语言 Transformer 训练与微调实战
MMF 中的 ViLT 模型:无卷积与区域监督的视觉语言 Transformer 训练与微调实战 ViLT(Vision and Language Transf
多模态人工智能深度学习NLP计算机视觉预训练Windows Precision Touchpad 驱动终极指南:让苹果触控板在 Windows 上原生级工作
Windows Precision Touchpad 驱动终极指南:让苹果触控板在 Windows 上原生级工作 你是否曾在 Windows 系统中使用苹果 M
驱动开发系统底层硬件开发
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考