Классификация изображений без обучения и поиск по сочетанию изображения и текста с использованием CLIP

Используйте модель CLIP от OpenAI для классификации изображений по категориям на естественном языке без каких-либо обучающих данных.

Hermes OpenClaw Средний Скопировали: 0
1 ресурс

Что понадобится

  • Установите CLIP вместе с библиотеками transformers, torch и pillow; модель работает под Linux, macOS и Windows и распространяется по лицензии MIT.

Как применить

CLIP предназначен для классификации без обучения, сопоставления изображений и текста, семантического поиска по изображениям, модерации контента, ответов на вопросы по изображениям и межмодального поиска между изображениями и текстом.

Для задач создания описаний альтернативой является BLIP-2, который показывает лучшие результаты.

Для визуально-языковых чатов альтернативой служит LLaVA.

Для сегментации изображений альтернативой является Segment Anything.

Выбор модели — это компромисс: RN50 (102 млн параметров) быстрая и качественная, ViT-B/32 (151 млн параметров) среднескоростная с ещё лучшим качеством, а ViT-L/14 (428 млн параметров) медленная, но обеспечивает наилучшее качество.

На процессоре на кодирование одного изображения уходит около 200 мс, а на кодирование текста — 50 мс; на GPU V100 эти значения составляют примерно 20 мс и 5 мс соответственно, причём вычисление схожести занимает менее 1 мс в любом случае.

CLIP не подходит для задач с высокой детализацией; он лучше всего справляется с широкими категориями.

Для работы модели требуется развернутый текст: нечеткие метки дают плохие результаты.

Поскольку модель обучалась на веб-данных, в результатах могут присутствовать искажения, связанные с особенностями набора данных.

Модель не может создавать рамки вокруг объектов и работает только со всем изображением целиком.

Её пространственное восприятие ограничено, поэтому позиционирование и подсчёт объектов выполняются плохо.

Модель распространяется по лицензии MIT.

Установите CLIP из его репозитория на GitHub, а затем установите torch, torchvision, ftfy, regex и tqdm.

pip install git+https://github.com/openai/CLIP.git
pip install torch torchvision ftfy regex tqdm

Чтобы классифицировать изображение без обучения, загрузите модель CLIP на доступное устройство, предварительно обработайте изображение, преобразуйте список возможных меток в токены и получите вероятность принадлежности изображения к каждой метке.

import torch
import clip
from PIL import Image

# Load model
device = "cuda" if torch.cuda.is_available() else "cpu"
model, preprocess = clip.load("ViT-B/32", device=device)

# Load image
image = preprocess(Image.open("photo.jpg")).unsqueeze(0).to(device)

# Define possible labels
text = clip.tokenize(["a dog", "a cat", "a bird", "a car"]).to(device)

# Compute similarity
with torch.no_grad():
    image_features = model.encode_image(image)
    text_features = model.encode_text(text)

    # Cosine similarity
    logits_per_image, logits_per_text = model(image, text)
    probs = logits_per_image.softmax(dim=-1).cpu().numpy()

# Print results
labels = ["a dog", "a cat", "a bird", "a car"]
for label, prob in zip(labels, probs[0]):
    print(f"{label}: {prob:.2%}")

Выбирайте модель по размеру и качеству: RN50, RN101, ViT-B/32 (рекомендуется), ViT-B/16 (лучшее качество, но медленнее) или ViT-L/14 (наилучшее качество, но самая медленная).

# Models (sorted by size)
models = [
    "RN50",           # ResNet-50
    "RN101",          # ResNet-101
    "ViT-B/32",       # Vision Transformer (recommended)
    "ViT-B/16",       # Better quality, slower
    "ViT-L/14",       # Best quality, slowest
]

model, preprocess = clip.load("ViT-B/32")

Чтобы определить, насколько хорошо изображение соответствует текстовому описанию, закодируйте оба объекта, нормализуйте полученные векторы признаков и вычислите их косинусную схожесть.

# Compute embeddings
image_features = model.encode_image(image)
text_features = model.encode_text(text)

# Normalize
image_features /= image_features.norm(dim=-1, keepdim=True)
text_features /= text_features.norm(dim=-1, keepdim=True)

# Cosine similarity
similarity = (image_features @ text_features.T).item()
print(f"Similarity: {similarity:.4f}")

Чтобы искать изображения по смыслу в коллекции, заранее вычислите нормализованные эмбеддинги для каждого изображения, так же закодируйте текстовый запрос и верните топ-k изображений, отсортированных по степени схожести.

# Index images
image_paths = ["img1.jpg", "img2.jpg", "img3.jpg"]
image_embeddings = []

for img_path in image_paths:
    image = preprocess(Image.open(img_path)).unsqueeze(0).to(device)
    with torch.no_grad():
        embedding = model.encode_image(image)
        embedding /= embedding.norm(dim=-1, keepdim=True)
    image_embeddings.append(embedding)

