andrej-1985/HyperparameterTunning
0
1"""2π SIMPLE ML FRONTEND - DIRECT INTEGRATION3=========================================4Benutzer setzt Parameter β Training startet β Ergebnisse anzeigen5"""6 7import streamlit as st8import plotly.graph_objects as go9import plotly.express as px10import pandas as pd11import numpy as np12import time13import json14from typing import Dict, Any15import threading16import queue17 18# Import deiner Original-Klassen (angepasst)19import os20import logging21from sklearn.datasets import load_diabetes22from sklearn.model_selection import train_test_split23from sklearn.preprocessing import StandardScaler24from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score as sklearn_r225import tensorflow as tf26import keras27from keras.optimizers import Adam28from keras.layers import Dense, Dropout29from keras.models import Sequential30from keras.callbacks import EarlyStopping, ReduceLROnPlateau, ModelCheckpoint31from keras.regularizers import l232from datetime import datetime33 34# Setup Logging35logging.basicConfig(level=logging.INFO)36logger = logging.getLogger(__name__)37 38class StreamlitMLTrainer:39 """40 π― VEREINFACHTE ML-KLASSE FΓR STREAMLIT INTEGRATION41 Basiert auf deiner Original-Logik + UI-Updates42 """43 44 def __init__(self):45 self.model = None46 self.scaler = None47 self.y_scaler = None48 self.history = None49 self.training_active = False50 51 # UI Update Queue52 if 'training_queue' not in st.session_state:53 st.session_state.training_queue = queue.Queue()54 if 'training_logs' not in st.session_state:55 st.session_state.training_logs = []56 57 def log_to_ui(self, message: str):58 """π Sende Log-Message an UI"""59 st.session_state.training_logs.append(f"{datetime.now().strftime('%H:%M:%S')} - {message}")60 # Nur letzte 50 Logs behalten61 if len(st.session_state.training_logs) > 50:62 st.session_state.training_logs = st.session_state.training_logs[-50:]63 64 def load_and_preprocess_data(self, test_size: float = 0.2, val_size: float = 0.2):65 """π Daten laden und vorverarbeiten"""66 self.log_to_ui("π Lade Diabetes-Dataset...")67 68 # Original Logik aus deinem Code69 dataset = load_diabetes()70 X, y = dataset.data, dataset.target.reshape(-1, 1)71 72 self.log_to_ui(f"β
Dataset geladen: {X.shape[0]} Samples, {X.shape[1]} Features")73 74 # Splits75 X_temp, X_test, y_temp, y_test = train_test_split(76 X, y, test_size=test_size, random_state=4277 )78 X_train, X_val, y_train, y_val = train_test_split(79 X_temp, y_temp, test_size=val_size, random_state=4280 )81 82 # Standardisierung83 self.scaler = StandardScaler()84 X_train_scaled = self.scaler.fit_transform(X_train).astype(np.float32)85 X_val_scaled = self.scaler.transform(X_val).astype(np.float32)86 X_test_scaled = self.scaler.transform(X_test).astype(np.float32)87 88 self.y_scaler = StandardScaler()89 y_train_scaled = self.y_scaler.fit_transform(y_train).astype(np.float32)90 y_val_scaled = self.y_scaler.transform(y_val).astype(np.float32)91 y_test_scaled = self.y_scaler.transform(y_test).astype(np.float32)92 93 self.log_to_ui(f"π Daten verarbeitet: {len(X_train)} Train, {len(X_val)} Val, {len(X_test)} Test")94 95 return (X_train_scaled, y_train_scaled), (X_val_scaled, y_val_scaled), (X_test_scaled, y_test_scaled)96 97 def build_model(self, hidden_layers: list, dropout_rate: float, l2_reg: float, learning_rate: float):98 """ποΈ Modell erstellen"""99 self.log_to_ui(f"ποΈ Erstelle Modell: {len(hidden_layers)} Hidden Layers {hidden_layers}")100 101 model = Sequential(name="StreamlitDiabetesRegression")102 103 # Hidden Layers104 for i, units in enumerate(hidden_layers):105 if i == 0:106 model.add(Dense(107 units=units, input_shape=(10,),108 activation='relu', kernel_initializer='he_normal',109 kernel_regularizer=l2(l2_reg)110 ))111 else:112 model.add(Dense(113 units=units, activation='relu',114 kernel_initializer='he_normal',115 kernel_regularizer=l2(l2_reg)116 ))117 118 model.add(Dropout(dropout_rate))119 120 # Output Layer121 model.add(Dense(1, kernel_initializer='he_normal'))122 123 # Kompilieren124 model.compile(125 optimizer=Adam(learning_rate=learning_rate),126 loss='mse',127 metrics=['mae']128 )129 130 total_params = model.count_params()131 self.log_to_ui(f"β
Modell erstellt: {total_params:,} Parameter")132 133 return model134 135 def train_model_with_ui_updates(self, model, train_data, val_data,136 max_epochs: int, batch_size: int, patience: int):137 """π Training mit Live-UI-Updates"""138 139 X_train, y_train = train_data140 X_val, y_val = val_data141 142 self.log_to_ui(f"π Starte Training: {max_epochs} max Epochs, Batch Size {batch_size}")143 144 # Custom Callback fΓΌr UI-Updates145 class StreamlitCallback(keras.callbacks.Callback):146 def __init__(self, ui_logger):147 self.ui_logger = ui_logger148 self.start_time = time.time()149 150 def on_epoch_end(self, epoch, logs=None):151 # Nur jede 5. Epoch fΓΌr Performance152 if (epoch + 1) % 5 == 0 or epoch < 10:153 elapsed = time.time() - self.start_time154 self.ui_logger(155 f"π Epoch {epoch+1}: Loss={logs['loss']:.4f}, "156 f"Val_Loss={logs['val_loss']:.4f}, Zeit={elapsed:.1f}s"157 )158 159 def on_train_end(self, logs=None):160 total_time = time.time() - self.start_time161 self.ui_logger(f"β
Training beendet nach {total_time:.1f} Sekunden")162 163 # Callbacks164 callbacks = [165 StreamlitCallback(self.log_to_ui),166 EarlyStopping(monitor='val_loss', patience=patience, restore_best_weights=True, verbose=0),167 ReduceLROnPlateau(monitor='val_loss', factor=0.5, patience=patience//2, min_lr=1e-7, verbose=0)168 ]169 170 # Training171 self.history = model.fit(172 X_train, y_train,173 batch_size=batch_size,174 epochs=max_epochs,175 validation_data=(X_val, y_val),176 callbacks=callbacks,177 verbose=0 # UI ΓΌbernimmt Output178 )179 180 return model181 182 def evaluate_model_with_ui(self, model, test_data):183 """π Evaluation mit UI-Feedback"""184 self.log_to_ui("π― Starte Modell-Evaluierung...")185 186 X_test, y_test = test_data187 y_pred_scaled = model.predict(X_test, verbose=0)188 189 # ZurΓΌck-transformieren fΓΌr echte Metriken190 y_test_original = self.y_scaler.inverse_transform(y_test)191 y_pred_original = self.y_scaler.inverse_transform(y_pred_scaled)192 193 # Metriken berechnen194 results = {195 'mse': float(mean_squared_error(y_test_original, y_pred_original)),196 'rmse': float(np.sqrt(mean_squared_error(y_test_original, y_pred_original))),197 'mae': float(mean_absolute_error(y_test_original, y_pred_original)),198 'r2': float(sklearn_r2(y_test_original, y_pred_original)),199 'mape': float(np.mean(np.abs((y_test_original - y_pred_original) / y_test_original)) * 100),200 'test_samples': len(y_test),201 'y_true': y_test_original.flatten(),202 'y_pred': y_pred_original.flatten()203 }204 205 self.log_to_ui(f"π― Evaluierung abgeschlossen: RΒ²={results['r2']:.4f}, MSE={results['mse']:.1f}")206 207 return results208 209 def run_complete_training(self, config: Dict[str, Any]) -> Dict[str, Any]:210 """π― Komplettes Training Pipeline"""211 try:212 # Reset213 st.session_state.training_logs = []214 self.training_active = True215 216 # 1. Daten laden217 train_data, val_data, test_data = self.load_and_preprocess_data(218 config['test_size'], config['validation_size']219 )220 221 # 2. Modell erstellen222 self.model = self.build_model(223 config['hidden_layers'],224 config['dropout_rate'],225 config['l2_reg'],226 config['learning_rate']227 )228 229 # 3. Training230 self.model = self.train_model_with_ui_updates(231 self.model, train_data, val_data,232 config['max_epochs'], config['batch_size'], config['patience']233 )234 235 # 4. Evaluation236 results = self.evaluate_model_with_ui(self.model, test_data)237 238 self.training_active = False239 self.log_to_ui("π Pipeline komplett abgeschlossen!")240 241 return results242 243 except Exception as e:244 self.training_active = False245 self.log_to_ui(f"β Fehler: {e}")246 return {"error": str(e)}247 248# ============================================================================249# STREAMLIT UI APPLICATION250# ============================================================================251 252def main():253 """π Hauptanwendung"""254 255 st.set_page_config(256 page_title="π ML Hyperparameter Tuning",257 page_icon="π",258 layout="wide"259 )260 261 st.title("π ML Hyperparameter Tuning & Training")262 st.markdown("**Set Parameters β Start Training β View Results**")263 264 # Initialize Trainer265 if 'trainer' not in st.session_state:266 st.session_state.trainer = StreamlitMLTrainer()267 268 # βοΈ SIDEBAR: Hyperparameter Configuration269 st.sidebar.header("βοΈ Hyperparameter Configuration")270 271 # Model Architecture272 with st.sidebar.expander("ποΈ Model Architecture", expanded=True):273 num_layers = st.slider("Anzahl Hidden Layers", 1, 5, 3)274 275 hidden_layers = []276 for i in range(num_layers):277 units = st.slider(278 f"Layer {i+1} Neurons", 8, 256,279 [128, 64, 32, 16, 8][i] if i < 5 else 16,280 step=8, key=f"layer_{i}"281 )282 hidden_layers.append(units)283 284 # Regularization285 with st.sidebar.expander("π‘οΈ Regularization", expanded=True):286 dropout_rate = st.slider("Dropout Rate", 0.0, 0.8, 0.3, 0.05)287 l2_reg = st.slider("L2 Regularization", 0.0, 0.1, 0.01, 0.005)288 289 # Training Parameters290 with st.sidebar.expander("π― Training Parameters", expanded=True):291 learning_rate = st.selectbox("Learning Rate", [0.01, 0.005, 0.001, 0.0005], index=2)292 batch_size = st.selectbox("Batch Size", [16, 32, 64, 128], index=1)293 max_epochs = st.slider("Max Epochs", 100, 2000, 1000, 100)294 patience = st.slider("Early Stopping Patience", 10, 100, 50, 10)295 test_size = st.slider("Test Size", 0.1, 0.3, 0.2, 0.05)296 validation_size = st.slider("Validation Size", 0.1, 0.3, 0.2, 0.05)297 298 # Sammle alle Parameter299 config = {300 'hidden_layers': hidden_layers,301 'dropout_rate': dropout_rate,302 'l2_reg': l2_reg,303 'learning_rate': learning_rate,304 'batch_size': batch_size,305 'max_epochs': max_epochs,306 'patience': patience,307 'test_size': test_size,308 'validation_size': validation_size309 }310 311 # ποΈ MAIN AREA: Tabs fΓΌr verschiedene Bereiche312 tab1, tab2, tab3 = st.tabs(["ποΈ Model Preview", "π Training", "π Results"])313 314 # ============================================================================315 # TAB 1: MODEL PREVIEW316 # ============================================================================317 with tab1:318 st.header("ποΈ Model Architecture Preview")319 320 col1, col2 = st.columns([2, 1])321 322 with col1:323 # Visualisiere Architektur324 fig = go.Figure()325 326 layers = ["Input (10)"] + [f"Hidden {i+1} ({units})" for i, units in enumerate(hidden_layers)] + ["Output (1)"]327 328 for i, layer_name in enumerate(layers):329 color = "lightblue" if i == 0 else ("lightcoral" if i == len(layers)-1 else "lightgreen")330 331 fig.add_shape(332 type="rect", x0=0, y0=i*1.2, x1=3, y1=i*1.2+1,333 fillcolor=color, line=dict(color="black", width=1)334 )335 336 fig.add_annotation(337 x=1.5, y=i*1.2+0.5, text=layer_name,338 showarrow=False, font=dict(size=12)339 )340 341 fig.update_layout(342 title="ποΈ Neural Network Architecture",343 xaxis=dict(visible=False), yaxis=dict(visible=False),344 height=400, showlegend=False345 )346 347 st.plotly_chart(fig, use_container_width=True)348 349 with col2:350 # Parameter Summary351 total_params = sum([10 * hidden_layers[0]] +352 [hidden_layers[i] * hidden_layers[i+1] for i in range(len(hidden_layers)-1)] +353 [hidden_layers[-1]])354 355 st.metric("π’ Est. Parameters", f"{total_params:,}")356 st.metric("π‘οΈ Dropout Rate", f"{dropout_rate:.1%}")357 st.metric("β‘ Learning Rate", f"{learning_rate}")358 st.metric("π¦ Batch Size", batch_size)359 st.metric("π― Max Epochs", max_epochs)360 st.metric("βΈοΈ Patience", patience)361 362 # ============================================================================363 # TAB 2: TRAINING INTERFACE364 # ============================================================================365 with tab2:366 st.header("π Training Interface")367 368 # Training Button369 col1, col2, col3 = st.columns([1, 1, 1])370 371 with col1:372 if st.button("π Start Training", type="primary",373 disabled=st.session_state.get('training_active', False)):374 375 st.session_state.training_active = True376 st.session_state.training_logs = []377 st.session_state.results = None378 379 # Starte Training380 with st.spinner("π Training lΓ€uft..."):381 results = st.session_state.trainer.run_complete_training(config)382 st.session_state.results = results383 st.session_state.training_active = False384 385 if 'error' not in results:386 st.success("β
Training erfolgreich abgeschlossen!")387 st.balloons() # π Celebration!388 else:389 st.error(f"β Training fehlgeschlagen: {results['error']}")390 391 with col2:392 if st.button("π§Ή Clear Logs"):393 st.session_state.training_logs = []394 395 with col3:396 if st.button("βΉοΈ Stop Training"):397 st.session_state.training_active = False398 st.warning("βΈοΈ Training gestoppt (nicht implementiert)")399 400 # Training Status401 if st.session_state.get('training_active', False):402 st.info("π Training lΓ€uft... Bitte warten.")403 404 # Progress Animation405 progress_bar = st.progress(0)406 status_text = st.empty()407 408 # Simuliere Progress (da echtes Training zu schnell fΓΌr UI)409 for i in range(100):410 progress_bar.progress(i + 1)411 status_text.text(f"Training Progress: {i+1}%")412 time.sleep(0.05) # 5 Sekunden total413 414 # Live Training Logs415 st.subheader("π Training Logs")416 417 if st.session_state.training_logs:418 # Container fΓΌr Logs (Auto-Scroll)419 log_container = st.container()420 with log_container:421 # Zeige neueste Logs zuerst422 for log in reversed(st.session_state.training_logs[-20:]):423 st.text(log)424 else:425 st.info("π― Klicke 'Start Training' um Logs zu sehen...")426 427 # ============================================================================428 # TAB 3: RESULTS DASHBOARD429 # ============================================================================430 with tab3:431 st.header("π Training Results Dashboard")432 433 if not st.session_state.get('results') or 'error' in st.session_state.get('results', {}):434 st.info("π― Starte Training um Ergebnisse zu sehen...")435 return436 437 results = st.session_state.results438 439 # π Key Metrics440 st.subheader("π Performance Metrics")441 442 col1, col2, col3, col4, col5 = st.columns(5)443 444 with col1:445 delta_r2 = f"+{(results['r2'] - 0.49)*100:.1f}%" if results['r2'] > 0.49 else None446 st.metric("π― RΒ² Score", f"{results['r2']:.4f}", delta_r2)447 448 with col2:449 st.metric("π MSE", f"{results['mse']:.1f}")450 451 with col3:452 st.metric("π RMSE", f"{results['rmse']:.1f}")453 454 with col4:455 st.metric("π MAE", f"{results['mae']:.1f}")456 457 with col5:458 st.metric("π MAPE", f"{results['mape']:.1f}%")459 460 # π Visualizations461 col1, col2 = st.columns(2)462 463 with col1:464 # Prediction vs Actual Scatter Plot465 fig_scatter = px.scatter(466 x=results['y_true'], y=results['y_pred'],467 labels={'x': 'Actual Values', 'y': 'Predicted Values'},468 title="π― Predictions vs Actual Values"469 )470 471 # Perfekte Vorhersage-Linie472 min_val, max_val = min(results['y_true']), max(results['y_true'])473 fig_scatter.add_trace(go.Scatter(474 x=[min_val, max_val], y=[min_val, max_val],475 mode='lines', name='Perfect Prediction',476 line=dict(color='red', dash='dash')477 ))478 479 st.plotly_chart(fig_scatter, use_container_width=True)480 481 with col2:482 # Performance Gauge483 fig_gauge = go.Figure(go.Indicator(484 mode="gauge+number+delta",485 value=results['r2'],486 domain={'x': [0, 1], 'y': [0, 1]},487 title={'text': "π― RΒ² Performance"},488 delta={'reference': 0.49},489 gauge={490 'axis': {'range': [0, 1]},491 'bar': {'color': "darkblue"},492 'steps': [493 {'range': [0, 0.4], 'color': "lightgray"},494 {'range': [0.4, 0.6], 'color': "yellow"},495 {'range': [0.6, 0.8], 'color': "lightgreen"},496 {'range': [0.8, 1.0], 'color': "green"}497 ],498 'threshold': {499 'line': {'color': "red", 'width': 4},500 'thickness': 0.75, 'value': 0.65501 }502 }503 ))504 505 st.plotly_chart(fig_gauge, use_container_width=True)506 507 # π Training History508 if st.session_state.trainer.history:509 st.subheader("π Training History")510 511 history_df = pd.DataFrame(st.session_state.trainer.history.history)512 513 fig_history = go.Figure()514 fig_history.add_trace(go.Scatter(515 x=list(range(len(history_df))),516 y=history_df['loss'],517 mode='lines',518 name='Training Loss',519 line=dict(color='blue')520 ))521 fig_history.add_trace(go.Scatter(522 x=list(range(len(history_df))),523 y=history_df['val_loss'],524 mode='lines',525 name='Validation Loss',526 line=dict(color='red')527 ))528 529 fig_history.update_layout(530 title="π Training & Validation Loss",531 xaxis_title="Epochs",532 yaxis_title="Loss",533 height=400534 )535 536 st.plotly_chart(fig_history, use_container_width=True)537 538 # π Detailed Results Table539 st.subheader("π Detailed Results")540 541 results_data = {542 'Metric': ['RΒ² Score', 'Mean Squared Error', 'Root MSE', 'Mean Absolute Error', 'MAPE', 'Test Samples'],543 'Value': [544 f"{results['r2']:.4f}",545 f"{results['mse']:.2f}",546 f"{results['rmse']:.2f}",547 f"{results['mae']:.2f}",548 f"{results['mape']:.1f}%",549 f"{results['test_samples']}"550 ],551 'Status': [552 'π― Excellent' if results['r2'] > 0.6 else 'β
Good' if results['r2'] > 0.4 else 'β οΈ Poor',553 'β
Good' if results['mse'] < 3000 else 'β οΈ High',554 'β
Good' if results['rmse'] < 55 else 'β οΈ High',555 'β
Good' if results['mae'] < 45 else 'β οΈ High',556 'β
Good' if results['mape'] < 20 else 'β οΈ High',557 'π Info'558 ]559 }560 561 st.dataframe(pd.DataFrame(results_data), use_container_width=True)562 563 # πΎ Download Results564 if st.button("πΎ Download Results JSON"):565 results_json = json.dumps({566 'config': config,567 'results': results,568 'timestamp': datetime.now().isoformat()569 }, indent=2)570 571 st.download_button(572 "π Download",573 results_json,574 f"ml_results_{int(time.time())}.json",575 "application/json"576 )577 578if __name__ == "__main__":579 main()580 581"""582π― SIMPLE & DIRECT APPROACH:583===========================584 585β
**Eine Datei** - Alles in einem586β
**Direkte Integration** - Keine komplexe MVC-Struktur587β
**Live Training Updates** - Callback direkt in UI588β
**Automatisches Training** - Button β Training β Ergebnisse589β
**SchΓΆne Results UI** - Plots, Metriken, Downloads590β
**Deine Original-Logik** - Komplett erhalten591 592π **Usage:**5931. Speichern als: streamlit_ml_app.py5942. Run: streamlit run streamlit_ml_app.py5953. Set Parameters β Click Training β View Results596 597π‘ **Features:**598- Dynamic Hyperparameter Tuning599- Real-time Training Logs600- Interactive Results Dashboard601- Model Architecture Visualization602- Results Export Functionality603- Progress Tracking604"""605 