import gradio as gr import torch import torch.nn.functional as F from torchvision import transforms from PIL import Image from model import SiameseNet # ── Load model ──────────────────────────────────────────────── device = torch.device("cuda" if torch.cuda.is_available() else "cpu") model = SiameseNet(embedding_dim=128).to(device) ckpt = torch.load("../checkpoints/best.pt", map_location=device) model.load_state_dict(ckpt["model_state"]) model.eval() # ── Transform ───────────────────────────────────────────────── transform = transforms.Compose([ transforms.Grayscale(), transforms.Resize((105, 105)), transforms.ToTensor(), transforms.Normalize([0.9220], [0.2256]), ]) def preprocess(img: Image.Image) -> torch.Tensor: return transform(img).unsqueeze(0).to(device) # [1, 1, 105, 105] # ── Inference ───────────────────────────────────────────────── def compare_images(img1: Image.Image, img2: Image.Image): with torch.no_grad(): emb1 = model.get_embedding(preprocess(img1)) emb2 = model.get_embedding(preprocess(img2)) similarity = F.cosine_similarity(emb1, emb2).item() match = similarity > 0.5 label = "Same class" if match else "Different class" conf = f"{similarity * 100:.1f}%" colour = "green" if match else "red" result = f"""