-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathexplainer.py
More file actions
127 lines (101 loc) · 4.44 KB
/
Copy pathexplainer.py
File metadata and controls
127 lines (101 loc) · 4.44 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
"""
explainer.py — Medical Image Explainability Agent.
Generates structured, evidence-based explanations for model classifications
following the Grounding Protocol: Observation → Tool Evidence → Explanation.
"""
from model import CLASS_NAMES
# Pathology-specific explanation templates
PATHOLOGY_CONTEXT = {
"Pneumonia": {
"features": "increased density, opacification, or consolidation patterns",
"typical_regions": "lower lobes (particularly right lower lobe)",
"description": (
"The detected opacification pattern in this region is consistent with "
"alveolar filling or inflammatory infiltrate, which are characteristic "
"radiographic features the model has learned to associate with pneumonia."
),
},
"Tuberculosis": {
"features": "opacities, cavitary lesions, or fibrotic changes",
"typical_regions": "upper lobes (particularly right upper lobe)",
"description": (
"The activation pattern in this region suggests the presence of opacities "
"or cavitary changes, which are hallmark radiographic findings the model "
"has learned to associate with tuberculosis."
),
},
"Normal": {
"features": "clear lung fields with no focal opacities or consolidation",
"typical_regions": "distributed across bilateral lung fields",
"description": (
"The diffuse, low-intensity activation pattern indicates the model did not "
"detect significant focal abnormalities, consistent with normal lung parenchyma."
),
},
}
def generate_explanation(result: dict) -> str:
"""
Generate a structured explanation following the Grounding Protocol.
Args:
result: Dictionary with keys:
- prediction: str (class name)
- confidence: float
- anatomical_focus: str
- heatmap_intensity: str
- methodology: str
- all_probabilities: dict
Returns:
Formatted explanation string.
"""
prediction = result["prediction"]
confidence = result["confidence"]
anatomical_focus = result["anatomical_focus"]
heatmap_intensity = result["heatmap_intensity"]
methodology = result["methodology"]
all_probs = result["all_probabilities"]
ctx = PATHOLOGY_CONTEXT.get(prediction, PATHOLOGY_CONTEXT["Normal"])
# Build probability breakdown
prob_lines = "\n".join(
f" • {name}: {prob * 100:.1f}%" for name, prob in all_probs.items()
)
explanation = f"""## Observation
The model identifies findings consistent with **{prediction}** with a confidence of **{confidence * 100:.1f}%**.
**Class Probabilities:**
{prob_lines}
---
## Tool Evidence
**Methodology:** {methodology}
Grad-CAM computes neuron importance weights by back-propagating gradients to the \
final convolutional layer, highlighting the specific pixels that most influenced the \
model's decision. The resulting heatmap is a ReLU-activated weighted combination of \
forward activation maps.
**Activation Analysis:**
• **Anatomical Focus:** {anatomical_focus}
• **Heatmap Intensity:** {heatmap_intensity}
• **Target Region:** The maximum Grad-CAM activation is localized in the **{anatomical_focus}**
---
## Explanation
{ctx['description']}
**Key Findings:**
• The model detected **{ctx['features']}** in the **{anatomical_focus}**
• The **{heatmap_intensity.lower()}** activation intensity indicates a \
{"strong" if heatmap_intensity == "High" else "moderate" if heatmap_intensity == "Medium" else "subtle"} \
signal from the learned feature detectors in this region
• For {prediction.lower()}, the model's training data typically shows involvement in the \
**{ctx['typical_regions']}**
---
> **Note:** This analysis is limited to visual evidence within the provided X-ray image \
and the model's learned feature representations. No clinical history, symptoms, or \
demographic information has been inferred."""
return explanation
def generate_metadata_display(result: dict) -> str:
"""Format the result dictionary for display in the metadata panel."""
import json
display_dict = {
"prediction": result["prediction"],
"confidence": result["confidence"],
"anatomical_focus": result["anatomical_focus"],
"heatmap_intensity": result["heatmap_intensity"],
"methodology": result["methodology"],
}
return json.dumps(display_dict, indent=2)