Mikecode123 commited on
Commit
6fa7603
·
verified ·
1 Parent(s): bafa357

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +34 -69
app.py CHANGED
@@ -28,67 +28,63 @@ PD_CLASSES = [
28
  ]
29
 
30
  # =========================================================
31
- # MODELS
32
  # =========================================================
33
 
34
  INPUT_DIM = 95
35
 
36
  # =========================================================
37
- # MLP MODEL
38
  # =========================================================
39
 
40
- class MLP(nn.Module):
41
-
42
  def __init__(self, output_dim):
43
-
44
  super().__init__()
45
 
46
- self.network = nn.Sequential(
 
47
 
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.BatchNorm1d(128),
60
- nn.GELU(),
61
 
62
- nn.Linear(128, output_dim)
63
- )
64
 
65
  def forward(self, x):
 
 
 
 
 
 
66
 
67
- return self.network(x)
 
 
 
68
 
69
  # =========================================================
70
  # LOAD MODELS
71
  # =========================================================
72
 
73
- ad_mlp = MLP(3).to(DEVICE)
74
- pd_mlp = MLP(2).to(DEVICE)
75
 
76
- ad_mlp.load_state_dict(
77
- torch.load(
78
- "AD_MLP.pt",
79
- map_location=DEVICE
80
- )
81
  )
82
 
83
- pd_mlp.load_state_dict(
84
- torch.load(
85
- "PD_MLP.pt",
86
- map_location=DEVICE
87
- )
88
  )
89
 
90
- ad_mlp.eval()
91
- pd_mlp.eval()
92
 
93
  print("Models Loaded Successfully")
94
 
@@ -97,7 +93,6 @@ print("Models Loaded Successfully")
97
  # =========================================================
98
 
99
  class EEGRequest(BaseModel):
100
-
101
  features: list
102
 
103
  # =========================================================
@@ -105,23 +100,13 @@ class EEGRequest(BaseModel):
105
  # =========================================================
106
 
107
  def predict_model(model, features):
108
-
109
- x = torch.tensor(
110
- features,
111
- dtype=torch.float32
112
- ).unsqueeze(0).to(DEVICE)
113
 
114
  with torch.no_grad():
115
-
116
  outputs = model(x)
117
-
118
- probs = torch.softmax(
119
- outputs,
120
- dim=1
121
- ).cpu().numpy()[0]
122
 
123
  pred = int(np.argmax(probs))
124
-
125
  confidence = float(probs[pred])
126
 
127
  return pred, confidence, probs.tolist()
@@ -131,9 +116,7 @@ def predict_model(model, features):
131
  # =========================================================
132
 
133
  @app.get("/")
134
-
135
  def home():
136
-
137
  return {
138
  "message": "NeuroHealth EEG API Running"
139
  }
@@ -143,24 +126,15 @@ def home():
143
  # =========================================================
144
 
145
  @app.post("/predict/alzheimer")
146
-
147
  def predict_alzheimer(request: EEGRequest):
148
 
149
- pred, confidence, probs = predict_model(
150
- ad_mlp,
151
- request.features
152
- )
153
 
154
  return {
155
-
156
  "prediction": AD_CLASSES[pred],
157
-
158
  "confidence": confidence,
159
-
160
  "probabilities": {
161
-
162
  AD_CLASSES[i]: float(probs[i])
163
-
164
  for i in range(len(AD_CLASSES))
165
  }
166
  }
@@ -170,24 +144,15 @@ def predict_alzheimer(request: EEGRequest):
170
  # =========================================================
171
 
172
  @app.post("/predict/parkinson")
173
-
174
  def predict_parkinson(request: EEGRequest):
175
 
176
- pred, confidence, probs = predict_model(
177
- pd_mlp,
178
- request.features
179
- )
180
 
181
  return {
182
-
183
  "prediction": PD_CLASSES[pred],
184
-
185
  "confidence": confidence,
186
-
187
  "probabilities": {
188
-
189
  PD_CLASSES[i]: float(probs[i])
190
-
191
  for i in range(len(PD_CLASSES))
192
  }
193
  }
 
28
  ]
29
 
30
  # =========================================================
31
+ # CONFIG
32
  # =========================================================
33
 
34
  INPUT_DIM = 95
