import gradio as gr import torch from PIL import Image import numpy as np import json from huggingface_hub import hf_hub_download import timm from torchvision import transforms DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu") # --- Download and Load Classification Model (EfficientNet-B3) --- CLASS_REPO_ID = "sheikh987/efficientnet-b3-skin" CLASS_MODEL_FILENAME = "efficientnet_b3_skin_model.pth" NUM_CLASSES = 7 try: class_model_path = hf_hub_download( repo_id=CLASS_REPO_ID, filename=CLASS_MODEL_FILENAME, cache_dir="/tmp" ) checkpoint = torch.load(class_model_path, map_location=DEVICE) # Auto-detect state_dict vs full model if isinstance(checkpoint, dict): classification_model = timm.create_model( 'efficientnet_b3', pretrained=False, num_classes=NUM_CLASSES ).to(DEVICE) classification_model.load_state_dict(checkpoint, strict=False) else: classification_model = checkpoint.to(DEVICE) classification_model.eval() print("✅ Classification model loaded successfully.") except Exception as e: raise gr.Error(f"Failed to load the classification model: {e}") # --- Load Knowledge Base --- try: with open('knowledge_base.json', 'r') as f: knowledge_base = json.load(f) except FileNotFoundError: raise gr.Error("knowledge_base.json not found. Upload it to the Space.") idx_to_class_abbr = {0: 'MEL', 1: 'NV', 2: 'BCC', 3: 'AKIEC', 4: 'BKL', 5: 'DF', 6: 'VASC'} # --- Image Transform --- transform_classify = transforms.Compose([ transforms.Resize((300, 300)), transforms.ToTensor(), transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]), ]) # --- Pipeline Function --- def classify_image(input_image): if input_image is None: return None, "Please upload an image." class_input_tensor = transform_classify(input_image).unsqueeze(0).to(DEVICE) with torch.no_grad(): logits = classification_model(class_input_tensor) probs = torch.nn.functional.softmax(logits, dim=1) confidence, predicted_idx = torch.max(probs, 1) confidence_percent = confidence.item() * 100 predicted_abbr = idx_to_class_abbr[predicted_idx.item()] info = knowledge_base.get(predicted_abbr, {}) # Build output info_text = ( f"**Predicted Condition:** {info.get('full_name', 'N/A')} ({predicted_abbr})\n" f"**Confidence:** {confidence_percent:.2f}%\n\n" f"**Description:**\n{info.get('description', 'No description available.')}\n\n" f"**Common Causes:**\n" + "\n".join([f"• {c}" for c in info.get('causes', ['N/A'])]) + "\n\n" f"**Common Treatments:**\n" + "\n".join([f"• {t}" for t in info.get('common_treatments', ['N/A'])]) + "\n\n" f"**--- IMPORTANT DISCLAIMER ---**\n{info.get('disclaimer', '')}" ) return input_image, info_text # --- Gradio Interface --- iface = gr.Interface( fn=classify_image, inputs=gr.Image(type="pil", label="Upload Skin Image"), outputs=[gr.Image(type="pil", label="Input Image"), gr.Markdown(label="Analysis Result")], title="AI Skin Lesion Classifier", description="Upload a skin lesion image and the AI EfficientNet-B3 model will classify it.\n\n" "**DISCLAIMER:** This is NOT a diagnosis. Always consult a qualified dermatologist." ) if __name__ == "__main__": iface.launch()