前言:在当今人工智能与机器学习领域,视觉-语言预训练(Vision-and-Language Pre-training, VLP)任务正逐渐崭露头角,其对于推动跨模态智能系统的进步起着至关重要的作用。在这些系统中,图像与文本不再是孤立的实体,而是能够相互理解、相互增强的互补信息源。正是在这样的背景下,我们提出了一种全新的BLIP - VLP任务框架,它不仅融合了图像与文本的最前沿技术,还通过创新的预训练策略,为跨模态智能应用开辟了新的可能性。
本文所涉及所有资源均在传知代码平台可获取
目录
概述
演示效果
核心代码
写在最后
概述
视觉语言预训练(VLP)显著提升了众多视觉语言任务的执行效果。其中,对图像和文本进行分类是一种重要的预训练任务。尽管如此,目前大部分的预训练任务主要集中在基于理解或基于生成的任务上。这些预训练方法都没有考虑到用户对输入的反馈和交互。尽管利用Web收集的带有噪声的图像-文本对来扩充数据集在很大程度上增强了其性能,但这种方法仍然是一个不太理想的监控来源。
BLIP代表了一种创新的VLP架构,它能够灵活地应用于视觉语言的理解和生成任务中,在视频解码系统中,字幕的处理非常重要。BLIP有效地利用了带有噪声的网络数据通过引导字幕,其中字幕生成器负责生成合成字幕,而滤波器则负责去除含有噪声的字幕。其对应的模型结构如下图所示:
BLIP采用ViT模型作为其图像编码器,而ViT则将输入的图像分割成补丁块,并进一步将这些补丁块编码为嵌入序列,同时还使用了额外的[cls]标记以表示图像的全局特征。这种方法使得编码器能够对一个特定的目标进行分类,并且能根据用户指定的上下文信息自动地确定是否需要修改该目标。BLIP提出了一种名为编码器-解码器的多模式混合(MED)的多任务模型,其目的是为了预先训练一个具备理解和生成功能的统一模型,该模型能够在以下三种功能之一中运行:
单峰编码器:
单峰式编码器分别对图像和文本进行编码,文本编码器与BERT相同,其中[CLS]标记被附加到文本输入的开头,以总结句子。BLIP使用图像-文本对比(ITC)损失的训练单峰编码器,以对齐视觉和语言表示。
基于图像的文本编码器:
基于图像的文本编码器,同时在文本编码器的每个transformer块的自注意力层SA和前馈网络FFN之间插入一个额外的交叉注意力层CA来注入视觉信息。特定于任务的[Encode]标记附加到文本中,[Encode]的输出嵌入用于图像-文本对的多模态表示。基于图像的文本编码器使用图像-文本匹配(ITM)损失进行训练,以区分匹配和不匹配的图像-文本对。
基于图像的文本编码器:
基于图像的文本编码器以因果自注意力层取代双向自注意力层,一个[Decode]标记用于表示序列的开始,一个序列结束标记用于表示序列的结束。基于图像的文本编码器使用语言建模(LM)损失进行训练,以生成给定图像的标题。
预训练的目标函数可以从下图看出:
BLIP在预训练中共同优化了三个目标函数,两个基于理解的目标函数和一个基于生成的目标函数。每个图像-文本对只需要通过计算量较大的ViT进行一次前向传递,并通过文本转换器进行三次前向传递,用以激活不同的功能以计算如下所述的三种损失:
图像-文本对比损失(ITC):
图像-文本对比损失激活单峰编码器,它的目的是通过鼓励匹配的图像-文本对具有相似的表示,不匹配的图像-文本对具有差异较大的表示来对齐视觉转换器和文本转换器的特征空间。
图像-文本匹配损失(ITM):
图像-文本匹配损失激活基于图像的文本编码器,它旨在学习图像-文本多模态表示,以捕获视觉和语言之间的细粒度对齐。ITM是一个二元分类任务,模型使用ITM头部(线性层)来预测给定图像-文本对的多模态特征是匹配的,还是负的不匹配的。
语言建模损失(LM):
语言建模损失激活基于图像的文本解码器,其目的是生成给定图像的文本描述。该损失训练模型以自回归的方式最大化文本的可能性,优化了交叉熵损失。
为了在利用多任务学习的同时执行有效的预训练,文本编码器和文本解码器共享除了自注意力层之外的所有参数,因为编码和解码任务之间的差异最好由自注意力层捕获。编码和解码任务之间的嵌入层,自注意力层和全连接前馈网络层的作用相似,因此,共享这些层可以提高训练效率,同时受益于多任务学习。
由于标注成本过高,高质量的人工标注图像-文本对的数量有限{(Ih,Th)},最近的工作使用了大量从网络上搜取的图像和替代文本对{(Iw,Tw)},然而,替代文本通常不能准确的描述图像的视觉内容,使他们成为一个嘈杂的信号,对于学习视觉对齐来说是次优的,如下图所示:
BLIP提出了Captioning 和Filtering(CapFilt),这是一种提高文本语料库质量的新方法,它引入了两个模块,一个用于生成给定web图像的标题的captioner,以及一个用于去除图像-文本对噪声的filter。captioner和filter都是从相同的预训练的MED模型初始化的,并在COCO数据集上分别进行微调,调优是一个轻量级的过程。
具体来说,captioner是一个基于图像的文本解码器,它使用LM目标函数进行微调,以解码给定图像的文本。给定web图像IwIw,captioner生成合成的标题TsTs。filter是一个基于图像的文本编码器,它使用ITC和ITM目标函数进行微调,以确定文本是否与图像匹配。如果标题预测文本与图像不匹配,则认为文本有噪声,过滤器去除原始网络文本和合成文本中的噪声文本。最后,BLIP将过滤后的图像文本对于人工注释的图像文本对结合起来形成一个新的数据集,使用它来训练一个新的模型。
演示效果
通过如下命令进行环境部署:
# 创建环境
conda create -n lavis python=3.8
conda activate lavis
pip install salesforce-lavis
# 进阶版包含源码
git clone https://github.com/salesforce/LAVIS.git
cd LAVIS
pip install -e .
BLIP对整个图像的关注程度可视化如下:
BLIP对局部分词的关注程度:
BLIP生成多个标题通过如下方式进行:
核心代码
下面这段代码的作用是加载一个预训练好的图像描述生成模型,然后使用该模型对给定的图像生成多个标题,如下:
# 加载预训练好的模型
model, vis_processors, _ = load_model_and_preprocess(
name="blip_caption", model_type="large_coco", is_eval=True, device=device
)
# 以下是其他可以使用的模型
# model, vis_processors, _ = load_model_and_preprocess(
# name="blip_caption", model_type="base_coco", is_eval=True, device=device
# )
# 对图像进行预处理操作
image = vis_processors["eval"](raw_image).unsqueeze(0).to(device)
# 采用核函数采样生成多个标题
model.generate({"image": image}, use_nucleus_sampling=True, num_captions=3)
下面这段代码的作用是加载一个预训练的图像文本匹配模型,并使用该模型计算并可视化图像和文本的梯度,通过计算每个 token 的梯度并可视化。首先,获取注意力矩阵和 token 的 ID 迭代器。然后,迭代每个 token 和对应的注意力矩阵,并使用 getAttMap 函数将注意力矩阵映射到图像上进行模糊处理。最后,使用 imshow 方法将每个 token 的 Grad-CAM 结果显示在一个或多个子图中,同时在图像上方显示对应的文本:
# 加载预训练模型
# model, vis_processors, text_processors = load_model_and_preprocess("blip_image_text_matching", "base", device=device, is_eval=True)
model, vis_processors, text_processors = load_model_and_preprocess("blip_image_text_matching", "large", device=device, is_eval=True)
# 准备操作
from matplotlib import pyplot as plt
from lavis.common.gradcam import getAttMap
from lavis.models.blip_models.blip_image_text_matching import compute_gradcam
import numpy as np
dst_w = 720
w, h = raw_image.size
scaling_factor = dst_w / w
resized_img = raw_image.resize((int(w * scaling_factor), int(h * scaling_factor)))
norm_img = np.float32(resized_img) / 255
# 分别处理图像和文本
img = vis_processors["eval"](raw_image).unsqueeze(0).to(device)
txt = text_processors["eval"](caption)
# 计算梯度
txt_tokens = model.tokenizer(txt, return_tensors="pt").to(device)
gradcam, _ = compute_gradcam(model, img, txt, txt_tokens, block_num=7)
# 计算整个图像的梯度并且可视化
avg_gradcam = getAttMap(norm_img, gradcam[0][1].numpy(), blur=True)
# fig, ax = plt.subplots(num_image, 1, figsize=(15,5*num_image))
fig, ax = plt.subplots(1, 1, figsize=(10, 10))
ax.imshow(avg_gradcam)
# 计算每一个token的梯度并且可视化
num_image = len(txt_tokens.input_ids[0]) - 2
fig, ax = plt.subplots(num_image, 1, figsize=(15, 5 * num_image))
gradcam_iter = iter(gradcam[0][2:-1].numpy())
token_id_iter = iter(txt_tokens.input_ids[0][1:-1])
for i, (gradcam, token_id) in enumerate(zip(gradcam_iter, token_id_iter)):
word = model.tokenizer.decode([token_id])
gradcam_image = getAttMap(norm_img, gradcam, blur=True)
ax[i].imshow(gradcam_image)
ax[i].set_yticks([])
ax[i].set_xticks([])
ax[i].set_xlabel(word)
写在最后
通过本文的探讨,我们可以看到,BLIP-VLP新框架在图像描述生成、视觉问答、图像检索等多个领域都展现出了卓越的性能。这不仅证明了其技术的先进性,更预示着它在未来跨模态智能应用中的主导地位,现在,我们正站在跨模态智能技术的新起点上,BLIP-VLP新框架无疑为我们指明了一条充满希望的探索之路。随着技术的不断进步和应用场景的不断拓展,我们相信,这一框架将在未来引领更多的创新和突破。
我们期待着BLIP-VLP新框架在更多领域大放异彩,为人工智能领域带来新的革命。让我们一起期待并见证跨模态智能技术的辉煌未来,共同探索这个充满无限可能的新世界。
详细复现过程的项目源码、数据和预训练好的模型可从该文章下方附件获取。