mgbam commited on
Commit
cf79036
·
verified ·
1 Parent(s): c79e22e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +107 -103
app.py CHANGED
@@ -1,10 +1,7 @@
1
  """
2
- 🫁 Multi-Class Chest X-Ray Detection with Adaptive Sparse Training
3
- WOW UI/UX Edition 4 Disease Classes
4
-
5
- - Normal, Tuberculosis, Pneumonia, COVID-19
6
- - Grad-CAM (Explainable AI)
7
- - Energy-efficient Adaptive Sparse Training
8
  """
9
 
10
  import io
@@ -12,6 +9,8 @@ from pathlib import Path
12
 
13
  import cv2
14
  import gradio as gr
 
 
15
  import matplotlib.pyplot as plt
16
  import numpy as np
17
  import torch
@@ -25,36 +24,68 @@ from torchvision import models, transforms
25
 
26
  device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
27
 
28
- # EfficientNet backbone
 
29
  model = models.efficientnet_b0(weights=None)
30
- model.classifier[1] = nn.Linear(model.classifier[1].in_features, 4) # 4 classes
31
 
32
- # Try a few reasonable checkpoint locations
33
  checkpoint_candidates = [
34
- "best.pt",
35
- "checkpoints/best.pt", # <-- your current file
36
- "checkpoints/lasttb.pt", # optional fallback
37
  ]
38
 
39
  MODEL_LOAD_INFO = ""
40
  loaded = False
41
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
  for ckpt_path in checkpoint_candidates:
43
  if Path(ckpt_path).is_file():
44
  try:
45
  print(f"🔍 Trying to load weights from: {ckpt_path}")
46
- state_dict = torch.load(ckpt_path, map_location=device)
47
- model.load_state_dict(state_dict)
48
- MODEL_LOAD_INFO = f"✅ Model loaded from **{ckpt_path}** on **{device.type.upper()}**."
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
  loaded = True
50
  break
51
  except Exception as e:
52
- print(f"⚠️ Found {ckpt_path} but failed to load: {e}")
53
 
54
  if not loaded:
55
  raise RuntimeError(
56
- "Model file not found or could not be loaded. "
57
- "Please upload 'checkpoints/best.pt' (or 'best.pt' in the repo root)."
 
 
 
58
  )
59
 
60
  model = model.to(device)
@@ -69,10 +100,10 @@ TOTAL_PARAMS_M = TOTAL_PARAMS / 1e6
69
 
70
  CLASSES = ["Normal", "Tuberculosis", "Pneumonia", "COVID-19"]
71
  CLASS_COLORS = {
72
- "Normal": "#2ecc71", # Green
73
- "Tuberculosis": "#e74c3c", # Red
74
- "Pneumonia": "#f39c12", # Orange
75
- "COVID-19": "#9b59b6", # Purple
76
  }
77
 
