ProximAditya commited on
Commit
5df5c7c
·
verified ·
1 Parent(s): 0dac960

Upload 3 files

Browse files
Files changed (3) hide show
  1. app.py +99 -0
  2. best_multitask_usg (1).pth +3 -0
  3. requirements.txt +8 -3
app.py ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import torch
3
+ import torch.nn as nn
4
+ import cv2
5
+ import numpy as np
6
+ from PIL import Image
7
+ import albumentations as A
8
+ from albumentations.pytorch import ToTensorV2
9
+ import timm
10
+
11
+ # --- 1. PAGE SETUP ---
12
+ st.set_page_config(page_title="Medical AI Sonographer", page_icon="🩺", layout="centered")
13
+ st.title("🩺 Dual-Head AI: Abdominal Ultrasound Diagnoser")
14
+ st.write("Upload an abdominal ultrasound image. The AI will identify the organ and detect if it is normal or abnormal.")
15
+
16
+ # --- 2. DEFINE THE AI ARCHITECTURE ---
17
+ # (This must match exactly what you trained in Kaggle)
18
+ class DualHeadConvNeXt(nn.Module):
19
+ def __init__(self, num_organs, num_statuses):
20
+ super().__init__()
21
+ # pretrained=False because we are loading our own weights!
22
+ self.backbone = timm.create_model('convnext_tiny', pretrained=False, num_classes=0)
23
+ in_features = self.backbone.num_features
24
+ self.organ_head = nn.Linear(in_features, num_organs)
25
+ self.status_head = nn.Linear(in_features, num_statuses)
26
+
27
+ def forward(self, x):
28
+ features = self.backbone(x)
29
+ return self.organ_head(features), self.status_head(features)
30
+
31
+ # --- 3. LABELS & CACHING ---
32
+ # Organ mapping based on your Kaggle Confusion Matrix
33
+ ORGAN_LABELS = {
34
+ 0: 'Spleen', 1: 'Pancreas', 2: 'Ovary', 3: 'Gallbladder',
35
+ 4: 'Portal Vein', 5: 'Liver', 6: 'Abdominal Aorta (AA)',
36
+ 7: 'Kidney', 8: 'UB / Prostate / Uterus', 9: 'Hepatic Vein', 10: 'Ascites'
37
+ }
38
+ STATUS_LABELS = {0: '✅ Normal (Healthy)', 1: '⚠️ Abnormal (Disease/Anomaly Detected)'}
39
+
40
+ @st.cache_resource
41
+ def load_model():
42
+ model = DualHeadConvNeXt(num_organs=11, num_statuses=2)
43
+ # map_location='cpu' is CRITICAL because web servers don't have Kaggle T4 GPUs
44
+ model.load_state_dict(torch.load('best_multitask_usg.pth', map_location=torch.device('cpu')))
45
+ model.eval()
46
+ return model
47
+
48
+ model = load_model()
49
+
50
+ # --- 4. IMAGE PREPROCESSING ---
51
+ # Must match validation transforms from training
52
+ transform = A.Compose([
53
+ A.Resize(384, 384),
54
+ A.Normalize(mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225)),
55
+ ToTensorV2()
56
+ ])
57
+
58
+ # --- 5. THE WEBSITE UI ---
59
+ uploaded_file = st.file_uploader("Choose an Ultrasound Image (JPG/PNG)...", type=["jpg", "jpeg", "png"])
60
+
61
+ if uploaded_file is not None:
62
+ # Show the image
63
+ image = Image.open(uploaded_file).convert('RGB')
64
+ st.image(image, caption='Uploaded Ultrasound', use_container_width=True)
65
+
66
+ st.write("🧠 **AI is analyzing the image...**")
67
+
68
+ # Preprocess
69
+ img_array = np.array(image)
70
+ tensor_img = transform(image=img_array)['image'].unsqueeze(0) # Add batch dimension
71
+
72
+ # Predict
73
+ with torch.no_grad():
74
+ organ_pred, status_pred = model(tensor_img)
75
+
76
+ organ_idx = organ_pred.argmax(dim=1).item()
77
+ status_idx = status_pred.argmax(dim=1).item()
78
+
79
+ # Calculate confidences (probabilities)
80
+ organ_conf = torch.nn.functional.softmax(organ_pred, dim=1)[0][organ_idx].item() * 100
81
+ status_conf = torch.nn.functional.softmax(status_pred, dim=1)[0][status_idx].item() * 100
82
+
83
+ # --- 6. DISPLAY RESULTS BEAUTIFULLY ---
84
+ st.markdown("### 📊 AI Diagnosis Report")
85
+
86
+ col1, col2 = st.columns(2)
87
+ with col1:
88
+ st.info(f"**Organ Detected:** \n### {ORGAN_LABELS[organ_idx]}")
89
+ st.write(f"Confidence: {organ_conf:.2f}%")
90
+
91
+ with col2:
92
+ if status_idx == 0:
93
+ st.success(f"**Health Status:** \n### {STATUS_LABELS[status_idx]}")
94
+ else:
95
+ st.error(f"**Health Status:** \n### {STATUS_LABELS[status_idx]}")
96
+ st.write(f"Confidence: {status_conf:.2f}%")
97
+
98
+ st.markdown("---")
99
+ st.caption("Disclaimer: This AI is for educational and research purposes only. It is not a substitute for professional medical diagnosis.")
best_multitask_usg (1).pth ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:247e02f1894742e5470d90b8e5b3734a37c13fa0cc213786800c4e0428eba17e
3
+ size 111397305
requirements.txt CHANGED
@@ -1,3 +1,8 @@
1
- altair
2
- pandas
3
- streamlit
 
 
 
 
 
 
1
+ streamlit
2
+ torch
3
+ torchvision
4
+ timm
5
+ albumentations
6
+ opencv-python-headless
7
+ numpy
8
+ Pillow