JohanBeytell commited on
Commit
df2fc25
ยท
verified ยท
1 Parent(s): 3449ee0

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +238 -0
app.py ADDED
@@ -0,0 +1,238 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import torch
3
+ import torch.nn as nn
4
+ import torch.nn.functional as F
5
+ from torchvision import models, transforms
6
+ import gradio as gr
7
+ import numpy as np
8
+ import cv2
9
+ from PIL import Image
10
+
11
+ # ==============================================================================
12
+ # 1. CORE CONFIGURATION & MODEL REGISTRY
13
+ # ==============================================================================
14
+ IMG_SIZE = 128
15
+ LABELS = [
16
+ "Adenocarcinoma",
17
+ "Large Cell Carcinoma",
18
+ "Normal Tissue Profile",
19
+ "Squamous Cell Carcinoma"
20
+ ]
21
+
22
+ class MedicalCLAHEEqualization(object):
23
+ """
24
+ Applies Contrast Limited Adaptive Histogram Equalization to neutralize
25
+ scanner baseline variations, matching the front-end JS functionality exactly.
26
+ """
27
+ def __call__(self, img):
28
+ img_np = np.array(img)
29
+ gray = cv2.cvtColor(img_np, cv2.COLOR_RGB2GRAY)
30
+ clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8, 8))
31
+ equalized = clahe.apply(gray)
32
+ return Image.fromarray(cv2.cvtColor(equalized, cv2.COLOR_GRAY2RGB))
33
+
34
+ # Re-establishing the exact validation transforms utilized during training
35
+ eval_transforms = transforms.Compose([
36
+ MedicalCLAHEEqualization(),
37
+ transforms.Resize((IMG_SIZE, IMG_SIZE)),
38
+ transforms.ToTensor(),
39
+ transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
40
+ ])
41
+
42
+ device = torch.device("cpu") # Hugging Face spaces run CPU pipelines by default
43
+
44
+ def load_bioset_cccm():
45
+ """
46
+ Constructs the underlying EfficientNet-B0 blueprint structure
47
+ and binds the trained Bioset CCCM parameter weights.
48
+ """
49
+ model = models.efficientnet_b0(weights=None)
50
+ in_features = model.classifier[1].in_features
51
+ model.classifier = nn.Sequential(
52
+ nn.Dropout(p=0.4, inplace=True),
53
+ nn.Linear(in_features, len(LABELS))
54
+ )
55
+
56
+ # Cascade verification checks to capture either weight file formatting variant
57
+ if os.path.exists('chestnet_efficientnet_weights.pth'):
58
+ model.load_state_dict(torch.load('chestnet_efficientnet_weights.pth', map_location=device))
59
+ elif os.path.exists('chestnet_efficientnet_full.pth'):
60
+ checkpoint = torch.load('chestnet_efficientnet_full.pth', map_location=device)
61
+ if hasattr(checkpoint, 'state_dict'):
62
+ model.load_state_dict(checkpoint.state_dict())
63
+ else:
64
+ model = checkpoint
65
+
66
+ model.eval()
67
+ return model
68
+
69
+ # Initialize the clinical architecture instance
70
+ model = load_bioset_cccm()
71
+
72
+ # ==============================================================================
73
+ # 2. RUNTIME INFERENCE FLOW PIPELINE
74
+ # ==============================================================================
75
+ def predict_chest_slice(input_image):
76
+ if input_image is None:
77
+ return "### Awaiting Ingestion Stream Vector...", {}
78
+
79
+ # Convert numpy array to PIL Image object context
80
+ pil_img = Image.fromarray(input_image.astype('uint8'), 'RGB')
81
+ tensor_input = eval_transforms(pil_img).unsqueeze(0).to(device)
82
+
83
+ with torch.no_grad():
84
+ logits = model(tensor_input)
85
+ probabilities = F.softmax(logits, dim=1).squeeze(0).numpy()
86
+
87
+ # Standardize result vectors into rank-ordered structures
88
+ indexed_results = [
89
+ {"label": LABELS[i], "prob": float(probabilities[i])}
90
+ for i in range(len(LABELS))
91
+ ]
92
+ indexed_results.sort(key=lambda x: x["prob"], reverse=True)
93
+
94
+ # Compile premium Markdown summary readout for the UI header
95
+ top_winner = indexed_results[0]
96
+ output_summary = f"### Primary Classification: <span style='color:#22d3ee;font-weight:900;'>{top_winner['label']}</span> ({top_winner['prob']*100:.1f}%)"
97
+
98
+ # Return Top 3 classes for Gradio's responsive classification list
99
+ gradio_label_output = {item["label"]: item["prob"] for item in indexed_results[:3]}
100
+
101
+ return output_summary, gradio_label_output
102
+
103
+ # ==============================================================================
104
+ # 3. PREMIUM UI THEMING (DARK MODE SAAS AESTHETIC)
105
+ # ==============================================================================
106
+ saas_theme = gr.themes.Default(
107
+ primary_hue="cyan",
108
+ secondary_hue="slate",
109
+ neutral_hue="slate",
110
+ ).set(
111
+ body_background_fill="#030712",
112
+ body_background_fill_dark="#030712",
113
+ block_background_fill="#0f172a",
114
+ block_background_fill_dark="#0f172a",
115
+ block_border_color="#1e293b",
116
+ block_border_width="1px",
117
+ panel_background_fill="#090d16",
118
+ container_radius="16px",
119
+ button_primary_background_fill="#06b6d4",
120
+ button_primary_text_color="#ffffff"
121
+ )
122
+
123
+ # ==============================================================================
124
+ # 4. COMPACT APP SURFACE DESIGN Layout
125
+ # ==============================================================================
126
+ with gr.Blocks(theme=saas_theme, title="Bioset CCCM Engine Deck") as demo:
127
+
128
+ # Top Identity Brand Layer
129
+ gr.Markdown(
130
+ """
131
+ # <span style='color:#22d3ee;font-weight:900;letter-spacing:-0.025em;'>Bioset CCCM</span>
132
+ ### Part of the **Bioset Model Collection** by **Infinitode** โ€ข AI + Biology Initiative
133
+ ---
134
+ """
135
+ )
136
+
137
+ # Official Bioset Core Clinical Screening and Regulatory Disclaimers
138
+ gr.Markdown(
139
+ """
140
+ <div style="background-color: rgba(239, 68, 68, 0.04); border: 1px solid rgba(239, 68, 68, 0.12); padding: 16px; border-radius: 14px; color: #fca5a5; font-size: 13px; line-height: 1.6; margin-bottom: 24px;">
141
+ <strong style="color: #fca5a5; text-transform: uppercase; letter-spacing: 0.05em; display: block; margin-bottom: 4px;">โš ๏ธ Bioset Model Registry Regulatory Notice</strong>
142
+ The Chest Cancer Classification Model (CCCM) is a regularized exploratory prototype engineered specifically for research evaluations inside computational biology domains. This architecture does not carry clinical validation certificates, is not cleared by the FDA or equivalent global healthcare oversight entities, and must never be deployed or relied upon as a primary proxy tool for human disease screening or medical case management.
143
+ </div>
144
+ """
145
+ )
146
+
147
+ # Interactive Processing Grid Split
148
+ with gr.Row():
149
+ # Input Workspace Panel Area
150
+ with gr.Column(scale=5):
151
+ gr.Markdown("#### ๐Ÿ“ฅ Tissue Ingestion & Alignment")
152
+
153
+ input_image = gr.Image(
154
+ label="Axial Pulmonary CT Slice Matrix Input",
155
+ sources=["upload", "clipboard", "webcam"],
156
+ type="numpy",
157
+ tool="crop" # Enables high-fidelity crop, pan, and alignment controls on mobile + web
158
+ )
159
+
160
+ with gr.Row():
161
+ clear_btn = gr.Button("Clear Node", variant="secondary")
162
+ submit_btn = gr.Button("Evaluate Matrix Data", variant="primary")
163
+
164
+ # Ranked Diagnostics Output Panel Area
165
+ with gr.Column(scale=7):
166
+ gr.Markdown("#### ๐Ÿ“Š Differential Analytics Report")
167
+
168
+ output_text = gr.Markdown("### Awaiting Ingestion Stream Vector...")
169
+
170
+ output_labels = gr.Label(
171
+ num_top_classes=3,
172
+ label="Rank-Ordered Softmax Probabilities"
173
+ )
174
+
175
+ gr.Markdown(
176
+ """
177
+ <div style="background-color: rgba(15, 23, 42, 0.4); border: 1px solid #1e293b; padding: 12px; border-radius: 10px; font-size: 11px; color: #94a3b8; line-height: 1.5; margin-top: 12px;">
178
+ <strong>Pipeline Protocol:</strong> Input slices undergo local adaptive luminance leveling prior to network calculations. This mitigates hardware-specific baseline variance, focusing the model's extraction nodes entirely on tumor texture shapes.
179
+ </div>
180
+ """
181
+ )
182
+
183
+ # Secondary Data Deck Layer: Compact Validation Profile Results
184
+ with gr.Accordion("๐Ÿ“‹ Model Profile & Performance Metrics Summary", open=True):
185
+ gr.Markdown(
186
+ """
187
+ ### Bioset Model Registry Evaluation Data (CCCM v1.4)
188
+ The following evaluation benchmarks were captured using an independent test set distribution following shape-equalization optimization:
189
+
190
+ <table style="width:100%; border-collapse: collapse; margin-top: 10px; font-size: 13px; color: #cbd5e1;">
191
+ <thead>
192
+ <tr style="border-b: 1px solid #334155; text-align: left; color: #94a3b8;">
193
+ <th style="padding: 10px 8px;">Target Validation Index</th>
194
+ <th style="padding: 10px 8px;">Metric Distribution</th>
195
+ <th style="padding: 10px 8px;">Infrastructure Scope</th>
196
+ </tr>
197
+ </thead>
198
+ <tbody>
199
+ <tr style="border-bottom: 1px solid #1e293b;">
200
+ <td style="padding: 10px 8px; font-weight: bold; color: #10b981;">Optimal Validation Accuracy</td>
201
+ <td style="padding: 10px 8px; font-family: monospace; font-weight: bold; color: #10b981;">93.06%</td>
202
+ <td style="padding: 10px 8px; color: #64748b;">Peak state convergence score</td>
203
+ </tr>
204
+ <tr style="border-bottom: 1px solid #1e293b;">
205
+ <td style="padding: 10px 8px; font-weight: bold;">Validation Loss Baseline</td>
206
+ <td style="padding: 10px 8px; font-family: monospace; color: #f43f5e;">0.1705</td>
207
+ <td style="padding: 10px 8px; color: #64748b;">Cross-Entropy loss ceiling</td>
208
+ </tr>
209
+ <tr style="border-bottom: 1px solid #1e293b;">
210
+ <td style="padding: 10px 8px; font-weight: bold; color: #22d3ee;">Highest Sample Confidence Target</td>
211
+ <td style="padding: 10px 8px; font-family: monospace; font-weight: bold; color: #22d3ee;">98.7%</td>
212
+ <td style="padding: 10px 8px; color: #64748b;">Verified on true positive test splits</td>
213
+ </tr>
214
+ <tr>
215
+ <td style="padding: 10px 8px; font-weight: bold;">Model footprint Volumetrics</td>
216
+ <td style="padding: 10px 8px; font-family: monospace;">16.6 MB</td>
217
+ <td style="padding: 10px 8px; color: #64748b;">Unified monolithic serialization array</td>
218
+ </tr>
219
+ </tbody>
220
+ </table>
221
+ """
222
+ )
223
+
224
+ # Binding actionable runtime function sequences
225
+ submit_btn.click(
226
+ fn=predict_chest_slice,
227
+ inputs=[input_image],
228
+ outputs=[output_text, output_labels]
229
+ )
230
+
231
+ clear_btn.click(
232
+ fn=lambda: ("### Awaiting Ingestion Stream Vector...", {}),
233
+ inputs=None,
234
+ outputs=[output_text, output_labels]
235
+ )
236
+
237
+ if __name__ == "__main__":
238
+ demo.launch()