78
  transform = transforms.Compose(
@@ -207,7 +238,6 @@ def create_overlay_visualization(image, cam):
207
  plt.tight_layout()
208
  return _figure_to_pil()
209
 
210
-
211
  # ============================================================================
212
  # Interpretation
213
  # ============================================================================
@@ -237,7 +267,6 @@ def create_interpretation(pred_label, confidence, results, audience="Clinician")
237
  ---
238
  """
239
 
240
- # Disease-specific sections (same logic, slightly formatted)
241
  if pred_label == "Tuberculosis":
242
  if confidence >= 85:
243
  interpretation += """
@@ -245,18 +274,12 @@ def create_interpretation(pred_label, confidence, results, audience="Clinician")
245
 
246
  The model has detected features strongly suggestive of **pulmonary tuberculosis**.
247
 
248
- **Recommended Clinical Pathway:**
249
- 1. Immediate medical review by a clinician or chest physician
250
- 2. ✅ **Sputum testing** (AFB smear, GeneXpert MTB/RIF, or TB-PCR)
251
- 3. Correlate with symptoms:
252
- - Persistent cough > 2 weeks
253
- - Weight loss, night sweats
254
- - Fever, fatigue
255
- - Hemoptysis (coughing blood)
256
- 4. ✅ Consider CT scan or additional imaging if uncertainty remains
257
- 5. ✅ Infection control and contact tracing if TB is confirmed
258
-
259
- > This tool helps *flag* suspicious cases. TB diagnosis still requires **laboratory confirmation**.
260
  """
261
  else:
262
  interpretation += """
@@ -264,10 +287,9 @@ The model has detected features strongly suggestive of **pulmonary tuberculosis*
264
 
265
  The scan shows features that **could** be compatible with tuberculosis, but confidence is moderate.
266
 
267
- **Suggested Actions:**
268
- - Clinical review and detailed history
269
- - Consider sputum testing if symptoms or risk factors are present
270
- - Follow-up imaging where clinically indicated
271
  """
272
 
273
  elif pred_label == "Pneumonia":
@@ -277,15 +299,13 @@ The scan shows features that **could** be compatible with tuberculosis, but conf
277
 
278
  The model has detected an opacity pattern consistent with **pneumonia**.
279
 
280
- **Typical Clinical Correlates:**
 
281
  - Fever, productive cough
282
  - Shortness of breath
283
  - Pleuritic chest pain
284
 
285
- **Next Steps (for clinicians):**
286
- - Correlate with fever, auscultation, and lab results
287
- - Consider antibiotics for bacterial pneumonia as per local guidelines
288
- - Repeat imaging if clinical evolution is atypical
289
  """
290
  else:
291
  interpretation += """
@@ -293,10 +313,9 @@ The model has detected an opacity pattern consistent with **pneumonia**.
293
 
294
  Findings may be compatible with pneumonia, but alternative explanations exist.
295
 
296
- **Recommended:**
297
- - Clinical evaluation (vital signs, exam)
298
- - Consider labs (WBC, CRP, cultures)
299
- - Watchful follow-up or repeat imaging as appropriate
300
  """
301
 
302
  elif pred_label == "COVID-19":
@@ -306,27 +325,20 @@ Findings may be compatible with pneumonia, but alternative explanations exist.
306
 
307
  Distribution and appearance of opacities are compatible with **COVID-19 pneumonia**.
308
 
309
- **Critical Points:**
310
- - Imaging is **not** diagnostic by itself
311
- - **RT-PCR / rapid antigen testing** is mandatory for confirmation
312
-
313
- **If clinically suspected:**
314
- - Isolate per local infection-control policies
315
- - Monitor SpO₂ and respiratory status
316
- - Escalate care if:
317
- - SpO₂ < 94% on room air
318
- - Increasing work of breathing
319
- - Hemodynamic instability
320
  """
321
  else:
322
  interpretation += """
323
  ### 🦠 COVID-19 Pattern – Possible
324
 
325
- Some features may overlap with COVID-19, but there is **significant uncertainty**.
326
 
327
- **Do not rely on imaging alone.**
328
- - Obtain RT-PCR / rapid antigen testing
329
- - Use clinical context and epidemiology to guide decisions
330
  """
331
 
332
  else: # Normal
@@ -334,12 +346,13 @@ Some features may overlap with COVID-19, but there is **significant uncertainty*
334
  interpretation += """
335
  ### ✅ No Major Abnormality Detected
336
 
337
- The model did **not** detect features suggestive of TB, pneumonia, or COVID-19.
 
 
338
 
339
- **Important Caveats:**
340
  - Early disease or small lesions may be missed
341
  - Non-infective conditions (e.g., cancer, ILD) are **not** specifically evaluated
342
- - If symptoms are present, further workup may still be required
343
  """
344
  else:
345
  interpretation += """
@@ -347,43 +360,38 @@ The model did **not** detect features suggestive of TB, pneumonia, or COVID-19.
347
 
348
  The scan leans towards **normal**, but the model is not highly confident.
349
 
350
- **If symptoms persist:**
351
- - Consider follow-up imaging
352
- - Seek a clinician’s interpretation
353
  """
354
 
355
- # Universal disclaimer
356
  interpretation += """
357
  ---
358
  ## ⚠️ CRITICAL MEDICAL DISCLAIMER
359
 
360
  - This AI model is a **screening / decision-support tool only**
361
- - It is **not FDA-approved** and **must not** be used as a stand-alone diagnostic device
362
  - Always integrate:
363
  - Clinical history and examination
364
- - Laboratory tests (e.g., sputum, PCR, cultures)
365
  - Expert radiologist review
366
 
367
- **Gold Standards:**
 
368
  - TB: Sputum AFB / culture, GeneXpert MTB/RIF, TB-PCR
369
  - Pneumonia: Clinical diagnosis + labs / microbiology
370
  - COVID-19: RT-PCR or validated antigen tests
371
 
372
  When in doubt, consult a qualified healthcare professional.
373
- """
374
-
375
- interpretation += """
376
  ---
377
  🫁 **Powered by Adaptive Sparse Training (AST)**
378
- Energy-efficient deep learning – designed to make advanced chest X-ray screening more accessible.
 
 
379
 
380
- **Links:**
381
  - GitHub: https://github.com/oluwafemidiakhoa/Tuberculosis
382
  - Hugging Face Space: https://huggingface.co/spaces/mgbam/Tuberculosis
383
  """
384
  return interpretation
385
 
386
-
387
  # ============================================================================
388
  # Prediction Pipeline
389
  # ============================================================================
@@ -412,7 +420,6 @@ def predict_chest_xray(image, show_gradcam=True, audience="Clinician"):
412
  original_img = image.copy()
413
  input_tensor = transform(image).unsqueeze(0).to(device)
414
 
415
- # Inference with optional Grad-CAM
416
  with torch.set_grad_enabled(show_gradcam):
417
  if show_gradcam:
418
  cam, output = grad_cam.generate(input_tensor)
@@ -435,18 +442,15 @@ def predict_chest_xray(image, show_gradcam=True, audience="Clinician"):
435
  for i in range(len(CLASSES))
436
  }
437
 
438
- # Visuals
439
  original_pil = create_original_display(original_img, pred_label, confidence)
440
  gradcam_viz = create_gradcam_visualization(original_img, cam) if cam is not None else None
441
  overlay_viz = create_overlay_visualization(original_img, cam) if cam is not None else None
442
 
443
  interpretation = create_interpretation(pred_label, confidence, results, audience=audience)
444
-
445
- snapshot = f"**{pred_label}** · {confidence:.1f}% confidence • Sum of probabilities: {prob_sum:.3f}"
446
 
447
  return results, original_pil, gradcam_viz, overlay_viz, interpretation, snapshot
448
 
449
-
450
  # ============================================================================
451
  # WOW UI / UX – Gradio App
452
  # ============================================================================
@@ -595,8 +599,7 @@ with gr.Blocks(css=custom_css, theme=theme) as demo:
595
  <div class="hero-title">🫁 AST Chest X-Ray Lab</div>
596
  <div class="hero-subtitle">
597
  Multi-class chest X-ray analysis with <b>Explainable AI</b> and
598
- <b>Adaptive Sparse Training</b>.
599
- Designed for TB, Pneumonia, COVID-19 and Normal scans.
600
  </div>
601
  <div class="hero-chip-row">
602
  <div class="hero-chip">
@@ -604,7 +607,7 @@ with gr.Blocks(css=custom_css, theme=theme) as demo:
604
  Live Inference
605
  </div>
606
  <div class="hero-chip">
607
- 4-class EfficientNet · ~{TOTAL_PARAMS_M:.1f}M params
608
  </div>
609
  <div class="hero-chip">
610
  95–97% validation accuracy · ~89% energy savings
@@ -620,8 +623,8 @@ with gr.Blocks(css=custom_css, theme=theme) as demo:
620
  <div class="stat-pill-value">{device.type.upper()}</div>
621
  </div>
622
  <div class="stat-pill">
623
- <div class="stat-pill-label">Model</div>
624
- <div class="stat-pill-value">EfficientNet-B0 · 4-way classifier</div>
625
  </div>
626
  </div>
627
  </div>
@@ -632,9 +635,7 @@ with gr.Blocks(css=custom_css, theme=theme) as demo:
632
  gr.Markdown(" ")
633
 
634
  with gr.Row(equal_height=True):
635
- # ----------------------------------
636
  # LEFT: INPUT PANEL
637
- # ----------------------------------
638
  with gr.Column(scale=1, elem_classes="glass-card"):
639
  gr.Markdown("### 1️⃣ Upload & Configure")
640
 
@@ -666,13 +667,11 @@ with gr.Blocks(css=custom_css, theme=theme) as demo:
666
 
667
  - Use frontal (PA/AP) chest X-rays in PNG / JPG format
668
  - This tool is best used as a **triage / screening assistant**
669
- - For noisy images or rotated scans, consider preprocessing before upload
670
  """
671
  )
