Spaces:
Runtime error
Runtime error
Update core/train_eval.py
Browse files- core/train_eval.py +14 -6
core/train_eval.py
CHANGED
|
@@ -22,22 +22,23 @@ def mean_absolute_percentage_error(y_true, y_pred):
|
|
| 22 |
y_true, y_pred = np.array(y_true), np.array(y_pred)
|
| 23 |
non_zero = np.abs(y_true) > 0
|
| 24 |
if np.sum(non_zero) == 0:
|
| 25 |
-
return np.nan
|
| 26 |
return np.mean(np.abs((y_true[non_zero] - y_pred[non_zero]) / y_true[non_zero])) * 100
|
| 27 |
|
| 28 |
|
| 29 |
def train_and_evaluate(
|
| 30 |
df,
|
|
|
|
| 31 |
model_cls,
|
| 32 |
horizon=1,
|
| 33 |
hidden=64,
|
| 34 |
layers=1,
|
| 35 |
epochs=50,
|
| 36 |
lr=0.001,
|
| 37 |
-
beta1=0.9,
|
| 38 |
-
beta2=0.999,
|
| 39 |
-
weight_decay=0.01,
|
| 40 |
-
dropout=0.2,
|
| 41 |
window=30,
|
| 42 |
test_split=0.2,
|
| 43 |
device="cuda" if torch.cuda.is_available() else "cpu",
|
|
@@ -76,6 +77,7 @@ def train_and_evaluate(
|
|
| 76 |
model = model_cls(input_size=input_dim, hidden_size=hidden, num_layers=layers, output_size=horizon, dropout=dropout).to(device)
|
| 77 |
optimizer = torch.optim.AdamW(model.parameters(), lr=lr, betas=(beta1, beta2), weight_decay=weight_decay)
|
| 78 |
loss_fn = nn.MSELoss()
|
|
|
|
| 79 |
|
| 80 |
train_losses = []
|
| 81 |
val_losses = []
|
|
@@ -108,8 +110,10 @@ def train_and_evaluate(
|
|
| 108 |
val_loss /= len(val_loader)
|
| 109 |
val_losses.append(val_loss)
|
| 110 |
|
|
|
|
|
|
|
| 111 |
if verbose and (epoch + 1) % 10 == 0:
|
| 112 |
-
print(f"Epoch {epoch+1}/{epochs} - Train Loss: {train_losses[-1]:.4f}, Val Loss: {val_losses[-1]:.4f}")
|
| 113 |
|
| 114 |
if val_loss < best_val_loss:
|
| 115 |
best_val_loss = val_loss
|
|
@@ -173,4 +177,8 @@ def train_and_evaluate(
|
|
| 173 |
|
| 174 |
result["latest_prediction"] = future_pred_inv[0].tolist()
|
| 175 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 176 |
return result
|
|
|
|
| 22 |
y_true, y_pred = np.array(y_true), np.array(y_pred)
|
| 23 |
non_zero = np.abs(y_true) > 0
|
| 24 |
if np.sum(non_zero) == 0:
|
| 25 |
+
return np.nan
|
| 26 |
return np.mean(np.abs((y_true[non_zero] - y_pred[non_zero]) / y_true[non_zero])) * 100
|
| 27 |
|
| 28 |
|
| 29 |
def train_and_evaluate(
|
| 30 |
df,
|
| 31 |
+
future_df, # Added
|
| 32 |
model_cls,
|
| 33 |
horizon=1,
|
| 34 |
hidden=64,
|
| 35 |
layers=1,
|
| 36 |
epochs=50,
|
| 37 |
lr=0.001,
|
| 38 |
+
beta1=0.9,
|
| 39 |
+
beta2=0.999,
|
| 40 |
+
weight_decay=0.01,
|
| 41 |
+
dropout=0.2,
|
| 42 |
window=30,
|
| 43 |
test_split=0.2,
|
| 44 |
device="cuda" if torch.cuda.is_available() else "cpu",
|
|
|
|
| 77 |
model = model_cls(input_size=input_dim, hidden_size=hidden, num_layers=layers, output_size=horizon, dropout=dropout).to(device)
|
| 78 |
optimizer = torch.optim.AdamW(model.parameters(), lr=lr, betas=(beta1, beta2), weight_decay=weight_decay)
|
| 79 |
loss_fn = nn.MSELoss()
|
| 80 |
+
scheduler = torch.optim.lr_scheduler.ReduceLROnPlateau(optimizer, mode='min', patience=5, factor=0.5, threshold=1e-4, verbose=True)
|
| 81 |
|
| 82 |
train_losses = []
|
| 83 |
val_losses = []
|
|
|
|
| 110 |
val_loss /= len(val_loader)
|
| 111 |
val_losses.append(val_loss)
|
| 112 |
|
| 113 |
+
scheduler.step(val_loss)
|
| 114 |
+
|
| 115 |
if verbose and (epoch + 1) % 10 == 0:
|
| 116 |
+
print(f"Epoch {epoch+1}/{epochs} - Train Loss: {train_losses[-1]:.4f}, Val Loss: {val_losses[-1]:.4f}, LR: {optimizer.param_groups[0]['lr']:.6f}")
|
| 117 |
|
| 118 |
if val_loss < best_val_loss:
|
| 119 |
best_val_loss = val_loss
|
|
|
|
| 177 |
|
| 178 |
result["latest_prediction"] = future_pred_inv[0].tolist()
|
| 179 |
|
| 180 |
+
# Include actual future values if available
|
| 181 |
+
if not future_df.empty:
|
| 182 |
+
result["future_actuals"] = future_df['value'].values.tolist()[:horizon]
|
| 183 |
+
|
| 184 |
return result
|