Danielhalali's picture
Update app.py
cb0343d verified
Raw
History Blame Contribute Delete
3.36 kB
import gradio as gr
import numpy as np
import pandas as pd
import torch
from transformers import CLIPProcessor, CLIPModel
from sklearn.metrics.pairwise import cosine_similarity
from datasets import load_dataset
# Load model
device = "cuda" if torch.cuda.is_available() else "cpu"
model_name = "openai/clip-vit-base-patch32"
model = CLIPModel.from_pretrained(model_name).to(device)
processor = CLIPProcessor.from_pretrained(model_name)
# Load embeddings
df = pd.read_parquet("nature_embeddings.parquet")
EMBEDDINGS_MATRIX = np.array(df['embedding'].tolist())
CAPTIONS = df['caption'].tolist()
ORIGINAL_INDICES = df['original_index'].tolist()
# Load dataset
dataset = load_dataset("mertcobanov/nature-dataset")
train_data = dataset['train']
def classify_scene(caption):
"""Classify nature scene based on caption keywords"""
caption = caption.lower()
if any(w in caption for w in ['beach', 'ocean', 'sea', 'coast', 'wave']):
return '🌊 Coastal'
elif any(w in caption for w in ['waterfall', 'stream', 'river', 'lake']):
return 'πŸ’§ Water'
elif any(w in caption for w in ['mountain', 'peak', 'cliff', 'rock']):
return 'πŸ”οΈ Mountain'
elif any(w in caption for w in ['desert', 'dune', 'sand', 'arid']):
return '🏜️ Desert'
elif any(w in caption for w in ['forest', 'tree', 'jungle', 'wood']):
return '🌲 Forest'
else:
return '🌿 Nature'
def get_image_embedding(image):
inputs = processor(images=image, return_tensors="pt", padding=True).to(device)
with torch.no_grad():
outputs = model.vision_model(**inputs)
features = outputs.pooler_output
features = torch.nn.functional.normalize(features, p=2, dim=-1)
return features.cpu().numpy()
def recommend(image):
query_embedding = get_image_embedding(image)
similarities = cosine_similarity(query_embedding, EMBEDDINGS_MATRIX)[0]
top_indices = np.argsort(similarities)[::-1]
top_indices = [idx for idx in top_indices if similarities[idx] < 0.9999][:3]
results = []
for idx in top_indices:
original_idx = ORIGINAL_INDICES[idx]
img = train_data[int(original_idx)]['image']
cap = CAPTIONS[idx]
sim = float(similarities[idx])
scene = classify_scene(cap)
results.append((img, f"{scene} | {cap} (similarity: {sim:.4f})"))
return results[0][0], results[0][1], results[1][0], results[1][1], results[2][0], results[2][1]
# Gradio interface
with gr.Blocks(title="Nature Scene Recommender") as demo:
gr.Markdown("# 🌿 Nature Scene Recommender")
gr.Markdown("Upload a nature image and get the 3 most similar scenes!")
with gr.Row():
input_image = gr.Image(type="pil", label="Upload Nature Image")
btn = gr.Button("Find Similar Scenes πŸ”", variant="primary")
gr.Markdown("### Top 3 Similar Scenes")
with gr.Row():
img1 = gr.Image(label="Match #1")
img2 = gr.Image(label="Match #2")
img3 = gr.Image(label="Match #3")
with gr.Row():
cap1 = gr.Textbox(label="Scene #1")
cap2 = gr.Textbox(label="Scene #2")
cap3 = gr.Textbox(label="Scene #3")
btn.click(fn=recommend, inputs=input_image,
outputs=[img1, cap1, img2, cap2, img3, cap3])
demo.launch(server_name="0.0.0.0", server_port=7860)