「多模态」基于CLIP实现以文精准搜图

本文探讨如何利用CLIP模型扩展其功能,支持同时对多个图片和文本进行精确匹配,通过封装函数和实例展示如何计算图片与关键词的匹配度,并通过实际代码操作演示了应用过程。

基于CLIP实现以文精准搜图

前言

在使用CLIP做图文匹配时,发现只能用多个文本语句和一张图片匹配,而我想实现多个图片与文本进行匹配。

思考

在这里插入图片描述
打个断点 用DEBUG看了下 在经过预处理和模型后 logits_per_image以及logits_per_text的

tensor([[25.5625, 20.0938, 19.7500]], device=‘cuda:0’, dtype=torch.float16)

推测这三个float数值分别代表了这三个文本与一张图片的匹配程度,而最后的
probs = logits_per_image.softmax(dim=-1).cpu().numpy()
也只是使用 softmax层进行一些权重、对数等变换处理下变成更规范的格式
再使用仅仅第一个语句与该图片匹配,tensor中数值仍为25.5625
所以验证猜想成立 在经过model(image,text)时就已经确定图文匹配结果。
print出来如下:

logits_per_text:
tensor([[21.0442],
[19.5299],
[26.7914],
[12.4424],
[16.9726]])
logits_per_image:tensor([[21.0442, 19.5299, 26.7914, 12.4424, 16.9726]])

##
将获得图文匹配度封装成函数,并返回匹配度的数值:

def match(str1,sent):
    device = "cuda" if torch.cuda.is_available() else "cpu"
    model, preprocess = clip.load("ViT-B/32", device=device)
    image = preprocess(Image.open(str1)).unsqueeze(0).to(device)
    text = clip.tokenize([sent]).to(device)
    with torch.no_grad():
        image_features = model.encode_image(image)
        text_features = model.encode_text(text)
        logits_per_image, logits_per_text = model(image, text)
        similarity = str(logits_per_image)[9:13]
        res = int(similarity)
        return res

利用for循环,使用字典存放多张图片的绝对路径和图文匹配度
看代码就懂了

	'...............................................'
	sent = input("请输入图片关键词:")
    getPic(sent)
    #获取图片
    path0 ='C:\\Users\\DELL\\Desktop\\CLIP-main\\'+ sent
    similar_key = []
    similar_value = []
    for filename in os.listdir(path0):
        if filename.endswith('jpg') or filename.endswith('png'):
            #  存储图片的文件夹绝对路径
            str1 = path0 +'\\'+filename
            print(str1)
            similar_key.append(str1)
            sim = match(str1,sent)
            #将得到的多张图片匹配你输入的图片关键词
            similar_value.append(sim)
    # 存放图片绝对路径和图文相似度的字典
    similar_dict = dict(zip(similar_key, similar_value))
    print(similar_dict)
    similar_value.sort(reverse=True)
    print(similar_value)
    result = ' '
    # 找到图文相似度最高的那个图片的绝对路径
    for key, value in similar_dict.items():
        if value == similar_value[0]:
            result = key
            break
    img = Image.open(result)
    img.show()

执行玩显示出最匹配你需求的那张图片。

爬虫抓取图片并存储路径的步骤不做介绍。

从头到尾可一键执行的代码打包一起放在资源里。
在这里插入图片描述
用pyqt 做了一个前端
在这里插入图片描述

在这里插入图片描述

代码

完整代码见 github:
yangzi0210
觉得不错就给个star 帅哥美女

