多模态论文一:CLIP模型主要内容讲解【原理+代码】

一、CLIP模型主要内容讲解

  CLIP(Contrastive Language-Image Pre-training)是OpenAI在2021年发布的一种用于图像和文本联合表示学习的模型。CLIP的核心思想是通过对比学习来预训练一个模型,使其能够理解图像和文本之间的关系。以下是CLIP的工作原理和步骤:

1. 数据集

  CLIP使用大规模的图像-文本对数据集进行预训练,例如从互联网上收集的4亿个图像-文本对。这些数据集包含了丰富的图像和对应的描述文本,使得模型能够学习到广泛的视觉概念和语言表达。

2. 模型架构

  CLIP由两个主要部分组成:

  • 图像编码器:用于将图像转换为特征向量。图像编码器可以是卷积神经网络(如ResNet)或Transformer模型(如ViT)。
  • 文本编码器:用于将文本转换为特征向量。文本编码器通常是一个Transformer模型。

3. 对比学习

  CLIP通过对比学习来训练模型。具体来说,对于一个批次中的每个图像-文本对,模型会计算图像和文本的特征向量,并使用对比损失函数来优化模型参数。对比损失函数的目标是使得匹配的图像-文本对的特征向量尽可能接近,而不匹配的图像-文本对的特征向量尽可能远离。

4. 损失函数

  CLIP使用的损失函数是对称的对比损失函数。具体来说,对于每个图像-文本对,模型会计算两个方向的损失:

  • 图像到文本的损失:计算图像特征向量和文本特征向量之间的相似度,并优化使得匹配的图像-文本对的相似度最大化。
  • 文本到图像的损失:计算文本特征向量和图像特征向量之间的相似度,并优化使得匹配的文本-图像对的相似度最大化。

5. 推理阶段

  在推理阶段,CLIP可以用于多种任务,例如:

  • 图像分类:给定一个图像,模型可以将其特征向量与预定义的文本类别(如“猫”、“狗”等)的特征向量进行比较,选择相似度最高的类别作为预测结果。
  • 文本到图像检索:给定一个文本描述,模型可以将其特征向量与图像库中的图像特征向量进行比较,检索出与文本描述最匹配的图像。

二、 动机

  在计算机视觉领域,迁移学习的一种常见做法是先在如ImageNet这样的大规模数据集上进行预训练,然后在具体的下游任务上进行微调。这种预训练通常基于有监督学习,需要大量的数据标注,因此成本较高。近年来,随着自监督学习方法的兴起,这一局面得到了改变。自监督学习方法,包括基于对比学习的方法如MoCo和SimCLR,以及基于图像掩码的方法如MAE和BeiT,它们的优势在于不再依赖于数据标注。然而,无论是传统的监督学习还是新兴的自监督学习,它们在迁移到下游任务时,仍然需要进行有监督的微调,无法实现真正的零样本学习(Zero-shot)。
  对于有监督模型而言,由于它们在预训练数据集上使用了固定类别数的分类器,因此在新的数据集上需要重新定义分类器并进行训练。而对于自监督模型,虽然代理任务有助于表征学习,但在迁移到其他数据集时,同样需要添加新的分类器进行有监督训练。
  相比之下,在自然语言处理(NLP)领域,基于自回归或语言掩码的预训练方法已经相当成熟,并且预训练模型能够轻松实现零样本迁移到下游任务,例如OpenAI的GPT-3。这种差异一方面源于文本和图像这两种完全不同的模态,另一方面则是因为NLP模型可以利用互联网上丰富多样的文本数据。
  这就引出了一个问题:我们能否利用互联网上的大量文本来预训练视觉模型,从而实现类似NLP领域的零样本迁移能力?这一问题的探讨,不仅涉及跨模态学习的深入研究,也为视觉模型的预训练和迁移学习开辟了新的可能性。
  所以openai基于前面的工作,从文本信息获取监督信息的方式,做了以下两件事:1.足够大的数据集(爬取清洗了4亿对图像文本对),2.多模态(图像跟文本),统一用transformer架构,使用对比学习训练。
