引言
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