【传知代码】BLIP - VLP任务的新框架(论文复现)

news2024/11/24 11:07:24

前言:在当今人工智能与机器学习领域,视觉-语言预训练(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新框架在更多领域大放异彩,为人工智能领域带来新的革命。让我们一起期待并见证跨模态智能技术的辉煌未来,共同探索这个充满无限可能的新世界。

详细复现过程的项目源码、数据和预训练好的模型可从该文章下方附件获取。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1807188.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vue -ant -design 卡片是布局 实现动态计算 当前的 左右间距 实现居中

是这样的一个样式 我们使用display :flex 布局的时候 我们全部剧中 display: flex;align-items: center;justify-content: center; 如果是上述的代码来说的话 总是最后的一个也是会居中的 这样就比较丑 我们好像就没有什么好的办法了 我们这自己写的 肯定没有组件牛 如果有…

【Redis学习笔记04】Jedis客户端(上)

Java客户端操作Redis Java生态丰富,自定义的客户端非常多,常见的有Jedis、Lettuce、以及Spring整合后的RedisTemplate,但是对于初学者而言,从Jedis开始入门学习是非常容易上手的,因为Jedis中的API与原生Redis命令高度…

基于栅格占据概率和距离场的机器人覆盖轨迹模拟

基于栅格占据概率和距离场的机器人覆盖轨迹模拟 简介 辐射场模型实现 理论基础 指数函数建模 我们使用指数函数来表示机器人在某个栅格上停留时间对覆盖概率的影响: p ( t ) 1 − e − λ t p(t) 1 - e^{-\lambda t} p(t)1−e−λt 其中 λ \lambda λ 是控制增长速率…

java线程相关知识点

Java多线程涉及以下几个关键点 1.线程生命周期:理解线程从创建到销毁的各个阶段,包括新建、运行、阻塞、等待、计时等待和终止。 2.线程同步:掌握如何使用synchronized关键字和Lock接口来同步代码,防止数据竞争和死锁。 3.线程间通…

vivado HW_DEVICE

硬件设备 描述 在Vivado Design Suite的硬件管理器功能中,每个硬件目标都可以 具有一个或多个Xilinx FPGA设备进行编程或用于调试目的。这个 hw_device对象是通过hw_server打开的hw_target上的物理部分。这个 current_hw_device命令指定或返回当前设备。 相关对象 硬…

Linux系统编程(十二)线程同步、锁、条件变量、信号量

线程同步: 协同步调,对公共区域数据按序访问。防止数据混乱,产生与时间有关的错误。数据混乱的原因 一、互斥锁/互斥量mutex 1. 建议锁(协同锁): 公共数据进行保护。所有线程【应该】在访问公共数据前先拿…

Vue3 + TS + Antd + Pinia 从零搭建后台系统(一) 脚手架搭建 + 入口配置

简易后台系统搭建开启,分几篇文章更新,本篇主要先搭架子,配置入口文件等目录 效果图一、搭建脚手架:二、处理package.json基础需要的依赖及运行脚本三、创建环境运行文件四、填充vue.config.ts配置文件五、配置vite-env.d.ts使项目…

微服务开发与实战Day04 - 网关路由和配置

一、网关路由 网关&#xff1a;就是网络的关口&#xff0c;负责请求的路由、转发、身份校验。 在SpringCloud中网关的实现包括两种&#xff1a; 1. 快速入门 Spring Cloud Gateway 步骤&#xff1a; ①新建hm-gateway模块 ②引入依赖pom.xml(hm-gateway) <?xml version…

【python】OpenCV GUI——Trackbar(14.2)

学习来自 OpenCV基础&#xff08;12&#xff09;OpenCV GUI中的鼠标和滑动条 文章目录 GUI 滑条介绍cv2.createTrackbar 介绍牛刀小试 GUI 滑条介绍 GUI滑动条是一种直观且快速的调节控件&#xff0c;主要用于改变一个数值或相对值。以下是关于GUI滑动条的详细介绍&#xff1a…

course-nlp——6-rnn-english-numbers

本文参考自https://github.com/fastai/course-nlp。 使用 RNN 预测数字的英文单词版本 在上一课中&#xff0c;我们将 RNN 用作语言模型的一部分。今天&#xff0c;我们将深入了解 RNN 是什么以及它们如何工作。我们将使用尝试预测数字的英文单词版本的问题来实现这一点。 让…

Llama模型家族之Stanford NLP ReFT源代码探索 (三)reft_model.py代码解析

LlaMA 3 系列博客 基于 LlaMA 3 LangGraph 在windows本地部署大模型 &#xff08;一&#xff09; 基于 LlaMA 3 LangGraph 在windows本地部署大模型 &#xff08;二&#xff09; 基于 LlaMA 3 LangGraph 在windows本地部署大模型 &#xff08;三&#xff09; 基于 LlaMA…

C# WPF入门学习主线篇(十七)—— UniformGrid布局容器

C# WPF入门学习主线篇&#xff08;十七&#xff09;—— UniformGrid布局容器 欢迎来到C# WPF入门学习系列的第十七篇。在前几篇文章中&#xff0c;我们已经探讨了 Canvas、StackPanel、WrapPanel、DockPanel 和 Grid 布局容器及其使用方法。本篇博客将介绍另一种非常实用且简单…

推荐三款你不知道的良心软件

Tico——抠图、拼图软件 抠图软件大家见过很多了把&#xff0c;但是从多张图片中抠出来的图片拼接成一张图片你们很少见过吧。 Tico就是一款将抠出来的图片拼接成一张新图片的软件&#xff0c;目前仅支持IOS平台。 Tico拼贴图提供了强大的图像编辑和处理功能&#xff0c;用户…

预期值与实际值对比

编辑实际值和预期值变量 因为在单独的代码当中&#xff0c;我们先定义了变量str&#xff0c;所以在matcher时传入str参数&#xff0c;但当我们要把这串代码写在testrun当中&#xff0c;改下传入的参数&#xff0c;与excel表做连接 匹配的结果是excel表中的expect结果&#xf…

整型变量、赋值语句、cin 语句

1、变量&#xff1a; 在程序运行期间其值可以改变的量称为变量。变量是代码中最重要的元素。每个变量应该有一个名字&#xff0c;同一个程序内的变量名不重复。 请注意区分变量名和变量值这两个不同的概念&#xff08;相当于张三的名字和他本人是不同的概念一样&#xff09;。…

入门matlab

常识 如何建一个新文件 创建新文件&#xff0c;点击新建&#xff0c;我们就可以开始写代码了 为什么要在代码开头加入clear 假如我们有2个文件&#xff0c;第一个文件里面给x赋值100&#xff0c;第二个文件为输出x 依次运行&#xff1a; 结果输出100&#xff0c;这是因为它们…

elasticsearch安装与使用(1)-使用docker安装Elasticsearch

ES的优点&#xff1a; 1、分布式准实时2、提供REST风格的API接口&#xff0c;是用户可解借助任何语言使用https对ES执行请求来完成搜索任务&#xff1b;3、提供聚合功能 1、Elasticsearch安装 docker network create elastic docker pull docker.elastic.co/elasticsearch/e…

MySQL 与 PostgreSQL 关键对比二(SQL语法)

目录 1 详细示例 1.1自动增量列 1.2 字符串连接 1.3 JSON 支持 2 总结 MySQL 和 PostgreSQL 是两种流行的开源关系数据库管理系统&#xff08;RDBMS&#xff09;。尽管它们在许多方面相似&#xff0c;但在 SQL 语法和功能上存在一些显著差异。 以下SQL语句的执行如果需要开…

Redis系列-5 Redis分布式锁

背景&#xff1a; 本文介绍Redis分布式锁的内容&#xff0c;包括Redis相关命令和Lua脚本的介绍&#xff0c;以及操作分布式锁的流程与消息&#xff0c;最后结合Redission源码介绍分布式锁的实现原理。 1.基本命令 1.1 基本键值对的设置 设值: set key value 取值: get key …

深度网络及经典网络简介

深度网络及经典网络简介 导语加深网络一个更深的CNN提高识别精度Data Augmentation 层的加深 经典网络VGGGoogLeNetResNet 高速学习迁移学习GPU分布式学习计算位缩减 强化学习总结参考文献 导语 深度学习简单来说&#xff0c;就是加深了层数的神经网络&#xff0c;前面已经提到…