在深度学习和自然语言处理领域,自动化标注数据集已成为可能。本文将指导如何使用CLIP(Contrastive Language-Image Pretraining)和Roboflow在Jupyter Notebook环境中自动标注数据集。
CLIP是由OpenAI开发的一种先进的深度学习模型,旨在从自然语言描述中提取视觉概念。该模型通过将图像和文本关联在共享的嵌入空间内,实现跨模态检索和理解。通过在大量图像及其对应的文本描述上进行广泛训练,CLIP学会了以一种反映语义相似性的方式对图像和文本进行编码。
在本演示中,将使用Roboflow艺术分类数据集。这个分类数据集包含了从抽象表现主义到波普艺术的艺术运动图像。数据集经过策划和标注,包括了多样化的艺术风格,使能够探索CLIP和自动化标注的能力。
在深入自动标注之前,让设置所需的环境。将使用Jupyter笔记本进行此演示。首先,安装必要的依赖项:
!pip install ftfy regex tqdm
!pip install git+https://github.com/openai/CLIP.git
!pip install roboflow
接下来,导入所需的库:
import glob
import os
import clip
import math
import torch
import matplotlib.pyplot as plt
from IPython.core.display import HTML
import numpy as np
from PIL import Image
from roboflow import Roboflow
import csv
接下来,需要为自动标注准备数据集。如果没有Roboflow账户,可以免费注册并创建一个新项目。一旦在Roboflow上设置了项目,可以使用Roboflow Python包直接将数据集下载到Jupyter笔记本中。以下是一个如何下载数据集的示例:
rf = Roboflow(api_key="YOUR_API_KEY")
project = rf.workspace("art-dataset").project("wiki-art")
dataset = project.version(2).download("clip")
为了自动标注数据集,需要使用CLIP模型从图像中提取特征。执行以下代码以提取图像特征:
for i in range(batches):
images = img[i*batch : (i+1)*batch]
batch_preprocessed = torch.stack([preprocess(i) for i in images if i is not None]).to(device)
with torch.no_grad():
image_embeddings = model.encode_image(batch_preprocessed)
image_embeddings /= image_embeddings.norm(dim=-1, keepdim=True)
features = torch.cat((features, image_embeddings))
print(f"Images Extracted: {features.shape}")
这段代码通过CLIP模型编码图像,并将编码后的特征存储起来,以便后续用于找到相似的图像。
现在,让使用提取的图像特征,根据文本输入找到相似的图像。执行以下代码定义一个函数,该函数根据文本查询找到相似的图像:
def findImg(input_text, threshold=25.9, num=5):
with torch.no_grad():
text_embeddings = model.encode_text(clip.tokenize(input_text).to(device))
text_embeddings /= text_embeddings.norm(dim=-1, keepdim=True)
similarities = (100.0 * features @ text_embeddings.T)
values, top_poster = similarities.topk(num, dim=0)
for frame_id in top_poster:
score = similarities[frame_id.item()]
if score > threshold:
print("Cosine Similarity Score for Image", frame_id.item(), ":", score)
display(img[frame_id])
findImg("Cubism")
这个函数接受一个输入文本,并基于文本和图像嵌入之间的余弦相似度找到最相似的图像。可以调整阈值参数来控制显示图像的相似度阈值。将文本查询替换为自己的描述以找到相关图像。
要可视化文本和图像特征之间的相似度,可以参考提供的完整代码中的交互式笔记本。计算文本和图像特征之间的余弦相似度,并将其可视化为热图。每一行代表一个文本描述,每一列代表一个图像类别。热图中的值表示文本和图像特征之间的相似度分数。
最后,让使用CLIP模型对数据集进行自动标注。执行以下代码:
class_tokens = clip.tokenize([desc for desc in labels]).cuda()
with torch.no_grad():
text_features = model.encode_text(class_tokens).float()
text_features /= text_features.norm(dim=-1, keepdim=True)
img = []
features = torch.empty([0, 512], dtype=torch.float16).to(device)
header = ["Names"] + labels
rows = []
for i in range(0, len(image_paths), batch):
batch_paths = image_paths[i : i + batch]
for path in batch_paths:
img_name = os.path.basename(path)
with Image.open(path) as im:
im_array = np.array(im)
new_im = Image.fromarray(im_array)
img.append(new_im)
images = img[-len(batch_paths):]
batch_preprocessed = torch.stack([preprocess(i) for i in images if i is not None]).to(device)
with torch.no_grad():
image_embeddings = model.encode_image(batch_preprocessed)
image_embeddings /= image_embeddings.norm(dim=-1, keepdim=True)
features = torch.cat((features, image_embeddings))
similarity_scores = np.dot(image_embeddings.cpu().numpy(), text_features.cpu().numpy().T)
most_similar_labels = np.argmax(similarity_scores, axis=1)
for img_name, label in zip(batch_paths, most_similar_labels):
row = [os.path.basename(img_name)]
for j in range(len(labels)):
if label == j:
row.append(1) # 最相似的标签,赋值为1
else:
row.append(0) # 其他标签,赋值为0
rows.append(row)
filename = "autolabel.csv" # 替换为希望的文件名
with open(filename, "w", newline="") as file:
writer = csv.writer(file)
writer.writerow(header)
writer.writerows(rows)