<think>嗯,用户想了解如何使用CLIP模型实现功能,需要教程、示例和代码。首先,我需要回忆CLIP的基本原理。CLIP是OpenAI开发的多模态模型,能够将文本图像映射到同一个向量空间,这样可以通过计算相似度来实现跨模态检索根据用户提供的引用,特别是引用[1]和[2],CLIP在视频定位和图像文本匹配方面有应用,所以应该可以应用到以。 接下来,用户需要具体的步骤和代码示例。我应该先整理实现流程,分步骤说明。第一步应该是环境准备,安装必要的库,比如PyTorch和transformers,可能还需要其他依赖如PIL处理图像。然后,加载预训练的CLIP模型和处理器,这里需要明确模型名称,比如openai/clip-vit-base-patch32。 然后是数据准备部分。用户可能需要用自己的片库,但示例中可以用一些示例片。需要说明如何加载片并进行预处理,使用CLIP的处理器来统一尺寸和归一化。 接下来是文本编码和图像编码。这部分需要详细说明如何将输入的文本图像转换为特征向量。需要强调将模型设置为评估模式,避免计算梯度,提高效率。 然后是相似度计算,通常使用余弦相似度或点积。这里可能需要比较两种方法的差异,但通常余弦相似度更常用,因为它不受向量长度影响。计算所有图像文本的相似度后,进行排序,输相关的结果。 在代码示例部分,需要确保语法正确,特别是使用transformers库的正确方式。可能需要用CLIPProcessor和CLIPModel,同时处理多张片的示例。另外,用户可能需要一个更完整的示例,包括加载本地片、处理批量数据等。 然后要考虑性能优化,比如批量处理图像特征,使用GPU加速。这部分可以提到,但示例代码可能需要更复杂的结构,用户可能需要进一步指导。 用户可能遇到的问题包括模型加载失败、片预处理错误、相似度计算方式等,需要指常见错误和解决方法,比如检查模型名称、确保片路径正确、使用适当的相似度方法。 最后,生成相关问题,需要围绕CLIP的其他应用、微调方法、性能优化、多语言支持等,这些都是在用户问题基础上自然延伸的问题。 还要注意引用用户提供的引用内容,比如引用[1]提到CLIP在视频定位中的应用,引用[2]提到从零实现CLIP,但当前问题是以,可能需要调整引用的位置,比如在提到CLIP多模态能力时引用[1]和[2]。 检查是否所有数学公式都用了正确的格式,比如在提到向量空间时,可能涉及向量运算,需要用$...$包裹。例如,相似度计算可以写成$\cos(\theta)$,但可能不需要,因为用户的问题更偏向应用而非理论推导。 确保回答结构清晰,分步骤说明,代码示例正确,并附有解释。最后的问题要相关,帮助用户深入理解CLIP的其他方面。</think>以下是使用CLIP模型实现功能的逐步教程,包含代码示例和实现要点: --- ### 一、实现原理 CLIP模型通过将文本图像编码到同一语义空间,计算两者特征向量的相似度实现跨模态检索。核心公式可表示为: $$ \text{相似度} = \cos(\theta) = \frac{\mathbf{T} \cdot \mathbf{I}}{\|\mathbf{T}\| \|\mathbf{I}\|} $$ 其中$\mathbf{T}$为文本特征向量,$\mathbf{I}$为图像特征向量[^1][^2] --- ### 二、实现步骤 #### 1. 环境准备 ```python # 安装依赖库 !pip install torch transformers Pillay ``` #### 2. 加载预训练模型 ```python from transformers import CLIPProcessor, CLIPModel import torch model = CLIPModel.from_pretrained("openai/clip-vit-base-patch32") processor = CLIPProcessor.from_pretrained("openai/clip-vit-base-patch32") device = "cuda" if torch.cuda.is_available() else "cpu" model.to(device) ``` #### 3. 准备图像库 ```python from PIL import Image # 示例图像库(实际应用需替换为真实路径) image_paths = ["image1.jpg", "image2.jpg", "image3.jpg"] images = [Image.open(path) for path in image_paths] ``` #### 4. 特征编码 ```python # 文本编码 text_inputs = ["一只橘色猫", "城市夜景", "生日蛋糕"] text_features = model.get_text_features(**processor(text=text_inputs, return_tensors="pt", padding=True).to(device)) # 图像编码 image_features = [] for image in images: inputs = processor(images=image, return_tensors="pt").to(device) features = model.get_image_features(**inputs) image_features.append(features.detach().cpu()) image_features = torch.stack(image_features).squeeze(1) ``` #### 5. 相似度计算与检索 ```python # 归一化特征向量 text_features = text_features / text_features.norm(dim=-1, keepdim=True) image_features = image_features / image_features.norm(dim=-1, keepdim=True) # 计算相似度矩阵 similarity = (text_features @ image_features.T) * 100 # 获取Top-K结果 top_k = 3 for text_idx, text in enumerate(text_inputs): values, indices = similarity[text_idx].topk(top_k) print(f"检索文本:'{text}'") for rank, (score, img_idx) in enumerate(zip(values, indices)): print(f"Top-{rank+1}: 图像{image_paths[img_idx]} (相似度{score:.2f}%)") ``` --- ### 三、性能优化技巧 1. **批量处理**:使用`processor(images=image_list)`替代循环处理 2. **特征缓存**:预计算图像库特征并存储为.npy件 3. **GPU加速**:使用`torch.nn.DataParallel`进行多卡并行 4. **量化压缩**:应用`torch.quantization`减少模型内存占用 --- ### 四、常见问题解决 - **图像尺寸问题**:CLIP要求224x224分辨率,需使用`processor`自动调整 - **多语言支持**:需加载多语言CLIP变体(如`M-CLIP`) - **长文本处理**:截断至模型最大长度(CLIP默认77个token) ---
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

zoe_ya

如果你成功申请,可以打赏杯奶茶

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

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

打赏作者

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

抵扣说明:

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

余额充值