672
 
673
- # ----------------------------------
674
  # RIGHT: RESULTS PANEL
675
- # ----------------------------------
676
  with gr.Column(scale=2, elem_classes="glass-card-light"):
677
  gr.Markdown("### 2️⃣ AI Dashboard")
678
 
@@ -712,15 +711,15 @@ with gr.Blocks(css=custom_css, theme=theme) as demo:
712
  ### 🧠 Model Card – AST Chest X-Ray
713
 
714
  - **Backbone**: EfficientNet-B0
715
- - **Task**: 4-way classification (Normal, Tuberculosis, Pneumonia, COVID-19)
716
  - **Optimization**: Sample-based Adaptive Sparse Training (AST)
717
  - **Energy Profile**: ~89% training energy reduction vs dense baseline
718
 
719
- **Design Goals**
720
 
721
  1. Provide **fast, explainable triage** support for TB & pneumonia
722
- 2. Maintain **high specificity**, especially differentiating TB from pneumonia
723
- 3. Be lightweight enough for **deployment in resource-constrained settings**
724
 
725
  > This model is a research prototype. Do **not** use it as a stand-alone clinical device.
726
  """
@@ -743,9 +742,7 @@ with gr.Blocks(css=custom_css, theme=theme) as demo:
743
  """
744
  )
