Skip to main content

Simple and efficient training-free methods for correcting errors in contrastive image-text retrieval!

Project description

Nearest Neighbor Normalization (EMNLP 2024)

Nearest Neighbor Normalization (NNN) is a simple and efficient training-free method for correcting errors in contrastive embedding-based retrieval!

Installation

You can install NNN directly with pip using

pip install -e .

For Faiss support (which significantly speeds up retrieval and retrieval dataset normalization calculations), follow the installation instructions here. NNN is compatible with both the CPU and GPU versions of Faiss.

For development, you can clone this repo locally, then install the package using:

pip install -e .[dev]

Example usage

Here's a demonstration of how to rerank CLIP embeddings using NNN. This is basic usage; for deployment, consider using a Faiss-based retriever for better performance (e.g. FaissGPURetriever).

To run this example, you'll need to install transformers, pillow, and requests.

import numpy as np
from nnn import NNNRetriever, NNNRanker
from transformers import CLIPProcessor, CLIPModel
import torch
from PIL import Image
import requests
from io import BytesIO

device = "cuda" if torch.cuda.is_available() else "cpu"

# Load the CLIP model
model = CLIPModel.from_pretrained("openai/clip-vit-base-patch32").to(device)
processor = CLIPProcessor.from_pretrained("openai/clip-vit-base-patch32")

# Example images as PyTorch tensors (replace with your images)
image_urls = [
    "https://upload.wikimedia.org/wikipedia/commons/a/a8/Tour_Eiffel_Wikimedia_Commons.jpg",
    "https://upload.wikimedia.org/wikipedia/commons/0/00/St_Louis_night_expblend_cropped.jpg",
    "https://upload.wikimedia.org/wikipedia/commons/0/0c/GoldenGateBridge-001.jpg",
    "https://upload.wikimedia.org/wikipedia/commons/d/da/The_Parthenon_in_Athens.jpg",
    "https://upload.wikimedia.org/wikipedia/commons/4/48/Alabamahills.jpg"
]

images = [Image.open(BytesIO(requests.get(url, headers={'User-Agent': 'curl/7.64.1'}).content)) for url in image_urls]
image_inputs = processor(images=images, return_tensors="pt").to(device)

# Embed the images using CLIP
with torch.no_grad():
    image_embeddings = model.get_image_features(**image_inputs).cpu().numpy()  # move back to CPU for NNN

# Embed the caption text (used as an input for retrieval)
caption = "A description of the images you want to match."
text_inputs = processor(text=[caption], return_tensors="pt").to(device)
with torch.no_grad():
    text_embedding = model.get_text_features(**text_inputs).cpu().numpy()

# Create reference embeddings from in-distribution captions
reference_captions = [f"Reference caption {i}" for i in range(1, 11)]
reference_inputs = processor(text=reference_captions, return_tensors="pt", padding=True, truncation=True).to(device)
with torch.no_grad():
    reference_embeddings = model.get_text_features(**reference_inputs).cpu().numpy()

# Perform ranking using NNN
if device == "cuda":
    nnn_retriever = NNNRetriever(image_embeddings.shape[1], use_gpu=True, gpu_id=0)
    nnn_ranker = NNNRanker(nnn_retriever, image_embeddings, reference_embeddings, alternate_ks=8, batch_size=8, use_gpu=True, gpu_id=0)
else:
    nnn_retriever = NNNRetriever(image_embeddings.shape[1])
    nnn_ranker = NNNRanker(nnn_retriever, image_embeddings, reference_embeddings, alternate_ks=8, batch_size=8)

_, indices = nnn_ranker.search(text_embedding, 5)
print("Ranked image indices:", indices)
# Ranked image indices: [[0 4 2 3 1]]

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

nnn-retrieval-0.1.tar.gz (10.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

nnn_retrieval-0.1-py3-none-any.whl (13.6 kB view details)

Uploaded Python 3

File details

Details for the file nnn-retrieval-0.1.tar.gz.

File metadata

  • Download URL: nnn-retrieval-0.1.tar.gz
  • Upload date:
  • Size: 10.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.7.9

File hashes

Hashes for nnn-retrieval-0.1.tar.gz
Algorithm Hash digest
SHA256 25dc245aa74c7f6a1b382e534f34ff8414acae253ffd7f77bef4fab941e19b58
MD5 5ee004f279972a8975bf4fc20506f980
BLAKE2b-256 744fd09e49fde04cc96b470f78a712d8f36aee79309090c6775e3f89ce2f0b23

See more details on using hashes here.

File details

Details for the file nnn_retrieval-0.1-py3-none-any.whl.

File metadata

  • Download URL: nnn_retrieval-0.1-py3-none-any.whl
  • Upload date:
  • Size: 13.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/4.0.2 CPython/3.7.9

File hashes

Hashes for nnn_retrieval-0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 48f9c0c410f4d768cd9fe70f145b3b6d806c4b3a4b532e694e84985aa2d31ca8
MD5 578c70debe768b3ac79b882c10243f2b
BLAKE2b-256 be897467d201d14c73ac53c0a5bd10f3ab64285f6aa9501ac599d9299187c827

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page