在这里插入图片描述
  蓝色是回归预测,也就是根据图像去预测对应的文本标签,这个任务难度是巨大的,而且一个图像可以有多个文本表述范式;橘黄色是在特诊空间进行预测,根据图像特征去预测文本特征。绿色是图像-文本匹对的损失,这个是最快收敛的,任务相对简单。同时这样的设置可以更好地将 图像与文本的语义信息绑定到一起。

三、模型

在这里插入图片描述

1. 训练过程

伪代码
在这里插入图片描述

2. 模型细节

  这里的image encoder可以是ResNet也可以是ViT;text encoder可以是CBOW也可以是Transformer。
图像、文本分别经过encoder之后得到的特征,会进行线性投影以及L2归一化操作。
  L2 归一化(L2 normalization)是一种常见的数据预处理技术,用于将数据向量的长度缩放到单位范数(即 L2 范数为 1)。对于一个向量 v = [ v 1 , v 2 , … , v n ] \mathbf{v} = [v_1, v_2, \ldots, v_n] v=[v1,v2,,vn],其 L2 范数定义为:
∥ v ∥ 2 = v 1 2 + v 2 2 + ⋯ + v n 2 \|\mathbf{v}\|_2 = \sqrt{v_1^2 + v_2^2 + \cdots + v_n^2} v2=v12+v22++vn2
L2 归一化后的向量 v ′ \mathbf{v}' v 计算如下:
v ′ = v ∥ v ∥ 2 = [ v 1 ∥ v ∥ 2 , v 2 ∥ v ∥ 2 , … , v n ∥ v ∥ 2 ] \mathbf{v}' = \frac{\mathbf{v}}{\|\mathbf{v}\|_2} = \left[ \frac{v_1}{\|\mathbf{v}\|_2}, \frac{v_2}{\|\mathbf{v}\|_2}, \ldots, \frac{v_n}{\|\mathbf{v}\|_2} \right] v=v2v=[v2v1,v2v2,,v2vn]
这样处理后,向量 v ′ \mathbf{v}' v 的 L2 范数为 1:
∥ v ′ ∥ 2 = ( v 1 ∥ v ∥ 2 ) 2 + ( v 2 ∥ v ∥ 2 ) 2 + ⋯ + ( v n ∥ v ∥ 2 ) 2 = 1 \|\mathbf{v}'\|_2 = \sqrt{\left( \frac{v_1}{\|\mathbf{v}\|_2} \right)^2 + \left( \frac{v_2}{\|\mathbf{v}\|_2} \right)^2 + \cdots + \left( \frac{v_n}{\|\mathbf{v}\|_2} \right)^2} = 1 v2=(v2v1)2+(v2v2)2++(v2vn)2 =1

3. 损失函数细节

对称性的损失设计

  在CLIP的训练中,损失设计包括两个方向:从图像到文本和从文本到图像。这两个方向的交叉熵损失计算如下:

  1. 计算相似度矩阵

    • 假设有 n n n 对图像-文本对,图像编码表示为 I \mathbf{I} I,文本编码表示为 T \mathbf{T} T
    • 相似度矩阵 S \mathbf{S} S 的元素 s i j s_{ij} sij 表示第 i i i 个图像和第 j j j个文本之间的相似度。通常,使用余弦相似度计算:
      S i j = cos ⁡ ( I i , T j ) = I i ⋅ T j ∥ I i ∥ ∥ T j ∥ S_{ij} = \cos(\mathbf{I}_i, \mathbf{T}_j) = \frac{\mathbf{I}_i \cdot \mathbf{T}_j}{\|\mathbf{I}_i\| \|\mathbf{T}_j\|} Sij=cos(Ii,Tj)=Ii∥∥TjIiTj
  2. 定义标签

    • 标签向量为 t e x t l a b e l s = np.arange ( n ) text{labels} = \text{np.arange}(n) textlabels=np.arange(n),表示对角线上的元素是匹配的图像-文本对。
  3. 交叉熵损失

    • 图像到文本的交叉熵损失 loss i \text{loss}_i lossi
      loss i = cross_entropy_loss ( S , labels , axis = 0 ) \text{loss}_i = \text{cross\_entropy\_loss}(\mathbf{S}, \text{labels}, \text{axis}=0) lossi=cross_entropy_loss(S,labels,axis=0)
      这里, axis = 0 \text{axis}=0 axis=0 表示对每一行(即每个图像对应的所有文本)计算损失。

    • 文本到图像的交叉熵损失 ( \text{loss}_t )
      loss t = cross_entropy_loss ( S , labels , axis = 1 ) \text{loss}_t = \text{cross\_entropy\_loss}(\mathbf{S}, \text{labels}, \text{axis}=1) losst=cross_entropy_loss(S,labels,axis=1)
      这里, axis = 1 \text{axis}=1 axis=1 表示对每一列(即每个文本对应的所有图像)计算损失。

  4. 综合损失

    • 最终的损失是这两个方向的交叉熵损失的平均值:
      loss = loss i + loss t 2 \text{loss} = \frac{\text{loss}_i + \text{loss}_t}{2} loss=2lossi+losst