745
 
746
- # ----------------------------------------------------------------------
747
  # Wiring
748
- # ----------------------------------------------------------------------
749
  analyze_btn.click(
750
  fn=predict_chest_xray,
751
  inputs=[image_input, show_gradcam, audience_select],
@@ -760,7 +757,14 @@ with gr.Blocks(css=custom_css, theme=theme) as demo:
760
  )
761
 
762
  clear_btn.click(
763
- fn=lambda: ({}, None, None, None, "Awaiting image upload…", "Awaiting image upload…"),
 
 
 
 
 
 
 
764
  inputs=None,
765
  outputs=[
766
  prob_output,
@@ -772,7 +776,7 @@ with gr.Blocks(css=custom_css, theme=theme) as demo:
772
  ],
773
  )
774
 
775
- # Example X-rays section (optional – remove if you don't have these paths)
776
  gr.Markdown("### 🔍 Try Example X-rays")
777
  gr.Examples(
778
  examples=[
 
1
  """
2
+ 🫁 AST Chest X-Ray Lab
3
+ Multi-Class Chest X-Ray Detection (Normal · TB · Pneumonia · COVID-19)
4
+ with Adaptive Sparse Training & Explainable AI (Grad-CAM)
 
 
 
5
  """
6
 
7
  import io
 
9
 
10
  import cv2
11
  import gradio as gr
12
+ import matplotlib
13
+ matplotlib.use("Agg") # safe backend for servers
14
  import matplotlib.pyplot as plt
15
  import numpy as np
16
  import torch
 
24
 
25
  device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
26
 
27
+ # EfficientNet backbone – we want 4 output classes
28
+ NUM_CLASSES = 4
29
  model = models.efficientnet_b0(weights=None)
30
+ model.classifier[1] = nn.Linear(model.classifier[1].in_features, NUM_CLASSES)
31
 
32
+ # We expect a 4-class EfficientNet checkpoint here
33
  checkpoint_candidates = [
34
+ "checkpoints/best.pt", # main location from your screenshot
35
+ "best.pt", # optional fallback in repo root
 
36
  ]
37
 
38
  MODEL_LOAD_INFO = ""
39
  loaded = False
40
 
41
+
42
+ def extract_state_dict(ckpt):
43
+ """
44
+ Handle both:
45
+ - plain state_dict (just parameter tensors)
46
+ - training checkpoints with keys like 'model_state_dict', 'state_dict', etc.
47
+ """
48
+ if isinstance(ckpt, dict):
49
+ for key in ["model_state_dict", "state_dict", "model"]:
50
+ if key in ckpt and isinstance(ckpt[key], dict):
51
+ return ckpt[key]
52
+ return ckpt # already a raw state dict
53
+
54
+
55
  for ckpt_path in checkpoint_candidates:
56
  if Path(ckpt_path).is_file():
57
  try:
58
  print(f"🔍 Trying to load weights from: {ckpt_path}")
59
+ raw_ckpt = torch.load(ckpt_path, map_location=device)
60
+ state_dict = extract_state_dict(raw_ckpt)
61
+
62
+ # Check classifier size to ensure it's truly 4-class
63
+ if "classifier.1.weight" in state_dict:
64
+ out_features = state_dict["classifier.1.weight"].shape[0]
65
+ if out_features != NUM_CLASSES:
66
+ raise ValueError(
67
+ f"Checkpoint at {ckpt_path} has {out_features} output "
68
+ f"classes, but this app expects {NUM_CLASSES}."
69
+ )
70
+
71
+ # Load strict – we want the full EfficientNet weights
72
+ model.load_state_dict(state_dict, strict=True)
73
+
74
+ MODEL_LOAD_INFO = (
75
+ f"✅ Model loaded from **{ckpt_path}** on **{device.type.upper()}**."
76
+ )
77
  loaded = True
78
  break
79
  except Exception as e:
80
+ print(f"⚠️ Found {ckpt_path} but failed to load model_state_dict: {e}")
81
 
82
  if not loaded:
83
  raise RuntimeError(
84
+ "Model file not found or could not be loaded.\n"
85
+ "Expected a 4-class EfficientNet checkpoint at 'checkpoints/best.pt' "
86
+ "or 'best.pt' that was saved with model.state_dict().\n"
87
+ "If you saved a training checkpoint, make sure it has a "
88
+ "'model_state_dict' key with the 4-class EfficientNet weights."
89
  )
90
 
91
  model = model.to(device)
 
100
 
101
  CLASSES = ["Normal", "Tuberculosis", "Pneumonia", "COVID-19"]
102
  CLASS_COLORS = {
103
+ "Normal": "#22c55e", # Green
104
+ "Tuberculosis": "#ef4444", # Red
105
+ "Pneumonia": "#f97316", # Orange
106
+ "COVID-19": "#a855f7", # Purple
107
  }
108
 
109
  transform = transforms.Compose(
 
238
  plt.tight_layout()
239
  return _figure_to_pil()
240
 
 
241
  # ============================================================================
242
  # Interpretation
243
  # ============================================================================
 
267
  ---
268
  """
269
 
 
270
  if pred_label == "Tuberculosis":
271
  if confidence >= 85:
272
  interpretation += """
 
274
 
275
  The model has detected features strongly suggestive of **pulmonary tuberculosis**.
276
 
277
+ **Suggested Clinical Pathway**
278
+ 1. Immediate review by a clinician or chest physician
279
+ 2. Sputum testing (AFB smear, GeneXpert MTB/RIF, or TB-PCR)
280
+ 3. Correlate with symptoms: chronic cough, weight loss, night sweats, fever, hemoptysis
281
+ 4. Consider CT or further imaging if uncertainty remains
282
+ 5. Infection control and contact tracing if TB is confirmed
 
 
 
 
 
 
283
  """
284
  else:
285
  interpretation += """
 
287
 
288
  The scan shows features that **could** be compatible with tuberculosis, but confidence is moderate.
289
 
290
+ - Correlate with symptoms and risk factors
291
+ - Consider sputum testing where suspicion is non-trivial
292
+ - Follow-up imaging as clinically indicated
 
293
  """
294
 
295
  elif pred_label == "Pneumonia":
 
299
 
300
  The model has detected an opacity pattern consistent with **pneumonia**.
301
 
302
+ Typical clinical correlates:
303
+
304
  - Fever, productive cough
305
  - Shortness of breath
306
  - Pleuritic chest pain
307
 
308
+ Use alongside clinical exam, labs, and local treatment guidelines.
 
 
 
309
  """
310
  else:
311
  interpretation += """
 
313
 
314
  Findings may be compatible with pneumonia, but alternative explanations exist.
315
 
316
+ - Check vital signs and auscultation
317
+ - Labs (WBC, CRP, cultures) may be useful
318
+ - Consider watchful follow-up or repeat imaging
 
319
  """
320
 
321
  elif pred_label == "COVID-19":
 
325
 
326
  Distribution and appearance of opacities are compatible with **COVID-19 pneumonia**.
327
 
328
+ ⚠️ Imaging alone is **not diagnostic**.
329
+
330
+ - Confirm with RT-PCR or validated antigen testing
331
+ - Follow local isolation and infection-control policies
332
+ - Monitor SpO₂ and respiratory status; escalate care if deterioration occurs
 
 
 
 
 
 
333
  """
334
  else:
335
  interpretation += """
336
  ### 🦠 COVID-19 Pattern – Possible
337
 
338
+ Some features may overlap with COVID-19, but there is substantial uncertainty.
339
 
340
+ - Testing (RT-PCR / antigen) is essential
341
+ - Integrate exposure history and symptoms
 
342
  """
343
 
344
  else: # Normal
 
346
  interpretation += """
347
  ### ✅ No Major Abnormality Detected
348
 
349
+ The model did **not** detect strong features of TB, pneumonia, or COVID-19.
350
+
351
+ Important caveats:
352
 
 
353
  - Early disease or small lesions may be missed
354
  - Non-infective conditions (e.g., cancer, ILD) are **not** specifically evaluated
355
+ - Persistent symptoms still warrant clinical review
356
  """
357
  else:
358
  interpretation += """
 
360
 
361
  The scan leans towards **normal**, but the model is not highly confident.
362
 
363
+ - Consider follow-up or additional tests if symptoms persist
 
 
364
  """
365
 
 
366
  interpretation += """
367
  ---
368
  ## ⚠️ CRITICAL MEDICAL DISCLAIMER
369
 
370
  - This AI model is a **screening / decision-support tool only**
371
+ - It is **not FDA-approved** and must **not** be used as a stand-alone diagnostic device
372
  - Always integrate:
373
  - Clinical history and examination
374
+ - Laboratory tests (sputum, PCR, cultures, etc.)
375
  - Expert radiologist review
376
 
377
+ **Gold Standards**
378
+
379
  - TB: Sputum AFB / culture, GeneXpert MTB/RIF, TB-PCR
380
  - Pneumonia: Clinical diagnosis + labs / microbiology
381
  - COVID-19: RT-PCR or validated antigen tests
382
 
383
  When in doubt, consult a qualified healthcare professional.
 
 
 
384
  ---
385
  🫁 **Powered by Adaptive Sparse Training (AST)**
386
+ Energy-efficient deep learning – designed to make chest X-ray screening more accessible.
387
+
388
+ **Links**
389
 
 
390
  - GitHub: https://github.com/oluwafemidiakhoa/Tuberculosis
391
  - Hugging Face Space: https://huggingface.co/spaces/mgbam/Tuberculosis
392
  """
393
  return interpretation
394
 
 
395
  # ============================================================================
396
  # Prediction Pipeline
397
  # ============================================================================
 
420
  original_img = image.copy()
421
  input_tensor = transform(image).unsqueeze(0).to(device)
422
 
 
423
  with torch.set_grad_enabled(show_gradcam):
424
  if show_gradcam:
425
  cam, output = grad_cam.generate(input_tensor)
 
442
  for i in range(len(CLASSES))
443
  }
444
 
 
445
  original_pil = create_original_display(original_img, pred_label, confidence)
446
  gradcam_viz = create_gradcam_visualization(original_img, cam) if cam is not None else None
447
  overlay_viz = create_overlay_visualization(original_img, cam) if cam is not None else None
448
 
449
  interpretation = create_interpretation(pred_label, confidence, results, audience=audience)
450
+ snapshot = f"**{pred_label}** · {confidence:.1f}% confidence • Prob. sum: {prob_sum:.3f}"
 
451
 
452
  return results, original_pil, gradcam_viz, overlay_viz, interpretation, snapshot
453
 
 
454
  # ============================================================================
455
  # WOW UI / UX – Gradio App
456
  # ============================================================================
 
599
  <div class="hero-title">🫁 AST Chest X-Ray Lab</div>
600
  <div class="hero-subtitle">
601
  Multi-class chest X-ray analysis with <b>Explainable AI</b> and
602
+ <b>Adaptive Sparse Training</b> – Normal · Tuberculosis · Pneumonia · COVID-19.
 
603
  </div>
604
  <div class="hero-chip-row">
605
  <div class="hero-chip">
 
607
  Live Inference
608
  </div>
609
  <div class="hero-chip">
610
+ EfficientNet-B0 · ~{TOTAL_PARAMS_M:.1f}M params
611
  </div>
612
  <div class="hero-chip">
613
  95–97% validation accuracy · ~89% energy savings
 
623
  <div class="stat-pill-value">{device.type.upper()}</div>
624
  </div>
625
  <div class="stat-pill">
626
+ <div class="stat-pill-label">Task</div>
627
+ <div class="stat-pill-value">Normal · TB · Pneumonia · COVID-19</div>
628
  </div>
629
  </div>
630
  </div>
 
635
  gr.Markdown(" ")
636
 
637
  with gr.Row(equal_height=True):
 
638
  # LEFT: INPUT PANEL
 
639
  with gr.Column(scale=1, elem_classes="glass-card"):
640
  gr.Markdown("### 1️⃣ Upload & Configure")
641
 
 
667
 
668
  - Use frontal (PA/AP) chest X-rays in PNG / JPG format
669
  - This tool is best used as a **triage / screening assistant**
670
+ - For noisy or rotated images, consider preprocessing before upload
671
  """
672
  )
673
 
 
674
  # RIGHT: RESULTS PANEL
 
675
  with gr.Column(scale=2, elem_classes="glass-card-light"):
676
  gr.Markdown("### 2️⃣ AI Dashboard")
677
 
 
711
  ### 🧠 Model Card – AST Chest X-Ray
712
 
713
  - **Backbone**: EfficientNet-B0
714
+ - **Classes**: Normal, Tuberculosis, Pneumonia, COVID-19
715
  - **Optimization**: Sample-based Adaptive Sparse Training (AST)
716
  - **Energy Profile**: ~89% training energy reduction vs dense baseline
717
 
718
+ **Goals**
719
 
720
  1. Provide **fast, explainable triage** support for TB & pneumonia
721
+ 2. Maintain high specificity, especially for TB vs pneumonia
722
+ 3. Be lightweight enough for deployment in **resource-constrained settings**
723
 
724
  > This model is a research prototype. Do **not** use it as a stand-alone clinical device.
725
  """
 
742
  """
743
  )
744
 
 
745
  # Wiring
 
746
  analyze_btn.click(
747
  fn=predict_chest_xray,
748
  inputs=[image_input, show_gradcam, audience_select],
 
757
  )
758
 
759
  clear_btn.click(
760
+ fn=lambda: (
761
+ {},
762
+ None,
763
+ None,
764
+ None,
765
+ "Awaiting image upload…",
766
+ "Awaiting image upload…",
767
+ ),
768
  inputs=None,
769
  outputs=[
770
  prob_output,
 
776
  ],
777
  )
778
 
779
+ # Example X-rays (optional – comment out if you don't have these files)
780
  gr.Markdown("### 🔍 Try Example X-rays")
781
  gr.Examples(
782
  examples=[