Siddharth Mishra commited on
Commit
b1b29cb
Β·
1 Parent(s): 0e171ce
Files changed (2) hide show
  1. app.py +245 -18
  2. requirements.txt +2 -1
app.py CHANGED
@@ -1,32 +1,61 @@
1
- # app.py for Gradio Space with Gemini 2.5 Flash Integration + Image Samples
2
  import gradio as gr
3
  import torch
 
4
  from PIL import Image
5
  from torchvision import transforms
6
  from huggingface_hub import hf_hub_download
7
  from model import StoolNetTriple
8
  import os
 
 
 
9
  from google import genai
10
 
11
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
  # ========================================
13
  # MODEL SETUP - Download from HF Hub
14
  # ========================================
15
- HF_TOKEN=os.getenv("HF_TOKEN")
16
 
17
  print("Downloading model from Hugging Face Hub...")
18
  model_path = hf_hub_download(
19
  repo_id="Sid3503/stoolnet-bristol-scale-triple-attn",
20
  filename="pytorch_model.bin",
21
- token=HF_TOKEN # Add this parameter for authentication
22
  )
23
 
24
  print("Loading model...")
 
25
  model = StoolNetTriple()
26
- state = torch.load(model_path, map_location="cpu")
27
  model.load_state_dict(state)
28
  model.eval()
29
- print("Model loaded successfully!")
 
30
 
31
  # Define transform
