AbdullahNasir commited on
Commit
c0953f1
·
1 Parent(s): 1242be5

Added modularity

Browse files
app.py CHANGED
@@ -14,215 +14,11 @@ 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
 
14
  import xgboost as xgb
15
  from torch.utils.data import DataLoader, TensorDataset
16
  import time
17
+ from models.temporal_fusion_transformer import TemporalFusionTransformer
18
+ from models.tcn import TCN
19
+ from models.etsformer import ETSformer
20
+ from models.bilstm import BiLSTM
21
+ from models.respfusion import RespFusion
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
22
 
23
  def process_video(video_path):
24
  # Parameters
models/__pycache__/bilstm.cpython-311.pyc ADDED
Binary file (1.53 kB). View file
 
models/__pycache__/etsformer.cpython-311.pyc ADDED
Binary file (2.74 kB). View file
 
models/__pycache__/respfusion.cpython-311.pyc ADDED
Binary file (6.53 kB). View file
 
models/__pycache__/tcn.cpython-311.pyc ADDED
Binary file (2.09 kB). View file
 
models/__pycache__/temporal_fusion_transformer.cpython-311.pyc ADDED
Binary file (2.1 kB). View file
 
models/bilstm.py CHANGED
@@ -1,19 +1,5 @@
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):
 
 
 
 
 
 
 
 
 
 
 
 
1
  import torch.nn as nn
2
+
 
 
 
3
 
4
  # Updated BiLSTM to handle variable layers
5
  class BiLSTM(nn.Module):
models/etsformer.py CHANGED
@@ -1,19 +1,6 @@
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):
 
 
 
 
 
 
 
 
 
 
 
1
  import torch
2
  import torch.nn as nn
3
  import torch.fft as fft
 
 
 
4
 
5
  # Build the ETSformer Class: Encoder, Trend, Seasonality, Exponential Smoothing, and Output Layer
6
  class ETSformer(nn.Module):
models/respfusion.py ADDED
@@ -0,0 +1,100 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ import torch.nn as nn
3
+ import xgboost as xgb
4
+ import numpy as np
5
+
6
+ class RespFusion(nn.Module):
7
+ def __init__(self, tft_model, tcn_model, ets_model, bilstm_model, meta_learner_path=None, weights=None, strategy='stacking',):
8
+ super(RespFusion, self).__init__()
9
+ self.tft = tft_model
10
+ self.tcn = tcn_model
11
+ self.ets = ets_model
12
+ self.bilstm = bilstm_model
13
+ self.strategy = strategy # 'stacking' or other strategies
14
+
15
+ # Initialize XGBoost meta-learner
16
+ self.meta_learner = xgb.XGBRegressor() # Or XGBClassifier for classification
17
+
18
+ # Load the meta-learner if a path is provided
19
+ if meta_learner_path is not None:
20
+ self.meta_learner.load_model(meta_learner_path)
21
+ print(f"Meta-learner loaded from {meta_learner_path}")
22
+
23
+ # Storage for stacking training data
24
+ self.stacking_features = []
25
+ self.stacking_targets = []
26
+
27
+ # Set model weights for ensembling, default to equal weights for weighted_average strategy
28
+ if strategy == 'weighted_average':
29
+ if weights is None:
30
+ self.weights = [1.0, 1.0, 1.0, 1.0]
31
+ else:
32
+ assert len(weights) == 4, "Weights must match the number of models."
33
+ self.weights = weights
34
+
35
+
36
+ def forward(self, x):
37
+ # Get predictions from each base model
38
+ tft_output = self.tft(x).detach().cpu().numpy()
39
+ tcn_output = self.tcn(x).detach().cpu().numpy()
40
+ ets_output = self.ets(x).detach().cpu().numpy()
41
+ bilstm_output = self.bilstm(x).detach().cpu().numpy()
42
+
43
+ if self.strategy == 'stacking':
44
+ # Combine outputs into features for the meta-learner
45
+ features = np.column_stack((tft_output, tcn_output, ets_output, bilstm_output))
46
+ # During inference, use the meta-learner to make predictions
47
+ ensemble_output = self.meta_learner.predict(features)
48
+ return torch.tensor(ensemble_output).to(x.device).float()
49
+
50
+ elif self.strategy == 'voting':
51
+ # For soft voting, calculate the average
52
+ ensemble_output = torch.mean(torch.stack([tft_output, tcn_output, ets_output, bilstm_output], dim=0), dim=0)
53
+ return ensemble_output
54
+
55
+ elif self.strategy == 'weighted_average':
56
+ # Weighted average of outputs
57
+ ensemble_output = (
58
+ self.weights[0] * tft_output +
59
+ self.weights[1] * tcn_output +
60
+ self.weights[2] * ets_output +
61
+ self.weights[3] * bilstm_output
62
+ ) / sum(self.weights)
63
+ return ensemble_output
64
+
65
+ elif self.strategy == 'simple_average':
66
+ # Simple average of outputs
67
+ ensemble_output = (tft_output + tcn_output + ets_output + bilstm_output) / 4
68
+ return ensemble_output
69
+
70
+
71
+ else:
72
+ raise ValueError(f"Invalid strategy: {self.strategy}. Currently supports only 'stacking', 'voting', 'weighted_average', and 'simple_average'.")
73
+
74
+ def collect_stacking_data(self, x, y):
75
+ """Collect base model outputs and corresponding targets for meta-learner training."""
76
+ tft_output = self.tft(x).detach().cpu().numpy()
77
+ tcn_output = self.tcn(x).detach().cpu().numpy()
78
+ ets_output = self.ets(x).detach().cpu().numpy()
79
+ bilstm_output = self.bilstm(x).detach().cpu().numpy()
80
+
81
+ # Stack features and store
82
+ features = np.column_stack((tft_output, tcn_output, ets_output, bilstm_output))
83
+ self.stacking_features.append(features)
84
+ self.stacking_targets.append(y.detach().cpu().numpy())
85
+
86
+ def train_meta_learner(self, save_path=None):
87
+ """Train the XGBoost meta-learner on collected data and save the model."""
88
+ # Concatenate all collected features and targets
89
+ X = np.vstack(self.stacking_features)
90
+ y = np.concatenate(self.stacking_targets)
91
+
92
+ # Train the XGBoost model
93
+ self.meta_learner.fit(X, y)
94
+ print("Meta-learner trained successfully!")
95
+
96
+ # Save the trained meta-learner
97
+ if save_path:
98
+ self.meta_learner.save_model(save_path)
99
+ print(f"Meta-learner saved to {save_path}")
100
+
models/tcn.py CHANGED
@@ -1,19 +1,5 @@
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):
 
 
 
 
 
 
 
 
 
 
 
1
  import torch
2
  import torch.nn as nn
 
 
 
 
3
 
4
  # Define the TCN model
5
  class TCN(nn.Module):
models/{temporalfusiontransformer.py → temporal_fusion_transformer.py} RENAMED
@@ -1,19 +1,5 @@
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):
 
 
 
 
 
 
 
 
 
 
 
 
1
  import torch.nn as nn
2
+
 
 
 
3
 
4
  # Define the Temporal Fusion Transformer (Temporal Fusion Transformer) model
5
  class TemporalFusionTransformer(nn.Module):