image_embeddings = torch.cat(image_embeddings)

# Search with text query
query = "a sunset over the ocean"
text_input = clip.tokenize([query]).to(device)
with torch.no_grad():
    text_embedding = model.encode_text(text_input)
    text_embedding /= text_embedding.norm(dim=-1, keepdim=True)

# Find most similar images
similarities = (text_embedding @ image_embeddings.T).squeeze(0)
top_k = similarities.topk(3)

for idx, score in zip(top_k.indices, top_k.values):
    print(f"{image_paths[idx]}: {score:.3f}")

Для модерации контента определите категории, такие как «приемлемо для работы», «неприемлемо для работы», «насильственный контент» и «откровенный контент», затем классифицируйте изображение и укажите наиболее вероятную категорию с её вероятностью.

# Define categories
categories = [
    "safe for work",
    "not safe for work",
    "violent content",
    "graphic content"
]

text = clip.tokenize(categories).to(device)

# Check image
with torch.no_grad():
    logits_per_image, _ = model(image, text)
    probs = logits_per_image.softmax(dim=-1)

# Get classification
max_idx = probs.argmax().item()
max_prob = probs[0, max_idx].item()

print(f"Category: {categories[max_idx]} ({max_prob:.2%})")

Для повышения эффективности обрабатывайте пакеты изображений и текстов одновременно и получайте полную матрицу схожести между ними.

# Process multiple images
images = [preprocess(Image.open(f"img{i}.jpg")) for i in range(10)]
images = torch.stack(images).to(device)

with torch.no_grad():
    image_features = model.encode_image(images)
    image_features /= image_features.norm(dim=-1, keepdim=True)

# Batch text
texts = ["a dog", "a cat", "a bird"]
text_tokens = clip.tokenize(texts).to(device)

with torch.no_grad():
    text_features = model.encode_text(text_tokens)
    text_features /= text_features.norm(dim=-1, keepdim=True)

# Similarity matrix (10 images × 3 texts)
similarities = image_features @ text_features.T
print(similarities.shape)  # (10, 3)

Для масштабирования поиска сохраняйте эмбеддинги CLIP в векторной базе данных, например Chroma, и выполняйте запросы с помощью текстового эмбеддинга для получения наиболее похожих изображений.

# Store CLIP embeddings in Chroma/FAISS
import chromadb

client = chromadb.Client()
collection = client.create_collection("image_embeddings")

# Add image embeddings
for img_path, embedding in zip(image_paths, image_embeddings):
    collection.add(
        embeddings=[embedding.cpu().numpy().tolist()],
        metadatas=[{"path": img_path}],
        ids=[img_path]
    )

# Query with text
query = "a sunset"
text_embedding = model.encode_text(clip.tokenize([query]))
results = collection.query(
    query_embeddings=[text_embedding.cpu().numpy().tolist()],
    n_results=5
)

ViT-B/32 представляет собой хороший баланс для большинства случаев.

Нормализуйте эмбеддинги — это необходимо для вычисления косинусной схожести.

Используйте пакетную обработку для более эффективного выполнения операций.

Кэшируйте эмбеддинги, так как их повторный расчёт требует значительных ресурсов.

Используйте развернутые метки для достижения лучших результатов при классификации без обучения.

Рекомендуется использовать GPU — он ускоряет обработку в 10–50 раз.

Предварительно обрабатывайте изображения с помощью предоставленной функции предобработки.

Лицензия — MIT.

Источник: nousresearch/hermes-agent и участники проекта. Лицензия: MIT.

Copyright (c) 2025 Nous Research

Перевод и редакционная адаптация: ClawCases.

>Ресурсы

>Похожие юзкейсы

Разработка

Арбитр разрешения конфликтов слияния агентов

Разрешает конфликт слияния Git между ветками двух агентов в качестве беспристрастной третьей стороны: нейтральный арбитр, который принимает обе версии изменений и указанные намерения, после чего формирует итоговый результат слияния, не перезаписывая ни одну из сторон.

Hermes Средний
Автоматизация Разработка

Автономное управление проектами с помощью подагентов

Координация проектов автономно: главный агент делегирует работу подагентам-менеджерам проектов, которые отслеживают задачи в общем файле STATE.yaml, обновляют его по мере выполнения, параллельно берутся за неблокируемые задачи и сохраняют всё состояние задач в файлах с контролем версий.

OpenClaw Средний
Творчество

Преобразуйте фотографию рукописного текста в шрифт TTF с помощью draw-your-font

Преобразуйте фотографию рукописных букв в устанавливаемый шрифт TTF: пользователь занимается отбором и разметкой букв, а также оценкой качества, в то время как CLI выполняет всю геометрическую обработку — трекирование, настройку метрик и сборку шрифта, без необходимости вручную редактировать SVG-пути.

Hermes OpenClaw Средний

>Ещё на этом уровне: Средний