一文搞懂CLIP:架构分析+源码解读

引言

CLIP是OpenAI推出的采用对比学习的文本-图像预训练模型,是近年来在多模态研究领域的经典之作。
很多模型都用到了CLIP,虽然它结构简单但是在各个任务上表现都不错。
本文没有根据论文的内容从头到尾分析,而是从模型结构入手结合源码来进行分析,希望能够帮助各位小伙伴对CLIP有一个更深的了解!

CLIP架构

如原论文中的结构图所示:
在这里插入图片描述

● text encoder:用来提取文本特征,作者这里用的是nn.Embedding
● image encoder:用来提取图像特征,原文中image encoder可选的模型有很多,比如ViT-B/32、RN101等
● 相似度计算:图像特征和文本特征映射到同一维度后,通过矩阵乘法来计算图像特征和文本特征之间的相似度
原论文代码并没有给出训练代码,如果大家想看是怎么训练的,可参考快速完成多模态模型-CLIP的训练

针对架构中的核心部分,我们来看一下源码细节加深理解!


clip核心代码:

def forward(self, image, text):
        # 分别提取图像和文本特征 
        image_features = self.encode_image(image) # [batch_size,output_dim]
        text_features = self.encode_text(text)  # [batch_size,output_dim]

        # 对图像和文本特征进行归一化操作
        image_features = image_features / image_features.norm(dim=1, keepdim=True)
        text_features = text_features / text_features.norm(dim=1, keepdim=True)

        # logit_scale是一个可训练参数,用来控制图像和文本特征之间相似度的尺度
        logit_scale = self.logit_scale.exp()
    
        #  @ 是矩阵乘法操作符,text_features.t()表示将文本特征矩阵转置
        # 最终得到每张图片与每段文本的相似度
        logits_per_image = logit_scale * image_features @ text_features.t()

        # 表示每段文本与每张图像的相似度
        logits_per_text = logits_per_image.t()

        # shape = [batch_size, global_batch_size]
        return logits_per_image, logits_per_text

在上述代码中,得到维度为[batch_size,output_dim]的图像特征image_features和维度为[batch_size,output_dim]的文本特征text_f

### VQGAN-CLIP 模型架构详解 #### 一、VQ-GAN部分 VQ-GAN(Vector Quantized Generative Adversarial Network)是一种基于离散表示学习的生成对抗网络。其核心在于结合了变分自编码器(VAE)的思想与GANS的优点。 - **编码器**:接收输入图像并将其映射到潜在空间中的连续向量;这些向量随后被量化为离散码本中的索引[^4]。 - **解码器**:负责将来自量化后的潜在变量重建回原始尺寸大小的图像数据流形式。为了提高效率,通常采用多尺度结构设计,即先粗略恢复低分辨率版本再逐步精细化高细节特征。 - **鉴别器**:用于区分真实样本和由生成器产生的假样本之间的差异,从而促使整个系统不断优化直至达到难以分辨真假的程度为止。 ```python import torch.nn as nn class Encoder(nn.Module): def __init__(self, channels=3, features=[64, 128, 256], latent_dim=256): super(Encoder, self).__init__() layers = [] in_channels = channels for feature in features: layers.append( nn.Conv2d(in_channels=in_channels, out_channels=feature, kernel_size=(3, 3), stride=(2, 2), padding=1)) layers.append(nn.ReLU()) in_channels = feature layers.append(nn.Flatten()) layers.append(nn.Linear(features[-1]*((img_size//2**(len(features)-1))**2),latent_dim)) self.encoder = nn.Sequential(*layers) def forward(self,x): encoded_representation=self.encoder(x) return encoded_representation class Decoder(nn.Module): def __init__(self,channels=3,features=[256,128,64],latent_dim=256,img_size=64): super().__init__() self.initial_linear_layer = nn.Linear(latent_dim, (img_size // (2 ** len(features))) * \ (img_size // (2 ** len(features))) * features[0]) modules = [] current_features = features[0] for hidden_features in reversed(features[:-1]): modules.append( nn.ConvTranspose2d(current_features,hidden_features,kernel_size=4,stride=2,padding=1,) ) modules.append(nn.BatchNorm2d(hidden_features)) modules.append(nn.LeakyReLU()) current_features = hidden_features modules.append( nn.ConvTranspose2d(current_features,channels,kernel_size=4,stride=2,padding=1,)) modules.append(nn.Tanh()) self.decoder = nn.Sequential(*modules) def main(): encoder_model = Encoder() decoder_model = Decoder() if __name__ == "__main__": main() ``` #### 二、CLIP 部分 CLIP(Contrastive Language–Image Pretraining),旨在解决跨模态理解问题,特别是文本描述与视觉内容之间关系的学习。该模块主要包含两个子组件: - **Text Encoder**:利用预训练好的BERT或其他先进的NLP模型来获取句子级别的语义表达。 - **Image Encoder**:可以是ResNet系列或者其他CNN框架,用来提取图片的关键属性作为固定长度的特征向量。 两者共同作用于构建大规模对比损失函数之上,使得同一组配对的数据点间距离更近而不同类别则尽可能远离,进而实现了零样本迁移能力。 当这两个独立却互补的部分结合起来时,就构成了完整的VQGAN-CLIP体系——既能高效地合成逼真的图像又能精准匹配相应的文字说明。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

疯狂的小强呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值