Mikecode123 commited on
Commit
59c2658
·
verified ·
1 Parent(s): 195e2c1

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +49 -84
app.py CHANGED
@@ -10,8 +10,8 @@ import numpy as np
10
  # =========================================================
11
 
12
  app = FastAPI(
13
- title="NeuroHealth EEG API",
14
- version="4.0"
15
  )
16
 
17
  DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu")
@@ -20,51 +20,50 @@ DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu")
20
  # LABELS
21
  # =========================================================
22
 
23
- AD_CLASSES = [
24
- "Alzheimer",
25
- "FTD",
26
- "Control"
27
- ]
28
-
29
- PD_CLASSES = [
30
- "Parkinson",
31
- "Control"
32
- ]
33
 
34
  # =========================================================
35
- # REQUEST MODEL
36
  # =========================================================
37
 
38
  class EEGRequest(BaseModel):
39
  features: list
40
 
41
  # =========================================================
42
- # MODEL ARCHITECTURE
43
  # =========================================================
44
 
45
- class EEG_MLP(nn.Module):
46
  def __init__(self, input_dim, output_dim):
47
  super().__init__()
48
 
49
- self.net = nn.Sequential(
50
- nn.Linear(input_dim, 256),
51
- nn.ReLU(),
52
 
53
- nn.BatchNorm1d(256),
 
54
 
55
- nn.Linear(256, 128),
56
- nn.ReLU(),
57
 
58
- nn.BatchNorm1d(128),
59
 
60
- nn.Linear(128, output_dim)
61
- )
62
 
63
  def forward(self, x):
64
- return self.net(x)
 
 
 
 
 
 
 
 
65
 
66
  # =========================================================
67
- # SETTINGS
68
  # =========================================================
69
 
70
  INPUT_DIM = 76
@@ -76,69 +75,48 @@ PD_MODEL_PATH = "PD_eeg_cnn.pth"
76
  # LOAD MODELS
77
  # =========================================================
78
 
79
- print("Loading AD model...")
80
-
81
- ad_model = EEG_MLP(INPUT_DIM, 3).to(DEVICE)
82
-
83
- ad_model.load_state_dict(
84
- torch.load(
85
- AD_MODEL_PATH,
86
- map_location=DEVICE
87
- )
88
- )
89
 
 
 
90
  ad_model.eval()
91
 
92
- print("AD model loaded successfully")
93
-
94
- print("Loading PD model...")
95
-
96
- pd_model = EEG_MLP(INPUT_DIM, 2).to(DEVICE)
97
 
98
- pd_model.load_state_dict(
99
- torch.load(
100
- PD_MODEL_PATH,
101
- map_location=DEVICE
102
- )
103
- )
104
 
 
 
105
  pd_model.eval()
106
 
107
- print("PD model loaded successfully")
108
 
109
- print("All models loaded")
110
 
111
  # =========================================================
112
- # PREDICTION FUNCTION
113
  # =========================================================
114
 
115
- def predict(model, features, class_names):
116
 
117
- x = torch.tensor(
118
- features,
119
- dtype=torch.float32
120
- )
121
 
122
  if x.numel() != INPUT_DIM:
123
- raise ValueError(
124
- f"Expected {INPUT_DIM} features but received {x.numel()}"
125
- )
126
 
127
  x = x.unsqueeze(0).to(DEVICE)
128
 
129
  with torch.no_grad():
130
- outputs = model(x)
131
- probs = torch.softmax(outputs, dim=1)
132
- probs = probs.cpu().numpy()[0]
133
 
134
- pred_idx = int(np.argmax(probs))
135
 
136
  return {
137
- "prediction": class_names[pred_idx],
138
- "confidence": float(probs[pred_idx]),
139
  "probabilities": {
140
- class_names[i]: float(probs[i])
141
- for i in range(len(class_names))
142
  }
143
  }
144
 
@@ -149,31 +127,18 @@ def predict(model, features, class_names):
149
  @app.get("/")
150
  def home():
151
  return {
152
- "status": "running",
153
- "device": str(DEVICE),
154
- "input_features": INPUT_DIM,
155
- "ad_classes": AD_CLASSES,
156
- "pd_classes": PD_CLASSES
157
  }
158
 
159
  @app.get("/health")
160
  def health():
161
- return {
162
- "status": "healthy"
163
- }
164
 
165
  @app.post("/predict/ad")
166
  def predict_ad(req: EEGRequest):
167
- return predict(
168
- ad_model,
169
- req.features,
170
- AD_CLASSES
171
- )
172
 
173
  @app.post("/predict/pd")
174
  def predict_pd(req: EEGRequest):
175
- return predict(
176
- pd_model,
177
- req.features,
178
- PD_CLASSES
179
- )
 
