RoboflowAPI提供了一套标准的路由,使得用户可以在不修改任何代码的情况下,改变部署目标。Roboflow推理服务器将包含基础模型,例如OpenAI的CLIP模型,这些模型可以在不同的部署目标和环境中使用。利用CLIP,可以在边缘或离线环境中对图像进行零样本分类,这意味着可以将图像分类到指定的一系列类别中,而无需进行任何训练。一个用例是,在将图像发送到外部服务器之前,过滤掉所有包含人的图像以保护他们的隐私。
在本指南中,将展示如何在Roboflow推理服务器上使用CLIP图像比较端点。使用这种逻辑和工作流程,可以使用CLIP进行媒体搜索、内容审核、相似性搜索、图像描述和图像排名。对于本指南,将专注于图像分类作为用例,其中将使用CLIP从提供的有限类别列表中分配一个类别。
💡 可以在RoboflowExamples GitHub仓库中找到本教程使用的完整源代码。请注意,像任何部署在生产中的模型一样,零样本分类模型可能无法准确识别每个对象。应该尝试用例,以了解在领域中的可行性。
安装推理服务器
💡 在付费的Roboflow层级上,可以在本地运行Roboflow推理服务器。如果不在付费计划中,请跳过这一步,使用下一节讨论的"infer.roboflow.com"服务器。
要安装Roboflow推理服务器,需要在机器上运行Docker。如果还没有Docker,请按照设备的Docker安装说明进行操作。当准备好Docker后,在终端中运行以下命令:
docker run -it –rm –network=host roboflow/roboflow-inference-server-cpu
此命令将从Docker Hub安装“roboflow/roboflow-inference-server-cpu”镜像。安装过程完成后,推理服务器将在机器上的9000端口运行。现在可以开始使用CLIP了。
使用CLIP嵌入图像
假设有一个名为“fruits”的图像文件夹。希望将所有香蕉照片发送进行分类,以确定有多少是成熟和未成熟的。为此,可以使用零样本分类来识别水果,然后如果水果是香蕉,就运行模型的成熟度检测推理。
首先,让导入脚本所需的库,并创建一个希望在分类中考虑的所有类别的列表:
import requests
import base64
from PIL import Image
from io import BytesIO
import os
INFERENCE_ENDPOINT = "https://infer.roboflow.com"
API_KEY = "API_KEY"
IMAGE_DIR = "fruits"
prompts = [
"orange",
"apple",
"banana"
]
将Roboflow API密钥添加到上述示例中,以及想要运行推理的图像的路径。(如果想在没有运行Roboflow推理服务器的情况下尝试这个,查询https://infer.roboflow.com而不是http://localhost:9001)。用在分类期间要考虑的项目替换“prompts”中的项目。
接下来,让定义一个函数,该函数接受给定的图像,并将其发送到推理服务器上的CLIP比较端点以对图像进行分类:
def classify_image(image: str) -> dict:
image_data = Image.open(image)
buffer = BytesIO()
image_data.save(buffer, format="JPEG")
image_data = base64.b64encode(buffer.getvalue()).decode("utf-8")
payload = {
"api_key": API_KEY,
"subject": {
"type": "base64",
"value": image_data
},
"prompt": prompts,
}
data = requests.post(INFERENCE_ENDPOINT + "/clip/compare?api_key=" + API_KEY, json=payload)
return data.json()
在这个函数中,打开图像,创建一个图像的base64编码版本,然后创建一个包含想要发送到API的数据的有效负载。然后,将数据发送到推理服务器并返回JSON有效负载。将这个值打印到控制台。
每个请求返回一个JSON有效负载,其中包含一个分数,显示图像包含类别中的对象的可能性。这个分数表示为0到1之间的值;分数越高,图像包含类别中的对象的可能性就越大。
将要测试的图像是这张苹果的照片:
让测试一下代码。目前,fruits文件夹只包含文章中前面提到的图像。当代码运行时,将嵌入图像并找到类别中最相似的——苹果、梨和橙子——代表图像。
{"similarity":[0.29781154187589154,0.2625142299710535,0.25538911112766416],"time":2.944441630000256}
代码打印出CLIP返回的分类。这些值是一个数字列表,其索引等于每个标签在列表中的位置。要找到与对象最相似的标签,可以使用这段代码:
def get_highest_prediction(predictions: list) -> str:
highest_prediction = 0
highest_prediction_index = 0
for i, prediction in enumerate(predictions):
if prediction > highest_prediction:
highest_prediction = prediction
highest_prediction_index = i
return prompts[highest_prediction_index]
现在,让遍历“fruits”目录中的每个文件,进行分类,并将结果打印到控制台:
for file in os.listdir(IMAGE_DIR):
image = f"{IMAGE_DIR}/{file}"
predictions = classify_image(image)
print(get_highest_prediction(predictions["similarity"]), image)
当运行代码时,得到这个响应:
apple 1.jpeg
orange 2.jpeg
1.jpeg是前面显示的苹果照片。2.jpeg是橙子的照片。模型按预期工作!
额外的端点
Roboflow推理服务器还有端点来计算文本和图像嵌入:
/clip/embed_text: 计算CLIP文本嵌入。
/clip/embed_image: 计算图像的CLIP嵌入。
可以在推理服务器文档中了解更多关于这些端点的信息。