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

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +57 -23
app.py CHANGED
@@ -6,8 +6,8 @@ import torch.nn as nn
6
  import numpy as np
7
 
8
  app = FastAPI(
9
- title="NeuroHealth EEG API",
10
- version="2.0"
11
  )
12
 
13
  DEVICE = "cuda" if torch.cuda.is_available() else "cpu"
@@ -20,14 +20,42 @@ AD_CLASSES = ["Alzheimer", "FTD", "Control"]
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):
@@ -55,42 +83,48 @@ class EEG_CNN(nn.Module):
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
  }
@@ -102,20 +136,20 @@ def predict(model, features, classes):
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)
 
6
  import numpy as np
7
 
8
  app = FastAPI(
9
+ title="NeuroHealth Unified EEG API",
10
+ version="3.0"
11
  )
12
 
13
  DEVICE = "cuda" if torch.cuda.is_available() else "cpu"
 
20
  PD_CLASSES = ["Parkinson", "Control"]
21
 
22
  # =========================================================
23
+ # INPUT SCHEMA
24
  # =========================================================
25
 
26
  class EEGRequest(BaseModel):
27
  features: list
28
 
29
  # =========================================================
30
+ # MLP MODEL (MATCHES YOUR .pth FILES)
31
+ # =========================================================
32
+
33
+ class EEG_MLP(nn.Module):
34
+ def __init__(self, input_dim, output_dim):
35
+ super().__init__()
36
+
37
+ self.net = nn.Sequential(
38
+ nn.Linear(input_dim, 512),
39
+ nn.BatchNorm1d(512),
40
+ nn.ReLU(),
41
+ nn.Dropout(0.3),
42
+
43
+ nn.Linear(512, 256),
44
+ nn.BatchNorm1d(256),
45
+ nn.ReLU(),
46
+ nn.Dropout(0.3),
47
+
48
+ nn.Linear(256, 128),
49
+ nn.ReLU(),
50
+
51
+ nn.Linear(128, output_dim)
52
+ )
53
+
54
+ def forward(self, x):
55
+ return self.net(x)
56
+
57
+ # =========================================================
58
+ # OPTIONAL CNN (ONLY IF YOU TRAIN TRUE EEG CNN LATER)
59
  # =========================================================
60
 
61
  class EEG_CNN(nn.Module):
 
83
  return self.fc(x)
84
 
85
  # =========================================================
86
+ # LOAD MODELS (BASED ON YOUR REAL FILES)
87
  # =========================================================
88
 
89
+ # THESE ARE MLP MODELS (CONFIRMED BY "net.*" KEYS)
90
+
91
+ ad_model = EEG_MLP(95, 3).to(DEVICE)
92
  ad_model.load_state_dict(torch.load("AD_eeg_cnn.pth", map_location=DEVICE))
93
  ad_model.eval()
94
 
95
+ pd_model = EEG_MLP(95, 2).to(DEVICE)
96
  pd_model.load_state_dict(torch.load("PD_eeg_cnn.pth", map_location=DEVICE))
97
  pd_model.eval()
98
 
99
+ print("All models loaded successfully")
100
 
101
  # =========================================================
102
+ # SAFE PREDICTION ENGINE
103
  # =========================================================
104
 
105
+ def predict(model, features, classes, model_type="mlp"):
106
  x = torch.tensor(features, dtype=torch.float32)
107
 
108
  if x.numel() != 95:
109
  raise ValueError("Expected exactly 95 features")
110
 
111
+ # MLP MODE: flat input
112
+ if model_type == "mlp":
113
+ x = x.unsqueeze(0).to(DEVICE)
114
+
115
+ # ✔ CNN MODE (future use only)
116
+ elif model_type == "cnn":
117
+ x = x.view(19, 5).unsqueeze(0).to(DEVICE)
118
 
119
  with torch.no_grad():
120
+ out = model(x)
121
+ probs = torch.softmax(out, dim=1).cpu().numpy()[0]
122
 
123
  pred = int(np.argmax(probs))
 
124
 
125
  return {
126
  "prediction": classes[pred],
127
+ "confidence": float(probs[pred]),
128
  "probabilities": {
129
  classes[i]: float(probs[i]) for i in range(len(classes))
130
  }
 
136
 
137
  @app.get("/")
138
  def home():
139
+ return {"message": "NeuroHealth Unified API Running"}
140
 
141
  # =========================================================
142
+ # AD PREDICTION
143
  # =========================================================
144
 
145
  @app.post("/predict/ad")
146
+ def predict_ad(req: EEGRequest):
147
+ return predict(ad_model, req.features, AD_CLASSES, "mlp")
148
 
149
  # =========================================================
150
+ # PD PREDICTION
151
  # =========================================================
152
 
153
  @app.post("/predict/pd")
154
+ def predict_pd(req: EEGRequest):
155
+ return predict(pd_model, req.features, PD_CLASSES, "mlp")