基于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)时就已经确定图文匹配度的具体相关值。

##

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

1
2
3
4
5
6
7
8
9
10
11
12
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循环,使用字典构建键值对存放多张图片的绝对路径和图文匹配度,并进行图文匹配度排序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
'...............................................'
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
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做一个界面,这样更好用,我打包了一下软件代码。

代码下载

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

在这里插入图片描述
在这里插入图片描述

作者也是小白,如果你感觉读后有收获,可以点击下方打赏请作者喝杯咖啡。