35
 
36
  # =========================================================
37
+ # CNN MODEL (MATCHES SAVED WEIGHTS)
38
  # =========================================================
39
 
40
+ class EEG_CNN(nn.Module):
 
41
  def __init__(self, output_dim):
 
42
  super().__init__()
43
 
44
+ self.conv1 = nn.Conv1d(1, 32, kernel_size=3, padding=1)
45
+ self.bn1 = nn.BatchNorm1d(32)
46
 
47
+ self.conv2 = nn.Conv1d(32, 64, kernel_size=3, padding=1)
48
+ self.bn2 = nn.BatchNorm1d(64)
 
 
49
 
50
+ self.conv3 = nn.Conv1d(64, 128, kernel_size=3, padding=1)
51
+ self.bn3 = nn.BatchNorm1d(128)
 
 
52
 
53
+ # Global pooling removes dependence on sequence length
54
+ self.pool = nn.AdaptiveAvgPool1d(1)
 
55
 
56
+ self.fc = nn.Linear(128, output_dim)
 
57
 
58
  def forward(self, x):
59
+ # x shape: (batch, features)
60
+ x = x.unsqueeze(1) # (batch, 1, 95)
61
+
62
+ x = torch.relu(self.bn1(self.conv1(x)))
63
+ x = torch.relu(self.bn2(self.conv2(x)))
64
+ x = torch.relu(self.bn3(self.conv3(x)))
65
 
66
+ x = self.pool(x) # (batch, 128, 1)
67
+ x = x.squeeze(-1) # (batch, 128)
68
+
69
+ return self.fc(x)
70
 
71
  # =========================================================
72
  # LOAD MODELS
73
  # =========================================================
74
 
75
+ ad_model = EEG_CNN(3).to(DEVICE)
76
+ pd_model = EEG_CNN(2).to(DEVICE)
77
 
78
+ ad_model.load_state_dict(
79
+ torch.load("AD_MLP.pt", map_location=DEVICE)
 
 
 
80
  )
81
 
82
+ pd_model.load_state_dict(
83
+ torch.load("PD_MLP.pt", map_location=DEVICE)
 
 
 
84
  )
85
 
86
+ ad_model.eval()
87
+ pd_model.eval()
88
 
89
  print("Models Loaded Successfully")
90
 
 
93
  # =========================================================
94
 
95
  class EEGRequest(BaseModel):
 
96
  features: list
97
 
98
  # =========================================================
 
100
  # =========================================================
101
 
102
  def predict_model(model, features):
103
+ x = torch.tensor(features, dtype=torch.float32).unsqueeze(0).to(DEVICE)
 
 
 
 
104
 
105
  with torch.no_grad():
 
106
  outputs = model(x)
107
+ probs = torch.softmax(outputs, dim=1).cpu().numpy()[0]
 
 
 
 
108
 
109
  pred = int(np.argmax(probs))
 
110
  confidence = float(probs[pred])
111
 
112
  return pred, confidence, probs.tolist()
 
116
  # =========================================================
117
 
118
  @app.get("/")
 
119
  def home():
 
120
  return {
121
  "message": "NeuroHealth EEG API Running"
122
  }
 
126
  # =========================================================
127
 
128
  @app.post("/predict/alzheimer")
 
129
  def predict_alzheimer(request: EEGRequest):
130
 
131
+ pred, confidence, probs = predict_model(ad_model, request.features)
 
 
 
132
 
133
  return {
 
134
  "prediction": AD_CLASSES[pred],
 
135
  "confidence": confidence,
 
136
  "probabilities": {
 
137
  AD_CLASSES[i]: float(probs[i])
 
138
  for i in range(len(AD_CLASSES))
139
  }
140
  }
 
144
  # =========================================================
145
 
146
  @app.post("/predict/parkinson")
 
147
  def predict_parkinson(request: EEGRequest):
148
 
149
+ pred, confidence, probs = predict_model(pd_model, request.features)
 
 
 
150
 
151
  return {
 
152
  "prediction": PD_CLASSES[pred],
 
153
  "confidence": confidence,
 
154
  "probabilities": {
 
155
  PD_CLASSES[i]: float(probs[i])
 
156
  for i in range(len(PD_CLASSES))
157
  }
158
  }