10
  # =========================================================
11
 
12
  app = FastAPI(
13
+ title="NeuroHealth EEG CNN API",
14
+ version="5.0"
15
  )
16
 
17
  DEVICE = torch.device("cuda" if torch.cuda.is_available() else "cpu")
 
20
  # LABELS
21
  # =========================================================
22
 
23
+ AD_CLASSES = ["Alzheimer", "FTD", "Control"]
24
+ PD_CLASSES = ["Parkinson", "Control"]
 
 
 
 
 
 
 
 
25
 
26
  # =========================================================
27
+ # REQUEST SCHEMA
28
  # =========================================================
29
 
30
  class EEGRequest(BaseModel):
31
  features: list
32
 
33
  # =========================================================
34
+ # CNN MODEL (MATCHES YOUR CHECKPOINT)
35
  # =========================================================
36
 
37
+ class EEG_CNN(nn.Module):
38
  def __init__(self, input_dim, output_dim):
39
  super().__init__()
40
 
41
+ self.conv1 = nn.Conv1d(1, 16, kernel_size=3, padding=1)
42
+ self.bn1 = nn.BatchNorm1d(16)
 
43
 
44
+ self.conv2 = nn.Conv1d(16, 32, kernel_size=3, padding=1)
45
+ self.bn2 = nn.BatchNorm1d(32)
46
 
47
+ self.conv3 = nn.Conv1d(32, 64, kernel_size=3, padding=1)
48
+ self.bn3 = nn.BatchNorm1d(64)
49
 
50
+ self.pool = nn.AdaptiveAvgPool1d(1)
51
 
52
+ self.fc = nn.Linear(64, output_dim)
 
53
 
54
  def forward(self, x):
55
+ x = x.unsqueeze(1) # (batch, 1, 76)
56
+
57
+ x = torch.relu(self.bn1(self.conv1(x)))
58
+ x = torch.relu(self.bn2(self.conv2(x)))
59
+ x = torch.relu(self.bn3(self.conv3(x)))
60
+
61
+ x = self.pool(x).squeeze(-1)
62
+
63
+ return self.fc(x)
64
 
65
  # =========================================================
66
+ # CONFIG
67
  # =========================================================
68
 
69
  INPUT_DIM = 76
 
75
  # LOAD MODELS
76
  # =========================================================
77
 
78
+ print("Loading AD CNN model...")
 
 
 
 
 
 
 
 
 
79
 
80
+ ad_model = EEG_CNN(INPUT_DIM, 3).to(DEVICE)
81
+ ad_model.load_state_dict(torch.load(AD_MODEL_PATH, map_location=DEVICE))
82
  ad_model.eval()
83
 
84
+ print("AD model loaded")
 
 
 
 
85
 
86
+ print("Loading PD CNN model...")
 
 
 
 
 
87
 
88
+ pd_model = EEG_CNN(INPUT_DIM, 2).to(DEVICE)
89
+ pd_model.load_state_dict(torch.load(PD_MODEL_PATH, map_location=DEVICE))
90
  pd_model.eval()
91
 
92
+ print("PD model loaded")
93
 
94
+ print("All models ready")
95
 
96
  # =========================================================
97
+ # PREDICTION ENGINE
98
  # =========================================================
99
 
100
+ def predict(model, features, classes):
101
 
102
+ x = torch.tensor(features, dtype=torch.float32)
 
 
 
103
 
104
  if x.numel() != INPUT_DIM:
105
+ raise ValueError(f"Expected {INPUT_DIM} features, got {x.numel()}")
 
 
106
 
107
  x = x.unsqueeze(0).to(DEVICE)
108
 
109
  with torch.no_grad():
110
+ logits = model(x)
111
+ probs = torch.softmax(logits, dim=1).cpu().numpy()[0]
 
112
 
113
+ pred = int(np.argmax(probs))
114
 
115
  return {
116
+ "prediction": classes[pred],
117
+ "confidence": float(probs[pred]),
118
  "probabilities": {
119
+ classes[i]: float(probs[i]) for i in range(len(classes))
 
120
  }
121
  }
122
 
 
127
  @app.get("/")
128
  def home():
129
  return {
130
+ "status": "NeuroHealth EEG CNN API running",
131
+ "input_dim": INPUT_DIM
 
 
 
132
  }
133
 
134
  @app.get("/health")
135
  def health():
136
+ return {"status": "ok"}
 
 
137
 
138
  @app.post("/predict/ad")
139
  def predict_ad(req: EEGRequest):
140
+ return predict(ad_model, req.features, AD_CLASSES)
 
 
 
 
141
 
142
  @app.post("/predict/pd")
143
  def predict_pd(req: EEGRequest):
144
+ return predict(pd_model, req.features, PD_CLASSES)