Mikecode123 commited on
Commit
ee50a41
·
verified ·
1 Parent(s): 2dfe2a7

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +38 -115
app.py CHANGED
@@ -6,7 +6,7 @@ import torch.nn as nn
6
  import numpy as np
7
 
8
  app = FastAPI(
9
- title="NeuroHealth Multi-Model EEG API",
10
  version="2.0"
11
  )
12
 
@@ -20,53 +20,16 @@ AD_CLASSES = ["Alzheimer", "FTD", "Control"]
20
  PD_CLASSES = ["Parkinson", "Control"]
21
 
22
  # =========================================================
23
- # INPUT
24
  # =========================================================
25
 
26
  class EEGRequest(BaseModel):
27
  features: list
28
 
29
  # =========================================================
30
- # DEVICE
31
  # =========================================================
32
 
33
- def to_tensor(features):
34
- return torch.tensor(features, dtype=torch.float32)
35
-
36
- # =========================================================
37
- # ===================== MODELS ============================
38
- # =========================================================
39
-
40
- # ---------------- MLP (CSV MODELS) ----------------------
41
-
42
- INPUT_DIM = 95
43
-
44
- class MLP(nn.Module):
45
- def __init__(self, output_dim):
46
- super().__init__()
47
- self.net = nn.Sequential(
48
- nn.Linear(INPUT_DIM, 512),
49
- nn.BatchNorm1d(512),
50
- nn.GELU(),
51
- nn.Dropout(0.3),
52
-
53
- nn.Linear(512, 256),
54
- nn.BatchNorm1d(256),
55
- nn.GELU(),
56
- nn.Dropout(0.3),
57
-
58
- nn.Linear(256, 128),
59
- nn.GELU(),
60
-
61
- nn.Linear(128, output_dim)
62
- )
63
-
64
- def forward(self, x):
65
- return self.net(x)
66
-
67
-
68
- # ---------------- CNN (EEG MODELS) ----------------------
69
-
70
  class EEG_CNN(nn.Module):
71
  def __init__(self, output_dim):
72
  super().__init__()
@@ -92,48 +55,46 @@ class EEG_CNN(nn.Module):
92
  return self.fc(x)
93
 
94
  # =========================================================
95
- # LOAD ALL MODELS
96
  # =========================================================
97
 
98
- # -------- AD MODELS --------
99
- ad_mlp = MLP(3).to(DEVICE)
100
- ad_mlp.load_state_dict(torch.load("AD_MLP.pt", map_location=DEVICE))
101
- ad_mlp.eval()
102
-
103
- ad_cnn = EEG_CNN(3).to(DEVICE)
104
- ad_cnn.load_state_dict(torch.load("AD_eeg_cnn.pth", map_location=DEVICE))
105
- ad_cnn.eval()
106
-
107
- # -------- PD MODELS --------
108
- pd_mlp = MLP(2).to(DEVICE)
109
- pd_mlp.load_state_dict(torch.load("PD_MLP.pt", map_location=DEVICE))
110
- pd_mlp.eval()
111
 
112
- pd_cnn = EEG_CNN(2).to(DEVICE)
113
- pd_cnn.load_state_dict(torch.load("PD_eeg_cnn.pth", map_location=DEVICE))
114
- pd_cnn.eval()
115
 
116
- print("All models loaded successfully")
117
 
118
  # =========================================================
119
- # PREDICTION ENGINE
120
  # =========================================================
121
 
122
- def predict(model, features, mode="mlp"):
123
- x = to_tensor(features)
124
 
125
- if mode == "mlp":
126
- x = x.unsqueeze(0).to(DEVICE)
127
 
128
- elif mode == "cnn":
129
- x = x.view(19, 5).unsqueeze(0).to(DEVICE)
130
 
131
  with torch.no_grad():
132
- out = model(x)
133
- probs = torch.softmax(out, dim=1).cpu().numpy()[0]
134
 
135
  pred = int(np.argmax(probs))
136
- return pred, float(probs[pred]), probs.tolist()
 
 
 
 
 
 
 
 
137
 
138
  # =========================================================
139
  # ROUTES
@@ -141,58 +102,20 @@ def predict(model, features, mode="mlp"):
141
 
142
  @app.get("/")
143
  def home():
144
- return {"message": "NeuroHealth Multi-Model API Running"}
145
 
146
  # =========================================================
147
- # AD ENDPOINTS
148
  # =========================================================
149
 