其中,

  • 图像到文本的交叉熵损失

    • 对于每个图像 I i \mathbf{I}_i Ii,计算它与所有文本的相似度 S i , : \mathbf{S}_{i,:} Si,:
    • 使用交叉熵损失,将这些相似度与标签(正确匹配的文本索引)进行比较,确保每个图像找到正确的文本描述。
  • 文本到图像的交叉熵损失

    • 对于每个文本 T i \mathbf{T}_i Ti,计算它与所有图像的相似度 S : , i \mathbf{S}_{:,i} S:,i
    • 使用交叉熵损失,将这些相似度与标签(正确匹配的图像索引)进行比较,确保每个文本找到正确的图像。

  这种设计的对称性确保了模型在训练过程中同时优化图像到文本和文本到图像的匹配效果。通过这种方式,模型不仅能够从图像中找到相应的文本描述,还能够从文本中找到对应的图像。这种双向优化使得CLIP模型在实际应用中表现更加鲁棒和准确。

4. zero shot tranfer

  这个算是CLIP最大的创新点,之前的有监督学习或者说无监督学习,主要的目的是获取一个强大的特征抽取器(backbone),但是在应用到下游任务的时候,基本上还是要收集下游数据进行微调的。CLIP做到这样的两点:1.无需微调;2.文本信息引导模型迁移

5. promot engineering and ensembing

在做zero-shot推理的时候要用到。

- 标签单词文本多义性polysemy,所以只给一个标签单词并不合适。
- 训练的时候文本信息是句子,而预测的时候标签是单词,这有影响,存在distribution gap的问题,可以做promot template来巧妙解决,如设定好模板:"A photo of a {label}",同时可以再细化,比如已经知道数据集是宠物分类,那就可以使用"A photo of a {label},a type of pet."
- ensembing就是使用多个提示模板,然后综合多个模板的结果。

在CLIP模型中,文本和图像都会被提取为特征嵌入(feature embeddings)。这些特征嵌入的形状(shape)取决于模型的架构和输入数据的处理方式。

6. 图像特征、文本特征嵌入的形状

对于图像特征嵌入,通常的形状是 (batch_size, embedding_dim),其中:

  • batch_size 是输入图像的批次大小。
  • embedding_dim 是图像特征嵌入的维度,这个维度取决于模型的架构。例如,对于CLIP的ViT-B/32模型,embedding_dim 通常是512。

对于文本特征嵌入,形状通常也是 (batch_size, embedding_dim),其中:

  • batch_size 是输入文本的批次大小。
  • embedding_dim 是文本特征嵌入的维度,这个维度同样取决于模型的架构。对于CLIP的ViT-B/32模型,embedding_dim 通常也是512。

代码

这里使用PyTorch和Hugging Face的Transformers库来加载和使用CLIP模型。这个代码展示了如何使用CLIP模型进行图像分类和文本到图像的检索。

  1. 安装必要的库:
pip install torch transformers pillow
  1. 加载CLIP模型并进行图像分类:
