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

news2024/9/24 11:33:07

一、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.coloradmin.cn/o/1950150.html

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

相关文章

Ruoyi-WMS本地运行

所需软件 1、JDK:8 安装包:https://www.oracle.com/java/technologies/javase/javase8-archive-downloads.htmlopen in new window 安装文档:https://cloud.tencent.com/developer/article/1698454open in new window 2、Redis 3.0 安装包&a…

【STM32 FreeRTOS】FreeRTOS的移植

其实这篇文章不侧重移植,因为我们会使用CubeMX配置,那样会自动移植FreeRTOS。 关于FreeRTOS,可以参考官网:FreeRTOS - Quick start guide 当我们在CubeMX中配置了CMSIS_V2后尝试编译的时候会有一个弹窗。 第一个问题就是强烈建议…

ubuntu实践

目录 扩容 本机上ping不通新建立的虚拟机 ssh连接 装sshd ssh客户端版本较低,会报key exchange算法不匹配问题 ubuntun上装docker 将centos7下的安装包改造成适配 ubuntu的包 参考文章 扩容 Hyper-V 管理器安装的ubutun扩容磁盘空间说明_hype-v磁盘扩容-…

私域电商丨软件系统开发中,一定要避开的几个坑,看懂少很多弯路

文丨微三云胡佳东,点击上方“关注”,为你分享市场商业模式电商干货。 - 大家好,我是软件开发胡佳东,每天为大家分享互联网资讯干货! 在数字化时代的今天,软件开发是已经成为推动科技进步和商业发展的重要…

【软件推荐】“聊崽”聊天机器人

不是广告!不是广告!不是广告! 自己小团队开发的产品,现在正在公测。 前言 什么是聊天机器人,将你自己的微信接入机器人系统,让你的微信能够具备智能客服、游戏交互、问题解答、气氛活跃等能力。 同样的问…

本地化部署一个简单的AI大模型,Llama3.1

7 月 23 日消息,Meta 今晚正式发布llama3.1,提供 8B、70B 及 405B 参数版本。 Meta 称 4050 亿参数的 Llama 3.1-405B 在常识、可引导性、数学、工具使用和多语言翻译等一系列任务中,可与 GPT-4、GPT-4o、Claude 3.5 Sonnet 等领先的闭源模型…

python-绝对值排序(赛氪OJ)

[题目描述] 输入 n 个整数,按照绝对值从大到小排序后输出。保证所有整数的绝对值不同。输入格式: 输入数据有多组,每组占一行,每行的第一个数字为 n ,接着是 n 个整数, n0 表示输入数据的结束,不做处理。输…

实现领域驱动设计(DDD)系列详解:领域模型的持久化

领域驱动设计主要通过限界上下文应对复杂度,它是绑定业务架构、应用架构和数据架构的关键架构单元。设计由领域而非数据驱动,且为了保证定义了领域模型的应用架构和定义了数据模型的数据架构的变化方向相同,就应该在领域建模阶段率先定义领域…

【MSP430】DriverLib库函数,GPIO相关函数介绍

采用了DriverLib库函数,以下是对GPIO相关函数的介绍 MSP430F5xx_6xx_DriverLib_Users_Guide-2_91_13_01(函数库手册).pdf 在MSP430单片机中,GPIO相关的函数提供了一套完整的接口用于配置和控制GPIO引脚。这些函数可以方便地管理引脚的输入输出模式、电平…

【微信小程序实战教程】之微信小程序 WXS 语法详解

WXS语法 WXS是微信小程序的一套脚本语言,其特性包括:模块、变量、注释、运算符、语句、数据类型、基础类库等。在本章我们主要介绍WXS语言的特性与基本用法,以及 WXS 与 JavaScript 之间的不同之处。 1 WXS介绍 在微信小程序中&#xff0c…

利用换元法计算积分的常见题型(考研高数复习)

考研中常见的几种换元法积分计算题 (1)被积式仅包含一个根式:根号下为有 a a a 和 x x x 的平方和/平方差 此种类型的积分题型,可以通过构造单个锐角大小为 t t t 的直角三角形,利用勾股定理和三角函数进行代换。 平方和的情况 形如 ∫…

40V/4.5A的AH6240直接替代PT2470的直流有刷电机驱动芯片

135-3806-7573本文将详细介绍AH6240直流有刷电机驱动芯片如何直接替代PT2470,并探讨其在实际应用中的优势。 一、AH6240与PT2470的对比分析 AH6240是一款高性能的直流有刷电机驱动芯片,具有40V/4.5A的输出能力,支持宽电压范围输入&#xff0…

【Android】Activity生命周期与四种启动模式

文章目录 生命周期返回栈Activity状态生命周期方法 启动模式standard模式singleTask模式singleTop模式singleInstance模式配置方式 生命周期 返回栈 每个Activity的状态由它在Activity栈(又叫“回退栈back stack”)中的位置决定,是所有当前…

scratch笔记

一、图章 练习题: 【画笔】 一、选择题 1.怎样修改图章的颜色?(D ) A. 只需要一个数字来设置颜色 B. 设置RGB的值 C. 在画笔中设置颜色、饱和度、亮度 D. 在外观中设置或修改角色颜色特效 2.执行下面程序,最后可能出…

idea中如何创建yml、yaml、properties配置文件

目录 1、配置文件 2、创建yml配置文件 3、配置文件的优先级 1、配置文件 我们一直使用springboot项目创建完毕后自带的application.properties进行属性的配置,那其实呢,在springboot项目当中是支持多种配置方式的,除了支持properties配置文件…

视频加密软件哪个好?怎么进行视频文件加密?

员工A:“最近公司有很多重要视频资料需要保存和分享,但担心安全问题,你有什么好推荐吗?” 员工B:“当然有,市面上有很多视频加密软件,其中我觉得域智盾非常不错。它是一款功能强大的企业文件加…

【Beyond Compare】Beyond Compare下载、安装与使用详细教程

目录 🌺1 概述 🎄2 Beyond Compare 安装包下载 🌼3 安装详细教程 🍂4 免费注册 🌍5 使用详情 🌺1 概述 Beyond Compare 是一款强大的文件和文件夹比较工具,广泛应用于软件开发、文档管理和…

【基础算法总结】优先级队列

优先级队列 1.最后一块石头的重量2.数据流中的第 K 大元素4.前K个高频单词4.数据流的中位数 点赞👍👍收藏🌟🌟关注💖💖 你的支持是对我最大的鼓励,我们一起努力吧!😃😃 1…

Unity UGUI 之 Mask

本文仅作学习笔记与交流,不作任何商业用途 本文包括但不限于unity官方手册,唐老狮,麦扣教程知识,引用会标记,如有不足还请斧正 本文在发布时间选用unity 2022.3.8稳定版本,请注意分别 1.什么是遮罩 遮罩是一…

docker搭建python3的私有源--devpi

一、部署 # docker run -d --name devpi-lib -p 7104:7104 --env DEVPISERVER_HOST0.0.0.0 --env DEVPISERVER_PORT7104 --env DEVPISERVER_ROOT_PASSWORDpassword --env DEVPISERVER_USERlowinli --env DEVPISERVER_PASSWORDpassword --env DEVPISERVER_MIRROR_INDEXpypi --…