150
- @app.post("/predict/ad/mlp")
151
- def ad_mlp_predict(req: EEGRequest):
152
- p, c, prob = predict(ad_mlp, req.features, "mlp")
153
-
154
- return {
155
- "model": "AD_MLP",
156
- "prediction": AD_CLASSES[p],
157
- "confidence": c,
158
- "probabilities": dict(zip(AD_CLASSES, prob))
159
- }
160
-
161
-
162
- @app.post("/predict/ad/eeg")
163
- def ad_cnn_predict(req: EEGRequest):
164
- p, c, prob = predict(ad_cnn, req.features, "cnn")
165
-
166
- return {
167
- "model": "AD_EEG_CNN",
168
- "prediction": AD_CLASSES[p],
169
- "confidence": c,
170
- "probabilities": dict(zip(AD_CLASSES, prob))
171
- }
172
 
173
  # =========================================================
174
- # PD ENDPOINTS
175
  # =========================================================
176
 
177
- @app.post("/predict/pd/mlp")
178
- def pd_mlp_predict(req: EEGRequest):
179
- p, c, prob = predict(pd_mlp, req.features, "mlp")
180
-
181
- return {
182
- "model": "PD_MLP",
183
- "prediction": PD_CLASSES[p],
184
- "confidence": c,
185
- "probabilities": dict(zip(PD_CLASSES, prob))
186
- }
187
-
188
-
189
- @app.post("/predict/pd/eeg")
190
- def pd_cnn_predict(req: EEGRequest):
191
- p, c, prob = predict(pd_cnn, req.features, "cnn")
192
-
193
- return {
194
- "model": "PD_EEG_CNN",
195
- "prediction": PD_CLASSES[p],
196
- "confidence": c,
197
- "probabilities": dict(zip(PD_CLASSES, prob))
198
- }
 
6
  import numpy as np
7
 
8
  app = FastAPI(
9
+ title="NeuroHealth EEG API",
10
  version="2.0"
11
  )
12
 
 
20
  PD_CLASSES = ["Parkinson", "Control"]
21
 
22
  # =========================================================
23
+ # REQUEST SCHEMA
24
  # =========================================================
25
 
26
  class EEGRequest(BaseModel):
27
  features: list
28
 
29
  # =========================================================
30
+ # EEG CNN MODEL (MATCHES YOUR .pth FILES)
31
  # =========================================================
32
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
  class EEG_CNN(nn.Module):
34
  def __init__(self, output_dim):
35
  super().__init__()
 
55
  return self.fc(x)
56
 
57
  # =========================================================
58
+ # LOAD MODELS (CLEAN VERSION)
59
  # =========================================================
60
 
61
+ ad_model = EEG_CNN(3).to(DEVICE)
62
+ ad_model.load_state_dict(torch.load("AD_eeg_cnn.pth", map_location=DEVICE))
63
+ ad_model.eval()
 
 
 
 
 
 
 
 
 
 
64
 
65
+ pd_model = EEG_CNN(2).to(DEVICE)
66
+ pd_model.load_state_dict(torch.load("PD_eeg_cnn.pth", map_location=DEVICE))
67
+ pd_model.eval()
68
 
69
+ print("All EEG CNN models loaded successfully")
70
 
71
  # =========================================================
72
+ # CORE PREDICTION FUNCTION
73
  # =========================================================
74
 
75
+ def predict(model, features, classes):
76
+ x = torch.tensor(features, dtype=torch.float32)
77
 
78
+ if x.numel() != 95:
79
+ raise ValueError("Expected exactly 95 features")
80
 
81
+ # reshape EEG features → (19 channels × 5 timesteps)
82
+ x = x.view(19, 5).unsqueeze(0).to(DEVICE)
83
 
84
  with torch.no_grad():
85
+ outputs = model(x)
86
+ probs = torch.softmax(outputs, dim=1).cpu().numpy()[0]
87
 
88
  pred = int(np.argmax(probs))
89
+ confidence = float(probs[pred])
90
+
91
+ return {
92
+ "prediction": classes[pred],
93
+ "confidence": confidence,
94
+ "probabilities": {
95
+ classes[i]: float(probs[i]) for i in range(len(classes))
96
+ }
97
+ }
98
 
99
  # =========================================================
100
  # ROUTES
 
102
 
103
  @app.get("/")
104
  def home():
105
+ return {"message": "NeuroHealth EEG API Running"}
106
 
107
  # =========================================================
108
+ # AD ROUTE
109
  # =========================================================
110
 
111
+ @app.post("/predict/ad")
112
+ def predict_ad(request: EEGRequest):
113
+ return predict(ad_model, request.features, AD_CLASSES)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
114
 
115
  # =========================================================
116
+ # PD ROUTE
117
  # =========================================================
118
 
119
+ @app.post("/predict/pd")
120
+ def predict_pd(request: EEGRequest):
121
+ return predict(pd_model, request.features, PD_CLASSES)