import torch
from PIL import Image
from transformers import CLIPProcessor, CLIPModel# 加载预训练的CLIP模型和处理器
model = CLIPModel.from_pretrained("openai/clip-vit-base-patch32")
processor = CLIPProcessor.from_pretrained("openai/clip-vit-base-patch32")# 定义图像路径和文本类别
image_path = "path_to_your_image.jpg"
text_labels = ["a photo of a cat", "a photo of a dog", "a photo of a bird"]# 加载图像
image = Image.open(image_path)# 处理图像和文本
inputs = processor(text=text_labels, images=image, return_tensors="pt", padding=True)# 计算特征向量并进行分类
with torch.no_grad():outputs = model(**inputs)logits_per_image = outputs.logits_per_image  # 图像到文本的相似度得分
probs = logits_per_image.softmax(dim=1)  # 概率分布# 输出分类结果
for i, label in enumerate(text_labels):print(f"{label}: {probs[0][i].item():.2%}")# 输出最高概率的类别
predicted_class = text_labels[probs[0].argmax()]
print(f"Predicted class: {predicted_class}")

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

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

相关文章

数据传输安全--SSL VPN

目录 IPSEC在Client to LAN场景下比较吃力的表现 SSL VPV SSL VPN优势 SSL协议 SSL所在层次 SSL工作原理 SSL握手协议、SSL密码变化协议、SSL警告协议三个协议作用 工作过程 1、进行TCP三次握手、建立网络连接会话 2、客户端先发送Client HELLO包,下图是包…

Oracle对比两表数据的不一致

MINUS 基本语法如下 [SQL 语句 1] MINUS [SQL 语句 2];举个例子: select 1 from dual minus select 2 from dual--运行结果 1-------------------------------- select 2 from dual minus select 1 from dual--运行结果 2所以,如果想找所有不一致的&a…

【数据结构】二叉树链式结构——感受递归的暴力美学

前言: 在上篇文章【数据结构】二叉树——顺序结构——堆及其实现中,实现了二叉树的顺序结构,使用堆来实现了二叉树这样一个数据结构;现在就来实现而二叉树的链式结构。 一、链式结构 链式结构,使用链表来表示一颗二叉树…

FPGA:有限状态机

从以下6个实验理解状态机的概念 开发板频率为 50 M H z 50MHz 50MHz,一个时钟周期是 20 n s 20ns 20ns。 1、实验一:LED灯亮0.25秒、灭0.75秒的状态循环 通过之前的分析,我们实现频闪灯时,是让led灯在0.5秒实现一次翻转,而这里…

经典文献阅读之--World Models for Autonomous Driving(自动驾驶的世界模型:综述)

Tip: 如果你在进行深度学习、自动驾驶、模型推理、微调或AI绘画出图等任务,并且需要GPU资源,可以考虑使用UCloud云计算旗下的Compshare的GPU算力云平台。他们提供高性价比的4090 GPU,按时收费每卡2.6元,月卡只需要1.7元每小时&…

html+css 实现水波纹按钮

前言:哈喽,大家好,今天给大家分享htmlcss 绚丽效果!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏关注哦 💕 文…

vue3前端开发-小兔鲜项目-使用pinia插件完成token的本地存储

vue3前端开发-小兔鲜项目-使用pinia插件完成token的本地存储!实际业务开发中,token是一个表示着用户登录状态的重要信息,它有自己的生命周期。因此,这个参数值必须实例化存储在本地中。不能跟着pinia。因为pinia是基于内存设计的模…

事务和函数索引

事务 事务的定义 事务(Transaction),就是将一组SQL语句放在同一批次内去执行,如果一个SQL语句出错,则该批次内 的所有SQL都将被取消执行。 事务的特点 一个事务中如果有一个数据库操作失败,那么整个 事务…

若依框架 : 生成代码

6.生成代码 6.1.配置生成设置 ruoyi-generator -> src -> main -> resources -> generator.yml 由于 案例中 表都有 前缀 为 tta_ , 这里设置去掉 6.2.生成代码 6.2.1.导入数据库中的表 6.2.2.修改设置 6.2.2.1.设置生成信息 点击 编辑 -> 生成信息 特别…

m4a怎么转mp3?m4a转mp3的几种方法教程

m4a怎么转mp3?M4A音频格式的全称MPEG-4 Audio,是一种音频压缩格式。这种格式以其卓越的音质和相对较小的文件大小而广受欢迎,尤其是在音乐存储、在线流媒体以及音频编辑等领域。M4A格式被广泛应用于苹果公司的产品中,如iPhone、iP…

