AbdullahNasir commited on
Commit
03ce4c5
·
1 Parent(s): bdc80d7

Added app.py and other requirements

Browse files
app.py ADDED
@@ -0,0 +1,368 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import torch
3
+ import cv2
4
+ import numpy as np
5
+ import pandas as pd
6
+ from scipy.signal import find_peaks, savgol_filter
7
+ from collections import Counter
8
+ from tqdm import tqdm
9
+ import time
10
+ import os
11
+ import torch
12
+ import torch.nn as nn
13
+ import torch.fft as fft
14
+ import xgboost as xgb
15
+ from torch.utils.data import DataLoader, TensorDataset
16
+ import time
17
+
18
+ # Define the TCN model
19
+ class TCN(nn.Module):
20
+ def __init__(self, input_size, hidden_size, output_size, num_layers=3, dropout=0.1):
21
+ super(TCN, self).__init__()
22
+
23
+ # List to hold convolutional layers
24
+ self.convs = nn.ModuleList()
25
+ dropout = dropout if num_layers > 1 else 0 # No dropout if only one layer
26
+ self.dropout = nn.Dropout(dropout)
27
+
28
+ # Create the convolutional layers
29
+ for i in range(num_layers):
30
+ in_channels = input_size if i == 0 else hidden_size # First layer uses input_size, others use hidden_size
31
+ out_channels = hidden_size # All layers have the same hidden size
32
+ self.convs.append(nn.Conv1d(in_channels, out_channels, kernel_size=2, padding=1))
33
+
34
+ # Fully connected output layer
35
+ self.fc = nn.Linear(hidden_size, output_size)
36
+
37
+ def forward(self, x):
38
+ x = x.permute(0, 2, 1) # Change to (batch_size, features, timesteps)
39
+
40
+ # Apply each convolutional layer followed by dropout
41
+ for conv in self.convs:
42
+ x = torch.relu(conv(x))
43
+ x = self.dropout(x) # Apply dropout after each convolution
44
+
45
+ x = torch.mean(x, dim=2) # Global average pooling
46
+ x = self.fc(x) # Output layer
47
+ return x
48
+
49
+ # Define the Temporal Fusion Transformer (Temporal Fusion Transformer) model
50
+ class TemporalFusionTransformer(nn.Module):
51
+ def __init__(self, input_size, hidden_size, output_size, num_layers=3, dropout=0.1):
52
+ super(TemporalFusionTransformer, self).__init__()
53
+ # Encoder and Decoder LSTMs with multiple layers
54
+ self.encoder = nn.LSTM(input_size, hidden_size, num_layers=num_layers, batch_first=True, dropout=dropout)
55
+ self.decoder = nn.LSTM(hidden_size, hidden_size, num_layers=num_layers, batch_first=True, dropout=dropout)
56
+
57
+ self.attention = nn.MultiheadAttention(hidden_size, num_heads=4, batch_first=True) # Attention mechanism
58
+ self.fc = nn.Linear(hidden_size, output_size) # Fully connected output layer
59
+ self.dropout = nn.Dropout(dropout) # Dropout layer
60
+
61
+ def forward(self, x):
62
+ encoder_output, _ = self.encoder(x) # Encoder output
63
+ decoder_output, _ = self.decoder(encoder_output) # Decoder output
64
+ attention_output, _ = self.attention(decoder_output, encoder_output, encoder_output) # Attention output
65
+ attention_output = self.dropout(attention_output) # Apply dropout
66
+ output = self.fc(attention_output[:, -1, :]) # Take the last time step from the attention output
67
+ return output
68
+
69
+
70
+ # Build the ETSformer Class: Encoder, Trend, Seasonality, Exponential Smoothing, and Output Layer
71
+ class ETSformer(nn.Module):
72
+ def __init__(self, input_size, hidden_size, output_size, num_layers=3, dropout=0.1):
73
+ super(ETSformer, self).__init__()
74
+
75
+ # Encoder: LSTM with multiple layers and dropout
76
+ self.encoder = nn.LSTM(
77
+ input_size,
78
+ hidden_size,
79
+ num_layers=num_layers,
80
+ batch_first=True,
81
+ dropout=dropout if num_layers > 1 else 0.0 # Dropout only applies if num_layers > 1
82
+ )
83
+
84
+ # Trend, Seasonality, Exponential Modules
85
+ self.trend_module = nn.Sequential(
86
+ nn.Linear(hidden_size, hidden_size),
87
+ nn.Dropout(dropout) # Dropout in the trend module
88
+ )
89
+ self.seasonality_module = nn.Sequential(
90
+ nn.Linear(hidden_size, hidden_size),
91
+ nn.Dropout(dropout) # Dropout in the seasonality module
92
+ )
93
+ self.exponential_module = nn.Sequential(
94
+ nn.Linear(hidden_size, hidden_size),
95
+ nn.Dropout(dropout) # Dropout in the exponential module
96
+ )
97
+
98
+ self.fc = nn.Linear(hidden_size, output_size) # Fully connected layer for output
99
+
100
+ def forward(self, x):
101
+ encoder_output, _ = self.encoder(x) # Encode the input sequence
102
+ trend = self.trend_module(encoder_output )# Trend Component
103
+ # Seasonality Component
104
+ freq = fft.fft(encoder_output, dim=1) # Frequency domain transformation
105
+ seasonality = fft.ifft(self.seasonality_module(torch.abs(freq)), dim=1).real
106
+ exponential = torch.sigmoid(self.exponential_module(encoder_output)) # Exponential Smoothing Component
107
+ combined = trend + seasonality + exponential # Combine the components
108
+ # Output layer: Use the last time step for predictions
109
+ output = self.fc(combined[:, -1, :])
110
+ return output
111
+
112
+ # Updated BiLSTM to handle variable layers
113
+ class BiLSTM(nn.Module):
114
+ def __init__(self, input_size, hidden_size, output_size, num_layers=2, dropout=0.1):
115
+ super(BiLSTM, self).__init__()
116
+ self.bilstm = nn.LSTM(
117
+ input_size,
118
+ hidden_size,
119
+ num_layers=num_layers,
120
+ batch_first=True,
121
+ bidirectional=True,
122
+ dropout=dropout if num_layers > 1 else 0 # Dropout only applies for num_layers > 1
123
+ )
124
+ self.fc = nn.Linear(hidden_size * 2, output_size) # Multiply hidden_size by 2 for bidirectional
125
+
126
+ def forward(self, x):
127
+ bilstm_output, _ = self.bilstm(x)
128
+ output = self.fc(bilstm_output[:, -1, :]) # Use the last time step
129
+ return output
130
+
131
+ class RespFusion(nn.Module):
132
+ def __init__(self, tft_model, tcn_model, ets_model, bilstm_model, meta_learner_path=None, weights=None, strategy='stacking',):
133
+ super(RespFusion, self).__init__()
134
+ self.tft = tft_model
135
+ self.tcn = tcn_model
136
+ self.ets = ets_model
137
+ self.bilstm = bilstm_model
138
+ self.strategy = strategy # 'stacking' or other strategies
139
+
140
+ # Initialize XGBoost meta-learner
141
+ self.meta_learner = xgb.XGBRegressor() # Or XGBClassifier for classification
142
+
143
+ # Load the meta-learner if a path is provided
144
+ if meta_learner_path is not None:
145
+ self.meta_learner.load_model(meta_learner_path)
146
+ print(f"Meta-learner loaded from {meta_learner_path}")
147
+
148
+ # Storage for stacking training data
149
+ self.stacking_features = []
150
+ self.stacking_targets = []
151
+
152
+ # Set model weights for ensembling, default to equal weights for weighted_average strategy
153
+ if strategy == 'weighted_average':
154
+ if weights is None:
155
+ self.weights = [1.0, 1.0, 1.0, 1.0]
156
+ else:
157
+ assert len(weights) == 4, "Weights must match the number of models."
158
+ self.weights = weights
159
+
160
+
161
+ def forward(self, x):
162
+ # Get predictions from each base model
163
+ tft_output = self.tft(x).detach().cpu().numpy()
164
+ tcn_output = self.tcn(x).detach().cpu().numpy()
165
+ ets_output = self.ets(x).detach().cpu().numpy()
166
+ bilstm_output = self.bilstm(x).detach().cpu().numpy()
167
+
168
+ if self.strategy == 'stacking':
169
+ # Combine outputs into features for the meta-learner
170
+ features = np.column_stack((tft_output, tcn_output, ets_output, bilstm_output))
171
+ # During inference, use the meta-learner to make predictions
172
+ ensemble_output = self.meta_learner.predict(features)
173
+ return torch.tensor(ensemble_output).to(x.device).float()
174
+
175
+ elif self.strategy == 'voting':
176
+ # For soft voting, calculate the average
177
+ ensemble_output = torch.mean(torch.stack([tft_output, tcn_output, ets_output, bilstm_output], dim=0), dim=0)
178
+ return ensemble_output
179
+
180
+ elif self.strategy == 'weighted_average':
181
+ # Weighted average of outputs
182
+ ensemble_output = (
183
+ self.weights[0] * tft_output +
184
+ self.weights[1] * tcn_output +
185
+ self.weights[2] * ets_output +
186
+ self.weights[3] * bilstm_output
187
+ ) / sum(self.weights)
188
+ return ensemble_output
189
+
190
+ elif self.strategy == 'simple_average':
191
+ # Simple average of outputs
192
+ ensemble_output = (tft_output + tcn_output + ets_output + bilstm_output) / 4
193
+ return ensemble_output
194
+
195
+
196
+ else:
197
+ raise ValueError(f"Invalid strategy: {self.strategy}. Currently supports only 'stacking', 'voting', 'weighted_average', and 'simple_average'.")
198
+
199
+ def collect_stacking_data(self, x, y):
200
+ """Collect base model outputs and corresponding targets for meta-learner training."""
201
+ tft_output = self.tft(x).detach().cpu().numpy()
202
+ tcn_output = self.tcn(x).detach().cpu().numpy()
203
+ ets_output = self.ets(x).detach().cpu().numpy()
204
+ bilstm_output = self.bilstm(x).detach().cpu().numpy()
205
+
206
+ # Stack features and store
207
+ features = np.column_stack((tft_output, tcn_output, ets_output, bilstm_output))
208
+ self.stacking_features.append(features)
209
+ self.stacking_targets.append(y.detach().cpu().numpy())
210
+
211
+ def train_meta_learner(self, save_path=None):
212
+ """Train the XGBoost meta-learner on collected data and save the model."""
213
+ # Concatenate all collected features and targets
214
+ X = np.vstack(self.stacking_features)
215
+ y = np.concatenate(self.stacking_targets)
216
+
217
+ # Train the XGBoost model
218
+ self.meta_learner.fit(X, y)
219
+ print("Meta-learner trained successfully!")
220
+
221
+ # Save the trained meta-learner
222
+ if save_path:
223
+ self.meta_learner.save_model(save_path)
224
+ print(f"Meta-learner saved to {save_path}")
225
+
226
+
227
+ def process_video(video_path):
228
+ # Parameters
229
+ roi_coordinates = None # Manual ROI selection
230
+ fps = 30 # Frames per second
231
+ feature_window = 10 # Window for feature aggregation (seconds)
232
+
233
+ cap = cv2.VideoCapture(video_path)
234
+ if not cap.isOpened():
235
+ return "Error opening video file"
236
+
237
+ frame_count = int(cap.get(cv2.CAP_PROP_FRAME_COUNT))
238
+
239
+ # Select ROI
240
+ ret, first_frame = cap.read()
241
+ if not ret:
242
+ return "Failed to read first frame"
243
+
244
+ if roi_coordinates is None:
245
+ roi_coordinates = cv2.selectROI("Select ROI", first_frame, fromCenter=False, showCrosshair=True)
246
+ cv2.destroyWindow("Select ROI")
247
+ x, y, w, h = map(int, roi_coordinates)
248
+
249
+ prev_gray = cv2.cvtColor(first_frame[y:y+h, x:x+w], cv2.COLOR_BGR2GRAY)
250
+ motion_magnitude, direction_angles = [], []
251
+
252
+ frame_skip = 2
253
+ scale_factor = 0.5
254
+
255
+ roi = cv2.resize(first_frame[y:y+h, x:x+w], None, fx=scale_factor, fy=scale_factor, interpolation=cv2.INTER_AREA)
256
+ prev_gray = cv2.cvtColor(roi, cv2.COLOR_BGR2GRAY)
257
+
258
+ while cap.isOpened():
259
+ ret, frame = cap.read()
260
+ if not ret:
261
+ break
262
+
263
+ frame_index = int(cap.get(cv2.CAP_PROP_POS_FRAMES))
264
+ if frame_index % frame_skip != 0:
265
+ continue
266
+
267
+ roi = cv2.resize(frame[y:y+h, x:x+w], None, fx=scale_factor, fy=scale_factor, interpolation=cv2.INTER_AREA)
268
+ gray = cv2.cvtColor(roi, cv2.COLOR_BGR2GRAY)
269
+
270
+ flow = cv2.calcOpticalFlowFarneback(prev_gray, gray, None, 0.5, 3, 15, 2, 5, 1.2, 0)
271
+ magnitude, angle = cv2.cartToPolar(flow[..., 0], flow[..., 1])
272
+
273
+ motion_magnitude.append(np.mean(magnitude))
274
+ direction_angles.extend(angle.flatten())
275
+
276
+ prev_gray = gray
277
+
278
+ cap.release()
279
+
280
+ window_length = min(len(motion_magnitude) - 1, 31)
281
+ if window_length % 2 == 0:
282
+ window_length += 1
283
+ smoothed_magnitude = savgol_filter(motion_magnitude, window_length=window_length, polyorder=3)
284
+
285
+ features = []
286
+ window_size = feature_window * (fps // frame_skip)
287
+ num_windows = len(smoothed_magnitude) // window_size
288
+
289
+ for i in range(num_windows):
290
+ start, end = i * window_size, (i + 1) * window_size
291
+ window_magnitude = smoothed_magnitude[start:end]
292
+ peaks, _ = find_peaks(window_magnitude)
293
+ troughs, _ = find_peaks(-window_magnitude)
294
+
295
+ features.append([
296
+ np.mean(window_magnitude), np.std(window_magnitude), np.max(window_magnitude), np.min(window_magnitude),
297
+ len(peaks), np.mean(window_magnitude[peaks]) if len(peaks) > 0 else 0,
298
+ np.mean(np.diff(peaks)) / (fps // frame_skip) if len(peaks) > 1 else 0,
299
+ (np.mean(window_magnitude[peaks]) - np.mean(window_magnitude[troughs])) if peaks.size > 0 and troughs.size > 0 else 0,
300
+ Counter((np.array(direction_angles[start:end]) / (np.pi / 4)).astype(int) % 8).most_common(1)[0][0] if len(direction_angles) > 0 else -1,
301
+ np.argmax(np.abs(np.fft.fft(window_magnitude))[1:len(window_magnitude)//2]) / window_size
302
+ ])
303
+
304
+ features_df = pd.DataFrame(features, columns=[
305
+ "mean_magnitude", "std_magnitude", "max_magnitude", "min_magnitude", "peak_count", "avg_peak_height", "peak_to_peak_interval", "amplitude", "dominant_direction", "dominant_frequency"
306
+ ])
307
+ print("Features Extracted. Matching Model Keys.")
308
+
309
+ X_inference = np.array([features_df.iloc[i-5:i, :].values for i in range(5, len(features_df))])
310
+ X_inference_tensor = torch.tensor(X_inference, dtype=torch.float32)
311
+
312
+
313
+ input_size, hidden_size, output_size = X_inference_tensor.shape[2], 64, 1
314
+ tft_model = TemporalFusionTransformer(input_size, hidden_size, output_size)
315
+ tcn_model = TCN(input_size, hidden_size, output_size)
316
+ ets_model = ETSformer(input_size, hidden_size, output_size)
317
+ bilstm_model = BiLSTM(input_size, hidden_size, output_size)
318
+
319
+ weights_path = './models/weights/'
320
+ # Load state dicts for each model
321
+ tft_model.load_state_dict(torch.load(weights_path + "tft_loss_optimized.pth", map_location=torch.device("cpu")))
322
+ print("TFT Model Loaded. All keys matched successfully.")
323
+ tcn_model.load_state_dict(torch.load(weights_path + "tcn_loss_optimized.pth", map_location=torch.device("cpu")))
324
+ print("TCN Model Loaded. All keys matched successfully.")
325
+ ets_model.load_state_dict(torch.load(weights_path + "etsformer_loss_optimized.pth", map_location=torch.device("cpu")))
326
+ print("ETSformer Model Loaded. All keys matched successfully.")
327
+ bilstm_model.load_state_dict(torch.load(weights_path + "bilstm_loss_optimized.pth", map_location=torch.device("cpu")))
328
+ print("BiLSTM Model Loaded. All keys matched successfully.")
329
+
330
+
331
+ tft_model.eval()
332
+ tcn_model.eval()
333
+ ets_model.eval()
334
+ bilstm_model.eval()
335
+
336
+ model = RespFusion(
337
+ tft_model, tcn_model, ets_model, bilstm_model,
338
+ strategy='stacking',
339
+ meta_learner_path=weights_path + "respfusion_2_xgboost_meta_learner.json"
340
+ )
341
+ print("Respfusion Model Loaded. Detecting Apnea.")
342
+ with torch.no_grad():
343
+ predictions = model(X_inference_tensor).squeeze().tolist()
344
+
345
+ def categorize_breathing_rate(pred):
346
+ if pred < 0.5:
347
+ return "Apnea"
348
+ elif pred > 20:
349
+ return "Tachypnea"
350
+ elif pred < 10:
351
+ return "Bradypnea"
352
+ else:
353
+ return "Normal"
354
+
355
+ categories = [categorize_breathing_rate(pred) for pred in predictions]
356
+ overall_category = categorize_breathing_rate(sum(predictions) / len(predictions))
357
+
358
+ return {"Breathing State per 10s": categories, "Average Breathing Rate": sum(predictions)/len(predictions), "Overall Breathing State": overall_category,}
359
+
360
+ demo = gr.Interface(
361
+ fn=process_video,
362
+ inputs=gr.Video(label="Upload Video for Analysis"),
363
+ outputs=gr.JSON(),
364
+ title="Apnea Detection System",
365
+ description="Upload a video to analyze breathing rate and detect conditions such as Apnea, Tachypnea, and Bradypnea."
366
+ )
367
+
368
+ demo.launch()
models/bilstm.py ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import torch
3
+ import cv2
4
+ import numpy as np
5
+ import pandas as pd
6
+ from scipy.signal import find_peaks, savgol_filter
7
+ from collections import Counter
8
+ from tqdm import tqdm
9
+ import time
10
+ import os
11
+ import torch
12
+ import torch.nn as nn
13
+ import torch.fft as fft
14
+ import xgboost as xgb
15
+ from torch.utils.data import DataLoader, TensorDataset
16
+ import time
17
+
18
+ # Updated BiLSTM to handle variable layers
19
+ class BiLSTM(nn.Module):
20
+ def __init__(self, input_size, hidden_size, output_size, num_layers=2, dropout=0.1):
21
+ super(BiLSTM, self).__init__()
22
+ self.bilstm = nn.LSTM(
23
+ input_size,
24
+ hidden_size,
25
+ num_layers=num_layers,
26
+ batch_first=True,
27
+ bidirectional=True,
28
+ dropout=dropout if num_layers > 1 else 0 # Dropout only applies for num_layers > 1
29
+ )
30
+ self.fc = nn.Linear(hidden_size * 2, output_size) # Multiply hidden_size by 2 for bidirectional
31
+
32
+ def forward(self, x):
33
+ bilstm_output, _ = self.bilstm(x)
34
+ output = self.fc(bilstm_output[:, -1, :]) # Use the last time step
35
+ return output
models/etsformer.py ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import torch
3
+ import cv2
4
+ import numpy as np
5
+ import pandas as pd
6
+ from scipy.signal import find_peaks, savgol_filter
7
+ from collections import Counter
8
+ from tqdm import tqdm
9
+ import time
10
+ import os
11
+ import torch
12
+ import torch.nn as nn
13
+ import torch.fft as fft
14
+ import xgboost as xgb
15
+ from torch.utils.data import DataLoader, TensorDataset
16
+ import time
17
+
18
+ # Build the ETSformer Class: Encoder, Trend, Seasonality, Exponential Smoothing, and Output Layer
19
+ class ETSformer(nn.Module):
20
+ def __init__(self, input_size, hidden_size, output_size, num_layers=3, dropout=0.1):
21
+ super(ETSformer, self).__init__()
22
+
23
+ # Encoder: LSTM with multiple layers and dropout
24
+ self.encoder = nn.LSTM(
25
+ input_size,
26
+ hidden_size,
27
+ num_layers=num_layers,
28
+ batch_first=True,
29
+ dropout=dropout if num_layers > 1 else 0.0 # Dropout only applies if num_layers > 1
30
+ )
31
+
32
+ # Trend, Seasonality, Exponential Modules
33
+ self.trend_module = nn.Sequential(
34
+ nn.Linear(hidden_size, hidden_size),
35
+ nn.Dropout(dropout) # Dropout in the trend module
36
+ )
37
+ self.seasonality_module = nn.Sequential(
38
+ nn.Linear(hidden_size, hidden_size),
39
+ nn.Dropout(dropout) # Dropout in the seasonality module
40
+ )
41
+ self.exponential_module = nn.Sequential(
42
+ nn.Linear(hidden_size, hidden_size),
43
+ nn.Dropout(dropout) # Dropout in the exponential module
44
+ )
45
+
46
+ self.fc = nn.Linear(hidden_size, output_size) # Fully connected layer for output
47
+
48
+ def forward(self, x):
49
+ encoder_output, _ = self.encoder(x) # Encode the input sequence
50
+ trend = self.trend_module(encoder_output )# Trend Component
51
+ # Seasonality Component
52
+ freq = fft.fft(encoder_output, dim=1) # Frequency domain transformation
53
+ seasonality = fft.ifft(self.seasonality_module(torch.abs(freq)), dim=1).real
54
+ exponential = torch.sigmoid(self.exponential_module(encoder_output)) # Exponential Smoothing Component
55
+ combined = trend + seasonality + exponential # Combine the components
56
+ # Output layer: Use the last time step for predictions
57
+ output = self.fc(combined[:, -1, :])
58
+ return output
59
+
models/tcn.py ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import torch
3
+ import cv2
4
+ import numpy as np
5
+ import pandas as pd
6
+ from scipy.signal import find_peaks, savgol_filter
7
+ from collections import Counter
8
+ from tqdm import tqdm
9
+ import time
10
+ import os
11
+ import torch
12
+ import torch.nn as nn
13
+ import torch.fft as fft
14
+ import xgboost as xgb
15
+ from torch.utils.data import DataLoader, TensorDataset
16
+ import time
17
+
18
+ # Define the TCN model
19
+ class TCN(nn.Module):
20
+ def __init__(self, input_size, hidden_size, output_size, num_layers=3, dropout=0.1):
21
+ super(TCN, self).__init__()
22
+
23
+ # List to hold convolutional layers
24
+ self.convs = nn.ModuleList()
25
+ dropout = dropout if num_layers > 1 else 0 # No dropout if only one layer
26
+ self.dropout = nn.Dropout(dropout)
27
+
28
+ # Create the convolutional layers
29
+ for i in range(num_layers):
30
+ in_channels = input_size if i == 0 else hidden_size # First layer uses input_size, others use hidden_size
31
+ out_channels = hidden_size # All layers have the same hidden size
32
+ self.convs.append(nn.Conv1d(in_channels, out_channels, kernel_size=2, padding=1))
33
+
34
+ # Fully connected output layer
35
+ self.fc = nn.Linear(hidden_size, output_size)
36
+
37
+ def forward(self, x):
38
+ x = x.permute(0, 2, 1) # Change to (batch_size, features, timesteps)
39
+
40
+ # Apply each convolutional layer followed by dropout
41
+ for conv in self.convs:
42
+ x = torch.relu(conv(x))
43
+ x = self.dropout(x) # Apply dropout after each convolution
44
+
45
+ x = torch.mean(x, dim=2) # Global average pooling
46
+ x = self.fc(x) # Output layer
47
+ return x
models/temporalfusiontransformer.py ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ import torch
3
+ import cv2
4
+ import numpy as np
5
+ import pandas as pd
6
+ from scipy.signal import find_peaks, savgol_filter
7
+ from collections import Counter
8
+ from tqdm import tqdm
9
+ import time
10
+ import os
11
+ import torch
12
+ import torch.nn as nn
13
+ import torch.fft as fft
14
+ import xgboost as xgb
15
+ from torch.utils.data import DataLoader, TensorDataset
16
+ import time
17
+
18
+ # Define the Temporal Fusion Transformer (Temporal Fusion Transformer) model
19
+ class TemporalFusionTransformer(nn.Module):
20
+ def __init__(self, input_size, hidden_size, output_size, num_layers=3, dropout=0.1):
21
+ super(TemporalFusionTransformer, self).__init__()
22
+ # Encoder and Decoder LSTMs with multiple layers
23
+ self.encoder = nn.LSTM(input_size, hidden_size, num_layers=num_layers, batch_first=True, dropout=dropout)
24
+ self.decoder = nn.LSTM(hidden_size, hidden_size, num_layers=num_layers, batch_first=True, dropout=dropout)
25
+
26
+ self.attention = nn.MultiheadAttention(hidden_size, num_heads=4, batch_first=True) # Attention mechanism
27
+ self.fc = nn.Linear(hidden_size, output_size) # Fully connected output layer
28
+ self.dropout = nn.Dropout(dropout) # Dropout layer
29
+
30
+ def forward(self, x):
31
+ encoder_output, _ = self.encoder(x) # Encoder output
32
+ decoder_output, _ = self.decoder(encoder_output) # Decoder output
33
+ attention_output, _ = self.attention(decoder_output, encoder_output, encoder_output) # Attention output
34
+ attention_output = self.dropout(attention_output) # Apply dropout
35
+ output = self.fc(attention_output[:, -1, :]) # Take the last time step from the attention output
36
+ return output
models/weights/bilstm_loss_optimized.pth ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:1a5713fef154f7aa13882523257bfa93ddd047f074c5daa12eb3c763080e5e27
3
+ size 559700
models/weights/etsformer_loss_optimized.pth ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:feb1fab663ae0f35546ca372f7f8b6b026d8bf6fd80a69c5204343d355a3fccf
3
+ size 401394
models/weights/respfusion_2_xgboost_meta_learner.json ADDED
The diff for this file is too large to render. See raw diff
 
models/weights/tcn_loss_optimized.pth ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:140476fe12888b96c5526457a51e55186cf51b0ad8c067c4f8c1d583f8049267
3
+ size 75012
models/weights/tft_loss_optimized.pth ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:0bf6c6d6a8c9078ac7bd4b7548d0d9746034ef1327e2ec3dcc354612f49bbeaa
3
+ size 819826
requirements.txt ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ gradio
2
+ torch
3
+ opencv-python
4
+ numpy
5
+ pandas
6
+ scipy
7
+ tqdm
8
+ xgboost