32
  transform = transforms.Compose([
@@ -36,12 +65,118 @@ transform = transforms.Compose([
36
  ])
37
 
38
 
39
- # Define transform
40
- transform = transforms.Compose([
41
- transforms.Resize((224, 224)),
42
- transforms.ToTensor(),
43
- transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
44
- ])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
45
 
46
 
47
  # ========================================
@@ -117,6 +252,7 @@ if not GEMINI_API_KEY:
117
  else:
118
  try:
119
  gemini_client = genai.Client(api_key=GEMINI_API_KEY)
 
120
  except Exception as e:
121
  print(f"Error initializing Gemini client: {e}")
122
  gemini_client = None
@@ -133,14 +269,18 @@ def generate_gemini_prompt(type_name, shape_name, color_name, type_conf, shape_c
133
  color_desc = COLOR_DESCRIPTIONS[color_name]
134
 
135
  prompt = f"""You are a board-certified gastroenterologist with over 15 years of clinical experience specializing in digestive health and bowel disorders. A gastroenterologist is a medical doctor who specializes in the diagnosis and treatment of disorders of the digestive system, which includes organs from the mouth to the anus. They treat a wide range of conditions, such as irritable bowel syndrome (IBS), ulcers, heartburn, and liver diseases. To do so, they use a combination of clinical examinations, blood tests, imaging, and procedures like endoscopy.
 
136
  **What You Do as a Gastroenterologist:**
137
  **Diagnose and treat digestive disorders:** You identify and manage diseases affecting the esophagus, stomach, intestines, pancreas, liver, gallbladder, and bile ducts, with particular expertise in stool-related conditions and bowel health.
138
  **Perform diagnostic procedures:** You utilize tools like endoscopes, CT scans, MRIs, and ultrasounds to examine the digestive tract, and you are highly skilled in analyzing stool characteristics as diagnostic indicators.
139
  **Manage complex conditions:** You handle chronic diseases like hepatitis, colitis, and pancreatitis, as well as cancer and nutritional problems, with extensive experience in conditions that affect stool consistency, frequency, and appearance.
140
  **Provide treatment:** You prescribe medication and recommend dietary modifications, lifestyle changes, fiber supplementation, and hydration strategies specifically tailored to improve stool consistency and bowel regularity. You also perform endoscopic procedures like colonoscopy and sigmoidoscopy when stool analysis indicates the need for further investigation.
 
141
  You have a warm, empathetic approach and excel at explaining complex medical concepts in accessible language. Your patients appreciate your thoroughness, compassion, and practical guidance.
 
142
  **YOUR ROLE:**
143
  Provide a comprehensive, evidence-based analysis of the Bristol Stool Chart classification while maintaining a supportive, non-judgmental tone. Your goal is to educate, reassure, and empower the patient with actionable insights based on your extensive experience in stool analysis and bowel health.
 
144
  **REASONING FRAMEWORK (Chain of Thought):**
145
  Before providing your analysis, consider:
146
  1. What does this stool type indicate about gut transit time?
@@ -148,47 +288,68 @@ Before providing your analysis, consider:
148
  3. What immediate and long-term health implications should be addressed?
149
  4. What evidence-based interventions are most effective?
150
  5. When should professional medical evaluation be prioritized?
 
151
  ---
 
152
  **CURRENT CLASSIFICATION RESULT:**
 
153
  **Bristol Stool Type:** {type_name}
154
  **Description:** {type_info['description']}
155
  **Clinical Significance:** {type_info['condition']}
156
  **Confidence:** {type_conf:.1f}%
 
157
  **Stool Shape:** {shape_name}
158
  **Shape Analysis:** {shape_desc}
159
  **Shape Confidence:** {shape_conf:.1f}%
 
160
  **Stool Color:** {color_name}
161
  **Color Analysis:** {color_desc}
162
  **Color Confidence:** {color_conf:.1f}%
 
163
  ---
 
164
  **INSTRUCTIONS:**
165
  Provide a comprehensive gastroenterological analysis. Structure your response naturally with appropriate markdown headers (##, ###) for main sections. Do NOT include instructional labels like "Warm, Professional Greeting" or "Encouragement & Empowerment" as headers - these are content guidelines, not section titles to display.
 
166
  Your response should naturally flow through these topics:
 
167
  1. Begin with a warm, professional greeting that acknowledges the person compassionately
 
168
  2. Explain the Bristol Type classification in accessible terms, including what it indicates about gut transit time
 
169
  3. **IMPORTANT:** Integrate the shape analysis ({shape_name}: {shape_desc}) and color analysis ({color_name}: {color_desc}) into your explanation, discussing how these characteristics provide additional clinical insights
 
170
  4. Describe the physiological mechanisms at play (use analogies where helpful)
 
171
  5. Explain clinical implications, both short-term and long-term health considerations, taking into account the combination of type, shape, and color
 
172
  6. Provide an action plan divided into:
173
  - Immediate Steps (24-72 hours)
174
  - Medium-Term Strategy (1-4 weeks)
175
  - Long-term Maintenance
 
176
  7. Include evidence-based recommendations covering:
177
  - Specific dietary changes with examples
178
  - Hydration guidelines
179
  - Physical activity suggestions
180
  - Lifestyle modifications
181
  - Supplement considerations (if appropriate)
 
182
  8. Provide clear criteria for when to seek medical attention, including red flags (pay special attention if color is abnormal)
 
183
  9. Set timeline expectations - what changes to expect and when
 
184
  10. End with supportive closing remarks emphasizing patient agency
 
185
  Use descriptive section headers like "Understanding Your Classification", "What's Happening in Your Body", "Your Action Plan", etc.
 
186
  **TONE GUIDELINES:**
187
  - Warm, empathetic, non-judgmental
188
  - Professional yet accessible
189
  - Evidence-based but not overly technical
190
  - Empowering and action-oriented
191
  - Balanced (acknowledge concerns without causing alarm)
 
192
  **FORMATTING:**
193
  - Use clear markdown headers (##, ###) and subheaders
194
  - Bullet points for actionable items
@@ -196,6 +357,7 @@ Use descriptive section headers like "Understanding Your Classification", "What'
196
  - Maintain readability with short paragraphs
197
  - Do NOT include HTML tags - use markdown only
198
  - Do NOT repeat section instruction labels as headers
 
199
  Please provide your comprehensive analysis now."""
200
 
201
  return prompt
@@ -205,14 +367,39 @@ Please provide your comprehensive analysis now."""
205
  # PREDICTION FUNCTION
206
  # ========================================
207
  def predict(image):
208
- """Predict Bristol type, shape, color, and get detailed AI analysis."""
209
  if image is None:
210
  return None, None, None, "⚠️ **Please upload an image to analyze.**"
211
 
212
  try:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
213
  # Preprocess and run inference
214
  img = image.convert("RGB")
215
- x = transform(img).unsqueeze(0)
216
 
217
  with torch.no_grad():
218
  type_out, shape_out, color_out = model(x)
@@ -239,18 +426,29 @@ def predict(image):
239
  # Generate AI analysis
240
  if gemini_client is None:
241
  analysis = f"""## ⚠️ AI Analysis Unavailable
 
242
  **Classification Summary:**
 
243
  {BRISTOL_DESCRIPTIONS[type_name]['emoji']} **{type_name}**
244
  - **Description:** {BRISTOL_DESCRIPTIONS[type_name]['description']}
245
  - **Condition:** {BRISTOL_DESCRIPTIONS[type_name]['condition']}
246
  - **Confidence:** {type_conf:.1f}%
 
247
  **Shape:** {shape_name} ({shape_conf:.1f}% confidence)
248
  - {SHAPE_DESCRIPTIONS[shape_name]}
 
249
  **Color:** {color_name} ({color_conf:.1f}% confidence)
250
  - {COLOR_DESCRIPTIONS[color_name]}
 
 
 
 
251
  ---
 
252
  *Note: Set GEMINI_API_KEY environment variable to enable detailed AI-powered gastroenterological analysis.*
 
253
  ### Quick Health Tips Based on Your Classification:
 
254
  **For {type_name}:**
255
  - {'Increase fiber intake and hydration' if 'Type 1' in type_name or 'Type 2' in type_name else 'Maintain balanced diet and regular exercise'}
256
  - {'Consider consulting a gastroenterologist if symptoms persist' if 'Type 1' in type_name or 'Type 7' in type_name else 'Monitor changes over time'}
@@ -263,29 +461,48 @@ def predict(image):
263
  )
264
 
265
  response = gemini_client.models.generate_content(
266
- model="gemini-2.5-flash",
267
  contents=prompt
268
  )
269
 
270
- analysis = response.text
 
 
 
 
 
 
 
 
 
 
 
271
 
272
  except Exception as e:
273
  analysis = f"""## ⚠️ Error Generating AI Analysis
 
274
  **Error:** {str(e)}
 
275
  **Classification Summary:**
 
276
  {BRISTOL_DESCRIPTIONS[type_name]['emoji']} **{type_name}**
277
  - **Description:** {BRISTOL_DESCRIPTIONS[type_name]['description']}
278
  - **Condition:** {BRISTOL_DESCRIPTIONS[type_name]['condition']}
279
  - **Confidence:** {type_conf:.1f}%
 
280
  **Shape:** {shape_name} ({shape_conf:.1f}% confidence)
281
  **Color:** {color_name} ({color_conf:.1f}% confidence)
 
 
282
  """
283
 
284
  return type_dict, shape_dict, color_dict, analysis
285
 
286
  except Exception as e:
287
  error_msg = f"""## ❌ Error Processing Image
 
288
  **Error:** {str(e)}
 
289
  Please ensure you've uploaded a valid image file and try again.
290
  """
291
  return None, None, None, error_msg
@@ -321,9 +538,10 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
321
  gr.Markdown("""
322
  # πŸ₯ StoolNet Triple Attention β€” AI-Powered Bristol Stool Scale Classifier
323
 
324
- ### Advanced Multi-Task Deep Learning Model for Comprehensive Stool Analysis
325
 
326
- This application combines **Triple Attention ResNet34** with **Google Gemini 2.5 Flash AI** for comprehensive gastroenterological assessment.
 
327
  """)
328
 
329
  # ========================================
@@ -342,6 +560,8 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
342
  1. Upload your image OR select from samples below
343
  2. Click "Analyze Sample"
344
  3. View results on the right
 
 
345
  """)
346
 
347
  # Sample Images Section
@@ -397,9 +617,16 @@ with gr.Blocks(theme=gr.themes.Soft(), css="""
397
  ### πŸ”¬ Model Information
398
 
399
  **Architecture:** Triple Attention ResNet34 (Position, Channel, Type Attention) + Multi-Task Learning
400
- **AI Analysis:** Powered by Google Gemini 2.5 Flash
 
401
  **Model Repository:** [Sid3503/stoolnet-bristol-scale-triple-attn](https://huggingface.co/Sid3503/stoolnet-bristol-scale-triple-attn)
402
 
 
 
 
 
 
 
403
  ### πŸ“š Bristol Stool Scale Quick Reference
404
 
405
  | Type | Description | Indication |
 
1
+ # app.py for Gradio Space with Gemini 2.5 Flash Integration + OOD Detection
2
  import gradio as gr
3
  import torch
4
+ import torch.nn as nn
5
  from PIL import Image
6
  from torchvision import transforms
7
  from huggingface_hub import hf_hub_download
8
  from model import StoolNetTriple
9
  import os
10
+ import numpy as np
11
+ import json
12
+ import joblib
13
  from google import genai
14
 
15
 
16
+ # ========================================
17
+ # FEATURE AUTOENCODER ARCHITECTURE
18
+ # ========================================
19
+ class FeatureAutoencoder(nn.Module):
20
+ def __init__(self, input_dim: int = 512, latent_dim: int = 128, hidden_dim: int = 256):
21
+ super().__init__()
22
+ self.encoder = nn.Sequential(
23
+ nn.Linear(input_dim, hidden_dim),
24
+ nn.ReLU(inplace=True),
25
+ nn.Linear(hidden_dim, latent_dim),
26
+ )
27
+ self.decoder = nn.Sequential(
28
+ nn.Linear(latent_dim, hidden_dim),
29
+ nn.ReLU(inplace=True),
30
+ nn.Linear(hidden_dim, input_dim),
31
+ )
32
+
33
+ def forward(self, x: torch.Tensor) -> torch.Tensor:
34
+ z = self.encoder(x)
35
+ xhat = self.decoder(z)
36
+ return xhat
37
+
38
+
39
  # ========================================
40
  # MODEL SETUP - Download from HF Hub
41
  # ========================================
42
+ HF_TOKEN = os.getenv("HF_TOKEN")
43
 
44
  print("Downloading model from Hugging Face Hub...")
45
  model_path = hf_hub_download(
46
  repo_id="Sid3503/stoolnet-bristol-scale-triple-attn",
47
  filename="pytorch_model.bin",
48
+ token=HF_TOKEN
49
  )
50
 
51
  print("Loading model...")
52
+ device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
53
  model = StoolNetTriple()
54
+ state = torch.load(model_path, map_location=device)
55
  model.load_state_dict(state)
56
  model.eval()
57
+ model = model.to(device)
58
+ print(f"Model loaded successfully on {device}!")
59
 
60
  # Define transform
61
  transform = transforms.Compose([
 
65
  ])
66
 
67
 
68
+ # ========================================
69
+ # LOAD AUTOENCODER ARTIFACTS FOR OOD DETECTION
70
+ # ========================================
71
+ print("Loading autoencoder artifacts for outlier detection...")
72
+ ae_dir = 'ae_artifacts_triple_attn'
73
+ ae_path = os.path.join(ae_dir, 'feature_ae.pth')
74
+ scaler_path = os.path.join(ae_dir, 'scaler.pkl')
75
+ thr_path = os.path.join(ae_dir, 'threshold.json')
76
+
77
+ feature_ae = None
78
+ feature_ae_scaler = None
79
+ feature_ae_threshold = None
80
+
81
+ try:
82
+ if os.path.isfile(ae_path) and os.path.isfile(scaler_path) and os.path.isfile(thr_path):
83
+ # Load autoencoder
84
+ feature_ae = FeatureAutoencoder(input_dim=512, latent_dim=128, hidden_dim=256).to(device)
85
+ ae_state = torch.load(ae_path, map_location=device)
86
+ feature_ae.load_state_dict(ae_state['model_state_dict'])
87
+ feature_ae.eval()
88
+
89
+ # Load scaler
90
+ feature_ae_scaler = joblib.load(scaler_path)
91
+
92
+ # Load threshold
93
+ with open(thr_path, 'r') as f:
94
+ thr_data = json.load(f)
95
+ feature_ae_threshold = float(thr_data.get('threshold', 0.0))
96
+
97
+ print(f"βœ“ Autoencoder artifacts loaded successfully (threshold: {feature_ae_threshold:.5f})")
98
+ else:
99
+ print("⚠ Autoencoder artifact files not found. OOD detection will be disabled.")
100
+ except Exception as e:
101
+ print(f"⚠ Error loading autoencoder: {e}")
102
+
103
+
104
+ # ========================================
105
+ # FEATURE EXTRACTION FUNCTION
106
+ # ========================================
107
+ @torch.no_grad()
108
+ def extract_feature_vector(image: Image.Image) -> np.ndarray:
109
+ """Extract 512-D feature vector from StoolNetTriple model"""
110
+ image_tensor = transform(image).unsqueeze(0).to(device)
111
+
112
+ # Forward pass through backbone
113
+ x = model.conv1(image_tensor)
114
+ x = model.bn1(x)
115
+ x = model.relu(x)
116
+ x = model.maxpool(x)
117
+ x = model.layer1(x)
118
+ x = model.layer2(x)
119
+ x = model.layer3(x)
120
+ x = model.layer4(x)
121
+
122
+ # Pass through triple attention
123
+ x, _ = model.triple_attention(x)
124
+
125
+ # Global average pooling
126
+ x = model.avgpool(x)
127
+ feats = torch.flatten(x, 1)
128
+
129
+ # Normalize features
130
+ feats = torch.nn.functional.normalize(feats, dim=1)
131
+ return feats.squeeze(0).cpu().numpy()
132
+
133
+
134
+ # ========================================
135
+ # OUTLIER DETECTION FUNCTION
136
+ # ========================================
137
+ def check_outlier(image: Image.Image) -> dict:
138
+ """Check if image is an outlier using autoencoder reconstruction error"""
139
+ if feature_ae is None or feature_ae_scaler is None or feature_ae_threshold is None:
140
+ return {
141
+ 'is_outlier': False,
142
+ 'ae_residual': None,
143
+ 'ae_threshold': None,
144
+ 'message': None
145
+ }
146
+
147
+ try:
148
+ # Extract feature vector
149
+ fv = extract_feature_vector(image).astype(np.float32)
150
+
151
+ # Standardize features
152
+ fv_std = feature_ae_scaler.transform(fv.reshape(1, -1)).astype(np.float32)
153
+
154
+ # Compute reconstruction error
155
+ x = torch.from_numpy(fv_std).to(device)
156
+ with torch.no_grad():
157
+ recon = feature_ae(x)
158
+ ae_residual = torch.mean((recon - x) ** 2, dim=1).item()
159
+
160
+ # Check if outlier
161
+ is_outlier = ae_residual > feature_ae_threshold
162
+
163
+ return {
164
+ 'is_outlier': is_outlier,
165
+ 'ae_residual': ae_residual,
166
+ 'ae_threshold': feature_ae_threshold,
167
+ 'message': (
168
+ f"⚠️ **Outlier Detected**: This image does not appear to be a valid stool sample. "
169
+ f"Reconstruction error ({ae_residual:.5f}) exceeds threshold ({feature_ae_threshold:.5f})."
170
+ ) if is_outlier else None
171
+ }
172
+ except Exception as e:
173
+ print(f"Error in outlier detection: {e}")
174
+ return {
175
+ 'is_outlier': False,
176
+ 'ae_residual': None,
177
+ 'ae_threshold': None,
178
+ 'message': None
179
+ }
180
 
181
 
182
  # ========================================
 
252
  else:
253
  try:
254
  gemini_client = genai.Client(api_key=GEMINI_API_KEY)
255
+ print("βœ“ Gemini API client initialized")
256
  except Exception as e:
257
  print(f"Error initializing Gemini client: {e}")
258
  gemini_client = None
 
269
  color_desc = COLOR_DESCRIPTIONS[color_name]
270
 
271
  prompt = f"""You are a board-certified gastroenterologist with over 15 years of clinical experience specializing in digestive health and bowel disorders. A gastroenterologist is a medical doctor who specializes in the diagnosis and treatment of disorders of the digestive system, which includes organs from the mouth to the anus. They treat a wide range of conditions, such as irritable bowel syndrome (IBS), ulcers, heartburn, and liver diseases. To do so, they use a combination of clinical examinations, blood tests, imaging, and procedures like endoscopy.
272
+
273
  **What You Do as a Gastroenterologist:**
274
  **Diagnose and treat digestive disorders:** You identify and manage diseases affecting the esophagus, stomach, intestines, pancreas, liver, gallbladder, and bile ducts, with particular expertise in stool-related conditions and bowel health.
275
  **Perform diagnostic procedures:** You utilize tools like endoscopes, CT scans, MRIs, and ultrasounds to examine the digestive tract, and you are highly skilled in analyzing stool characteristics as diagnostic indicators.
276
  **Manage complex conditions:** You handle chronic diseases like hepatitis, colitis, and pancreatitis, as well as cancer and nutritional problems, with extensive experience in conditions that affect stool consistency, frequency, and appearance.
277
  **Provide treatment:** You prescribe medication and recommend dietary modifications, lifestyle changes, fiber supplementation, and hydration strategies specifically tailored to improve stool consistency and bowel regularity. You also perform endoscopic procedures like colonoscopy and sigmoidoscopy when stool analysis indicates the need for further investigation.
278
+
279
  You have a warm, empathetic approach and excel at explaining complex medical concepts in accessible language. Your patients appreciate your thoroughness, compassion, and practical guidance.
280
+
281
  **YOUR ROLE:**
282
  Provide a comprehensive, evidence-based analysis of the Bristol Stool Chart classification while maintaining a supportive, non-judgmental tone. Your goal is to educate, reassure, and empower the patient with actionable insights based on your extensive experience in stool analysis and bowel health.
283
+
284
  **REASONING FRAMEWORK (Chain of Thought):**
285
  Before providing your analysis, consider:
286
  1. What does this stool type indicate about gut transit time?
 
288
  3. What immediate and long-term health implications should be addressed?
289
  4. What evidence-based interventions are most effective?
290
  5. When should professional medical evaluation be prioritized?
291
+
292
  ---
293
+
294
  **CURRENT CLASSIFICATION RESULT:**
295
+
296
  **Bristol Stool Type:** {type_name}
297
  **Description:** {type_info['description']}
298
  **Clinical Significance:** {type_info['condition']}
299
  **Confidence:** {type_conf:.1f}%
300
+
301
  **Stool Shape:** {shape_name}
302
  **Shape Analysis:** {shape_desc}
303
  **Shape Confidence:** {shape_conf:.1f}%
304
+
305
  **Stool Color:** {color_name}
306
  **Color Analysis:** {color_desc}
307
  **Color Confidence:** {color_conf:.1f}%
308
+
309
  ---
310
+
311
  **INSTRUCTIONS:**
312
  Provide a comprehensive gastroenterological analysis. Structure your response naturally with appropriate markdown headers (##, ###) for main sections. Do NOT include instructional labels like "Warm, Professional Greeting" or "Encouragement & Empowerment" as headers - these are content guidelines, not section titles to display.
313
+
314
  Your response should naturally flow through these topics:
315
+
316
  1. Begin with a warm, professional greeting that acknowledges the person compassionately
317
+
318
  2. Explain the Bristol Type classification in accessible terms, including what it indicates about gut transit time
319
+
320
  3. **IMPORTANT:** Integrate the shape analysis ({shape_name}: {shape_desc}) and color analysis ({color_name}: {color_desc}) into your explanation, discussing how these characteristics provide additional clinical insights
321
+
322
  4. Describe the physiological mechanisms at play (use analogies where helpful)
323
+
324
  5. Explain clinical implications, both short-term and long-term health considerations, taking into account the combination of type, shape, and color
325
+
326
  6. Provide an action plan divided into:
327
  - Immediate Steps (24-72 hours)
328
  - Medium-Term Strategy (1-4 weeks)
329
  - Long-term Maintenance
330
+
331
  7. Include evidence-based recommendations covering:
332
  - Specific dietary changes with examples
333
  - Hydration guidelines
334
  - Physical activity suggestions
335
  - Lifestyle modifications
336
  - Supplement considerations (if appropriate)
337
+
338
  8. Provide clear criteria for when to seek medical attention, including red flags (pay special attention if color is abnormal)
339
+
340
  9. Set timeline expectations - what changes to expect and when
341
+
342
  10. End with supportive closing remarks emphasizing patient agency
343
+
344
  Use descriptive section headers like "Understanding Your Classification", "What's Happening in Your Body", "Your Action Plan", etc.
345
+
346
  **TONE GUIDELINES:**
347
  - Warm, empathetic, non-judgmental
348
  - Professional yet accessible
349
  - Evidence-based but not overly technical
350
  - Empowering and action-oriented
351
  - Balanced (acknowledge concerns without causing alarm)
352
+
353
  **FORMATTING:**
354
  - Use clear markdown headers (##, ###) and subheaders
355
  - Bullet points for actionable items
 
357
  - Maintain readability with short paragraphs
358
  - Do NOT include HTML tags - use markdown only
359
  - Do NOT repeat section instruction labels as headers
360
+
361
  Please provide your comprehensive analysis now."""
362
 
363
  return prompt
 
367
  # PREDICTION FUNCTION
368
  # ========================================
369
  def predict(image):
370
+ """Predict Bristol type, shape, color, check for outliers, and get detailed AI analysis."""
371
  if image is None:
372
  return None, None, None, "⚠️ **Please upload an image to analyze.**"
373
 
374
  try:
375
+ # Check for outliers first
376
+ outlier_result = check_outlier(image)
377
+
378
+ if outlier_result['is_outlier']:
379
+ # Return outlier warning without predictions
380
+ outlier_message = f"""## ⚠️ Invalid Image Detected
381
+
382
+ {outlier_result['message']}
383
+
384
+ ### Quality Check Details:
385
+ - **Reconstruction Error:** {outlier_result['ae_residual']:.5f}
386
+ - **Threshold:** {outlier_result['ae_threshold']:.5f}
387
+
388
+ **Please upload a clear image of a stool sample for accurate analysis.**
389
+
390
+ ---
391
+
392
+ **Tips for Better Images:**
393
+ - Ensure good lighting
394
+ - Image should clearly show stool sample
395
+ - Avoid blurry or unclear images
396
+ - Image should contain actual stool content
397
+ """
398
+ return None, None, None, outlier_message
399
+
400
  # Preprocess and run inference
401
  img = image.convert("RGB")
402
+ x = transform(img).unsqueeze(0).to(device)
403
 
404
  with torch.no_grad():
405
  type_out, shape_out, color_out = model(x)
 
426
  # Generate AI analysis
427
  if gemini_client is None:
428
  analysis = f"""## ⚠️ AI Analysis Unavailable
429
+
430
  **Classification Summary:**
431
+
432
  {BRISTOL_DESCRIPTIONS[type_name]['emoji']} **{type_name}**
433
  - **Description:** {BRISTOL_DESCRIPTIONS[type_name]['description']}
434
  - **Condition:** {BRISTOL_DESCRIPTIONS[type_name]['condition']}
435
  - **Confidence:** {type_conf:.1f}%
436
+
437
  **Shape:** {shape_name} ({shape_conf:.1f}% confidence)
438
  - {SHAPE_DESCRIPTIONS[shape_name]}
439
+
440
  **Color:** {color_name} ({color_conf:.1f}% confidence)
441
  - {COLOR_DESCRIPTIONS[color_name]}
442
+
443
+ **Quality Check:** βœ… Image passed outlier detection
444
+ - Reconstruction Error: {outlier_result['ae_residual']:.5f} (threshold: {outlier_result['ae_threshold']:.5f})
445
+
446
  ---
447
+
448
  *Note: Set GEMINI_API_KEY environment variable to enable detailed AI-powered gastroenterological analysis.*
449
+
450
  ### Quick Health Tips Based on Your Classification:
451
+
452
  **For {type_name}:**
453
  - {'Increase fiber intake and hydration' if 'Type 1' in type_name or 'Type 2' in type_name else 'Maintain balanced diet and regular exercise'}
454
  - {'Consider consulting a gastroenterologist if symptoms persist' if 'Type 1' in type_name or 'Type 7' in type_name else 'Monitor changes over time'}
 
461
  )
462
 
463
  response = gemini_client.models.generate_content(
464
+ model="gemini-2.0-flash-exp",
465
  contents=prompt
466
  )
467
 
468
+ # Add quality check info to analysis
469
+ analysis = response.text + f"""
470
+
471
+ ---
472
+
473
+ ### πŸ” Quality Assurance
474
+
475
+ βœ… **Image Quality Check Passed**
476
+ - **Reconstruction Error:** {outlier_result['ae_residual']:.5f}
477
+ - **Threshold:** {outlier_result['ae_threshold']:.5f}
478
+ - **Status:** Valid stool sample detected
479
+ """
480
 
481
  except Exception as e:
482
  analysis = f"""## ⚠️ Error Generating AI Analysis
483
+
484
  **Error:** {str(e)}
485
+
486
  **Classification Summary:**
487
+
488
  {BRISTOL_DESCRIPTIONS[type_name]['emoji']} **{type_name}**
489
  - **Description:** {BRISTOL_DESCRIPTIONS[type_name]['description']}
490
  - **Condition:** {BRISTOL_DESCRIPTIONS[type_name]['condition']}
491
  - **Confidence:** {type_conf:.1f}%
492
+
493
  **Shape:** {shape_name} ({shape_conf:.1f}% confidence)
494
  **Color:** {color_name} ({color_conf:.1f}% confidence)
495
+
496
+ **Quality Check:** βœ… Passed (AE Error: {outlier_result['ae_residual']:.5f})
497
  """
498
 
499
  return type_dict, shape_dict, color_dict, analysis
500
 
501
  except Exception as e:
502
  error_msg = f"""## ❌ Error Processing Image
503
+
504
  **Error:** {str(e)}
505
+
506
  Please ensure you've uploaded a valid image file and try again.
507
  """
508
  return None, None, None, error_msg
 
538
  gr.Markdown("""
539
  # πŸ₯ StoolNet Triple Attention β€” AI-Powered Bristol Stool Scale Classifier
540
 
541
+ ### Advanced Multi-Task Deep Learning Model with Outlier Detection
542
 
543
+ This application combines **Triple Attention ResNet34** with **Google Gemini 2.0 Flash AI** for comprehensive gastroenterological assessment.
544
+ Features built-in **outlier detection** to identify invalid or unclear images.
545
  """)
546
 
547
  # ========================================
 
560
  1. Upload your image OR select from samples below
561
  2. Click "Analyze Sample"
562
  3. View results on the right
563
+
564
+ **Note:** Images undergo automatic quality validation using autoencoder-based outlier detection.
565
  """)
566
 
567
  # Sample Images Section
 
617
  ### πŸ”¬ Model Information
618
 
619
  **Architecture:** Triple Attention ResNet34 (Position, Channel, Type Attention) + Multi-Task Learning
620
+ **AI Analysis:** Powered by Google Gemini 2.0 Flash
621
+ **Outlier Detection:** Feature-space Autoencoder (trained on reference dataset)
622
  **Model Repository:** [Sid3503/stoolnet-bristol-scale-triple-attn](https://huggingface.co/Sid3503/stoolnet-bristol-scale-triple-attn)
623
 
624
+ ### πŸ›‘οΈ Quality Assurance Features
625
+
626
+ - **Autoencoder-based OOD Detection**: Identifies images that don't match training distribution
627
+ - **Reconstruction Error Threshold**: Images with high reconstruction error are flagged as invalid
628
+ - **Real-time Quality Feedback**: Immediate notification if uploaded image is not a valid stool sample
629
+
630
  ### πŸ“š Bristol Stool Scale Quick Reference
631
 
632
  | Type | Description | Indication |
requirements.txt CHANGED
@@ -3,4 +3,5 @@ torch>=2.0.0
3
  torchvision>=0.15.0
4
  pillow>=9.0.0
5
  huggingface-hub>=0.19.0
6
- google-genai>=1.0.0
 
 
3
  torchvision>=0.15.0
4
  pillow>=9.0.0
5
  huggingface-hub>=0.19.0
6
+ google-genai>=1.0.0
7
+ joblib>=1.3.0