开放式耳机会成为未来的主流吗?开放式耳机推荐指南

开放式耳机是否会成为未来的主流,是一个值得探讨的问题。 从目前的市场趋势和技术发展来看,有一些因素支持开放式耳机可能成为主流。 一方面,人们对于健康和舒适的关注度不断提高。长时间佩戴传统耳机可能导致耳部不适,而开放式…

在Linux中,部署及优化Tomcat

tomcat概述 自 2017 年 11月编程语言排行榜 Java 占比 13%,高居榜首,Tomcat 也一度成为 Java开发人员的首选。其开源、占用系统资源少、跨平台等特性深受广大程序员喜爱。本章主要学习如何部署 Tomcat 服务,根据生产环境实现多个虚拟主机的配置&#xf…

【QGroundControl二次开发】五.python生成自定义MAVLink消息及使用

一 . 环境配置 参考&#xff1a; MAVLink代码生成-C# 二. 生成MAVLINK协议 在MAVlink源码下找到message_definitions/common.xml&#xff0c;修改其中的内容。 例如&#xff1a; <message id"12" name"DISTANCE_SENSOR"><description>Dedi…

【Code Complete2】Note-1 [启发式编程、管理复杂度、隐藏设计]

【Code Complete2】_Note-1 [启发式编程、管理复杂度、隐藏设计] 文章目录 【Code Complete2】_Note-1 [启发式编程、管理复杂度、隐藏设计]启发式编程管理复杂度隐藏设计--减少“改动所影响的代码量” 启发式编程 ​ **设计是一个启发的过程&#xff0c;充满了不确定性&#…

记录|cmd方式恢复U盘中的数据

目录 前言一、CMD恢复Step1.Step2. 更新时间 前言 参考文章&#xff1a; u盘数据误删怎么恢复&#xff1f;安利8款数据恢复软件免费版&#xff08;2024 NEW&#xff09; 回家后&#xff0c;家人说U盘里的歌突然没有了。我就用电脑看了看&#xff0c;发现电脑中能看到U盘中是满的…

修改启动方案

AMP设置为1Linux&#xff08;CPU0&#xff09; 3HAL&#xff08;CPU1、 2、 3&#xff09; 配置。 用vscode打开its 配置文件rk3568_amp_linux.its文件修改 /* SPDX-License-Identifier: BSD-3-Clause */ /** Copyright (c) 2022 Rockchip Electronics Co., Ltd.*//dts-v1/; /…

【优秀python算法毕设】基于python时间序列模型分析气温变化趋势的设计与实现

1 绪论 1.1 研究背景与意义 在气候变化日益受到全球关注的背景下&#xff0c;天气气温的变化已经对人们的生活各方面都产生了影响&#xff0c;人们在外出时大多都会在手机上看看天气如何&#xff0c;根据天气的变化来决定衣物的穿着和出行的安排。[1]如今手机能提供的信息已经…

【大模型】基于LoRA微调Gemma大模型(1)

文章目录 一、LoRA工作原理1.1 基本原理1.2 实现步骤 二、LoRA 实现2.1 PEFT库&#xff1a;高效参数微调LoraConfig类&#xff1a;配置参数 2.2 TRL库SFTTrainer 类 三、代码实现3.1 核心代码3.2 完整代码 参考资料 大模型微调技术有很多&#xff0c;如P-Tuning、LoRA 等&#…

操作系统杂项(八)

目录 一、简述互斥锁的机制&#xff0c;互斥锁与读写的区别 1、互斥锁机制 2、互斥锁和读写锁 二、简述信号量及其作用 1、概念 2、原理 3、作用 三、简述进程、线程的中断切换过程 1、进程上下文切换 2、线程上下文切换 四、简述自旋锁和互斥锁的使用场景 1、互斥…

宝塔单ip,新建多站点

报错如上&#xff1a; 那么如何新建多站点呢 先随便写个名字上去&#xff0c;然后再重新绑定别的端口… 这个时候访问99端口即可 。 如果是有域名&#xff0c;则不需要这样做 、直接80端口也可以多站点