Spaces:
Runtime error
Runtime error
Update core/train_eval.py
Browse files- core/train_eval.py +23 -12
core/train_eval.py
CHANGED
|
@@ -30,7 +30,6 @@ def mean_absolute_scaled_error(y_true, y_pred, y_train):
|
|
| 30 |
"""Calculate MASE, using naive forecast as denominator."""
|
| 31 |
y_true, y_pred = np.array(y_true), np.array(y_pred)
|
| 32 |
errors = np.abs(y_true - y_pred)
|
| 33 |
-
# Naive forecast: use previous value as prediction
|
| 34 |
naive_errors = np.abs(y_train[1:] - y_train[:-1])
|
| 35 |
mean_naive_error = np.mean(naive_errors) if len(naive_errors) > 0 else 1.0
|
| 36 |
return np.mean(errors) / mean_naive_error if mean_naive_error != 0 else np.nan
|
|
@@ -62,6 +61,7 @@ def train_and_evaluate(
|
|
| 62 |
dropout=0.2,
|
| 63 |
window=30,
|
| 64 |
test_split=0.2,
|
|
|
|
| 65 |
device="cuda" if torch.cuda.is_available() else "cpu",
|
| 66 |
verbose=True
|
| 67 |
):
|
|
@@ -83,6 +83,7 @@ def train_and_evaluate(
|
|
| 83 |
print(f"X_val shape: {X_val.shape}, y_val shape: {y_val.shape}")
|
| 84 |
print(f"X_test shape: {X_test.shape}, y_test shape: {y_test.shape}")
|
| 85 |
|
|
|
|
| 86 |
X_train_tensor = torch.tensor(X_train, dtype=torch.float32)
|
| 87 |
y_train_tensor = torch.tensor(y_train, dtype=torch.float32)
|
| 88 |
X_val_tensor = torch.tensor(X_val, dtype=torch.float32)
|
|
@@ -90,15 +91,15 @@ def train_and_evaluate(
|
|
| 90 |
X_test_tensor = torch.tensor(X_test, dtype=torch.float32)
|
| 91 |
y_test_tensor = torch.tensor(y_test, dtype=torch.float32)
|
| 92 |
|
| 93 |
-
train_loader = DataLoader(TensorDataset(X_train_tensor, y_train_tensor), batch_size=
|
| 94 |
-
val_loader = DataLoader(TensorDataset(X_val_tensor, y_val_tensor), batch_size=
|
| 95 |
-
test_loader = DataLoader(TensorDataset(X_test_tensor, y_test_tensor), batch_size=
|
| 96 |
|
| 97 |
input_dim = X_train.shape[2] if X_train.ndim == 3 else 1
|
| 98 |
model = model_cls(input_size=input_dim, hidden_size=hidden, num_layers=layers, output_size=horizon, dropout=dropout).to(device)
|
| 99 |
optimizer = torch.optim.AdamW(model.parameters(), lr=lr, betas=(beta1, beta2), weight_decay=weight_decay)
|
| 100 |
loss_fn = nn.MSELoss()
|
| 101 |
-
scheduler = torch.optim.lr_scheduler.ReduceLROnPlateau(optimizer, mode='min', patience=5, factor=
|
| 102 |
|
| 103 |
train_losses = []
|
| 104 |
val_losses = []
|
|
@@ -186,13 +187,13 @@ def train_and_evaluate(
|
|
| 186 |
mda = mean_directional_accuracy(targets_inv, preds_inv)
|
| 187 |
|
| 188 |
result["metrics"] = {
|
| 189 |
-
"
|
| 190 |
-
"Explained Variance": round(evs,
|
| 191 |
-
"MDA (%)": round(mda,
|
| 192 |
-
"RMSE": round(rmse,
|
| 193 |
-
"MAE": round(mae,
|
| 194 |
-
"MAPE (%)": round(mape,
|
| 195 |
-
"MASE": round(mase,
|
| 196 |
}
|
| 197 |
|
| 198 |
result["forecast"] = preds_inv
|
|
@@ -212,4 +213,14 @@ def train_and_evaluate(
|
|
| 212 |
if not future_df.empty:
|
| 213 |
result["future_actuals"] = future_df['value'].values.tolist()[:horizon]
|
| 214 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 215 |
return result
|
|
|
|
| 30 |
"""Calculate MASE, using naive forecast as denominator."""
|
| 31 |
y_true, y_pred = np.array(y_true), np.array(y_pred)
|
| 32 |
errors = np.abs(y_true - y_pred)
|
|
|
|
| 33 |
naive_errors = np.abs(y_train[1:] - y_train[:-1])
|
| 34 |
mean_naive_error = np.mean(naive_errors) if len(naive_errors) > 0 else 1.0
|
| 35 |
return np.mean(errors) / mean_naive_error if mean_naive_error != 0 else np.nan
|
|
|
|
| 61 |
dropout=0.2,
|
| 62 |
window=30,
|
| 63 |
test_split=0.2,
|
| 64 |
+
scheduler_factor=0.5,
|
| 65 |
device="cuda" if torch.cuda.is_available() else "cpu",
|
| 66 |
verbose=True
|
| 67 |
):
|
|
|
|
| 83 |
print(f"X_val shape: {X_val.shape}, y_val shape: {y_val.shape}")
|
| 84 |
print(f"X_test shape: {X_test.shape}, y_test shape: {y_test.shape}")
|
| 85 |
|
| 86 |
+
batch_size = 32
|
| 87 |
X_train_tensor = torch.tensor(X_train, dtype=torch.float32)
|
| 88 |
y_train_tensor = torch.tensor(y_train, dtype=torch.float32)
|
| 89 |
X_val_tensor = torch.tensor(X_val, dtype=torch.float32)
|
|
|
|
| 91 |
X_test_tensor = torch.tensor(X_test, dtype=torch.float32)
|
| 92 |
y_test_tensor = torch.tensor(y_test, dtype=torch.float32)
|
| 93 |
|
| 94 |
+
train_loader = DataLoader(TensorDataset(X_train_tensor, y_train_tensor), batch_size=batch_size, shuffle=True)
|
| 95 |
+
val_loader = DataLoader(TensorDataset(X_val_tensor, y_val_tensor), batch_size=batch_size, shuffle=False)
|
| 96 |
+
test_loader = DataLoader(TensorDataset(X_test_tensor, y_test_tensor), batch_size=batch_size, shuffle=False)
|
| 97 |
|
| 98 |
input_dim = X_train.shape[2] if X_train.ndim == 3 else 1
|
| 99 |
model = model_cls(input_size=input_dim, hidden_size=hidden, num_layers=layers, output_size=horizon, dropout=dropout).to(device)
|
| 100 |
optimizer = torch.optim.AdamW(model.parameters(), lr=lr, betas=(beta1, beta2), weight_decay=weight_decay)
|
| 101 |
loss_fn = nn.MSELoss()
|
| 102 |
+
scheduler = torch.optim.lr_scheduler.ReduceLROnPlateau(optimizer, mode='min', patience=5, factor=scheduler_factor, threshold=1e-4)
|
| 103 |
|
| 104 |
train_losses = []
|
| 105 |
val_losses = []
|
|
|
|
| 187 |
mda = mean_directional_accuracy(targets_inv, preds_inv)
|
| 188 |
|
| 189 |
result["metrics"] = {
|
| 190 |
+
"R² (%)": round(r2 * 100, 2),
|
| 191 |
+
"Explained Variance (%)": round(evs * 100, 2),
|
| 192 |
+
"MDA (%)": round(mda, 2) if not np.isnan(mda) else None,
|
| 193 |
+
"RMSE": round(rmse, 2),
|
| 194 |
+
"MAE": round(mae, 2),
|
| 195 |
+
"MAPE (%)": round(mape, 2) if not np.isnan(mape) else None,
|
| 196 |
+
"MASE": round(mase, 2) if not np.isnan(mase) else None
|
| 197 |
}
|
| 198 |
|
| 199 |
result["forecast"] = preds_inv
|
|
|
|
| 213 |
if not future_df.empty:
|
| 214 |
result["future_actuals"] = future_df['value'].values.tolist()[:horizon]
|
| 215 |
|
| 216 |
+
result["architecture"] = {
|
| 217 |
+
"model_name": model_cls.__name__,
|
| 218 |
+
"num_layers": layers,
|
| 219 |
+
"hidden_units": hidden,
|
| 220 |
+
"dropout": dropout,
|
| 221 |
+
"batch_size": batch_size,
|
| 222 |
+
"input_size": input_dim,
|
| 223 |
+
"output_size": horizon
|
| 224 |
+
}
|
| 225 |
+
|
| 226 |
return result
|