diff options
author | Dennis Kobert <dennis@kobert.dev> | 2025-03-25 15:51:51 +0100 |
---|---|---|
committer | Dennis Kobert <dennis@kobert.dev> | 2025-03-25 15:52:04 +0100 |
commit | a7da9c7140181ab4ef4af5e5f3222ca44741d66a (patch) | |
tree | baf07ce81cf60ff43749dfa5eedfeb6ffe540b70 | |
parent | 7f49625ee1cfadaf523da9e2c247fded90d82665 (diff) |
Update ml script
-rw-r--r-- | power_predictor.py | 38 | ||||
-rw-r--r-- | src/benchmark.rs | 49 |
2 files changed, 67 insertions, 20 deletions
diff --git a/power_predictor.py b/power_predictor.py index 49e49fe..ca38498 100644 --- a/power_predictor.py +++ b/power_predictor.py @@ -14,6 +14,7 @@ import matplotlib.pyplot as plt def load_data(csv_path): # Read the CSV file df = pd.read_csv(csv_path) + df = df.sample(frac=1).reset_index(drop=True) # Extract target (power usage) y = df['package_power_j'].values @@ -82,8 +83,18 @@ class PowerEstimator(nn.Module): def __init__(self, input_size): super(PowerEstimator, self).__init__() self.model = nn.Sequential( + # nn.Linear(input_size, 128), + # nn.ReLU(), + # nn.Dropout(0.3), + # nn.Linear(128, 64), + # nn.ReLU(), + # nn.Dropout(0.2), + # nn.Linear(64, 32), + # nn.ReLU(), + # nn.Linear(32, 1) nn.Linear(input_size, 64), nn.ReLU(), + # // leaky relu nn.Dropout(0.2), nn.Linear(64, 32), nn.ReLU(), @@ -94,10 +105,12 @@ class PowerEstimator(nn.Module): return self.model(x) # Step 5: Train the model -def train_model(X, y, batch_size=32, epochs=100, lr=0.001): +def train_model(X, y, batch_size=32, epochs=100, lr=0.001, early_stopping_patience=10): # Split data into training and validation sets X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=42) + + # Scale the features scaler = StandardScaler() X_train_scaled = scaler.fit_transform(X_train) @@ -123,6 +136,9 @@ def train_model(X, y, batch_size=32, epochs=100, lr=0.001): # Training loop train_losses = [] val_losses = [] + best_val_loss = float('inf') + epochs_without_improvement = 0 + best_model_state = None for epoch in range(epochs): # Training @@ -150,10 +166,27 @@ def train_model(X, y, batch_size=32, epochs=100, lr=0.001): val_loss /= len(val_loader.dataset) val_losses.append(val_loss) + + # Early stopping check + if val_loss < best_val_loss: + best_val_loss = val_loss + best_model_state = model.state_dict().copy() + epochs_without_improvement = 0 + else: + epochs_without_improvement += 1 # Print progress if (epoch + 1) % 10 == 0: print(f"Epoch {epoch+1}/{epochs}, Train Loss: {train_loss:.6f}, Val Loss: {val_loss:.6f}") + + # Check early stopping + if epochs_without_improvement >= early_stopping_patience: + print(f"\nEarly stopping triggered after {epoch+1} epochs") + break + + # Load best model + if best_model_state is not None: + model.load_state_dict(best_model_state) # Plot training history plt.figure(figsize=(10, 5)) @@ -233,11 +266,12 @@ def main(): print("Loading data...") X, y = load_data(csv_path) - X, y = remove_outliers(X, y) # Impute missing values print("\nImputing missing values...") X_imputed = impute_missing_values(X) + + X_imputed, y = remove_outliers(X_imputed, y) # Analyze feature importance print("\nAnalyzing feature importance...") diff --git a/src/benchmark.rs b/src/benchmark.rs index 6368fa8..6487c7a 100644 --- a/src/benchmark.rs +++ b/src/benchmark.rs @@ -379,15 +379,15 @@ fn define_available_events() -> Vec<(String, Event)> { "cpu_cycles".to_string(), Event::Hardware(Hardware::CPU_CYCLES), ), - // ( - // "instructions".to_string(), - // Event::Hardware(Hardware::INSTRUCTIONS), - // ), ( - "cache_references".to_string(), - Event::Hardware(Hardware::CACHE_REFERENCES), + "instructions".to_string(), + Event::Hardware(Hardware::INSTRUCTIONS), ), // ( + // "cache_references".to_string(), + // Event::Hardware(Hardware::CACHE_REFERENCES), + // ), + // ( // "cache_misses".to_string(), // Event::Hardware(Hardware::CACHE_MISSES), // ), @@ -395,14 +395,18 @@ fn define_available_events() -> Vec<(String, Event)> { // "branch_instructions".to_string(), // Event::Hardware(Hardware::BRANCH_INSTRUCTIONS), // ), - ( - "branch_misses".to_string(), - Event::Hardware(Hardware::BRANCH_MISSES), - ), + // ( + // "branch_misses".to_string(), + // Event::Hardware(Hardware::BRANCH_MISSES), + // ), ( "ref_cpu_cycles".to_string(), Event::Hardware(Hardware::REF_CPU_CYCLES), ), + ( + "stalled-cycles-frontend".to_string(), + Event::Hardware(Hardware::STALLED_CYCLES_FRONTEND), + ), ]); // L1 Data Cache events @@ -415,16 +419,25 @@ fn define_available_events() -> Vec<(String, Event)> { // result: CacheResult::ACCESS, // }), // ), - ( - "l1d_read_miss".to_string(), - Event::Cache(Cache { - which: WhichCache::L1D, - operation: CacheOp::READ, - result: CacheResult::MISS, - }), - ), + // ( + // "l1d_read_miss".to_string(), + // Event::Cache(Cache { + // which: WhichCache::L1D, + // operation: CacheOp::READ, + // result: CacheResult::MISS, + // }), + // ), ]); + // events.push(( + // "fp_ops_retired_by_type.all".to_string(), + // Event::Raw(4, 0xFF0A), // EventCode 0x0A with UMask 0xFF + // )); + events.push(( + "sse_avx_ops_retired.all".to_string(), + Event::Raw(4, 0xFF0B), // EventCode 0x0B with UMask 0xFF + )); + // L1 Instruction Cache events events.extend([ // ( |