import optuna import torch import torch.nn as nn import torch.optim as optim from torch.utils.data import DataLoader, TensorDataset import pandas as pd import numpy as np from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler import matplotlib.pyplot as plt import os script_path = os.path.abspath(__file__) script_dir = os.path.dirname(script_path) os.chdir(script_dir) device = torch.device("cuda" if torch.cuda.is_available() else "cpu") print(f"Using device: {device}") data = pd.read_csv('data.csv') X = data.drop(columns=['OS.time']).values y = data['OS.time'].values scaler = StandardScaler() X_scaled = scaler.fit_transform(X) X_train, X_test, y_train, y_test = train_test_split(X_scaled, y, test_size=0.2, random_state=42) X_train_tensor = torch.tensor(X_train, dtype=torch.float32).to(device) y_train_tensor = torch.tensor(y_train, dtype=torch.float32).view(-1, 1).to(device) X_test_tensor = torch.tensor(X_test, dtype=torch.float32).to(device) y_test_tensor = torch.tensor(y_test, dtype=torch.float32).view(-1, 1).to(device) train_dataset = TensorDataset(X_train_tensor, y_train_tensor) test_dataset = TensorDataset(X_test_tensor, y_test_tensor) train_loader = DataLoader(train_dataset, batch_size=32, shuffle=True) test_loader = DataLoader(test_dataset, batch_size=32, shuffle=False) class SimpleNN(nn.Module): def __init__(self, input_dim, hidden_dim, num_layers, dropout_rate): super(SimpleNN, self).__init__() self.layers = nn.ModuleList() last_dim = input_dim for _ in range(num_layers): self.layers.append(nn.Linear(last_dim, hidden_dim)) self.layers.append(nn.ReLU()) self.layers.append(nn.Dropout(dropout_rate)) last_dim = hidden_dim self.layers.append(nn.Linear(last_dim, 1)) def forward(self, x): for layer in self.layers: x = layer(x) return x def weights_init(m): if isinstance(m, nn.Linear): nn.init.kaiming_uniform_(m.weight) nn.init.zeros_(m.bias) def objective(trial): num_layers = trial.suggest_int('num_layers', 2, 5) hidden_dim = trial.suggest_int('hidden_dim', 50, 200) dropout_rate = trial.suggest_float('dropout_rate', 0.2, 0.5) momentum = trial.suggest_float('momentum', 0.5, 0.9) num_epochs = trial.suggest_int('num_epochs', 6000, 10000) model = SimpleNN(X_train.shape[1], hidden_dim, num_layers, dropout_rate).to(device) model.apply(weights_init) criterion = nn.MSELoss() optimizer = optim.SGD(model.parameters(), lr=0.0001, momentum=momentum) for epoch in range(num_epochs): model.train() for inputs, targets in train_loader: optimizer.zero_grad() outputs = model(inputs) loss = criterion(outputs, targets) loss.backward() torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0) optimizer.step() model.eval() test_loss = 0 with torch.no_grad(): for inputs, targets in test_loader: outputs = model(inputs) test_loss += criterion(outputs, targets).item() * inputs.size(0) test_loss /= len(test_loader.dataset) trial.report(test_loss, epoch) if trial.should_prune(): raise optuna.exceptions.TrialPruned() return test_loss study = optuna.create_study(direction='minimize') study.optimize(objective, n_trials=200) print(f"Best trial parameters: {study.best_trial.params}") print(f"Best trial test loss: {study.best_trial.value}") import optuna.visualization as vis vis.plot_param_importances(study).show() vis.plot_parallel_coordinate(study).show() best_params = study.best_trial.params model = SimpleNN(X_train.shape[1], best_params['hidden_dim'], best_params['num_layers'], best_params['dropout_rate']).to(device) model.apply(weights_init) criterion = nn.MSELoss() optimizer = optim.SGD(model.parameters(), lr=0.0001, momentum=best_params['momentum']) test_losses = [] for epoch in range(best_params['num_epochs']): model.train() for inputs, targets in train_loader: optimizer.zero_grad() outputs = model(inputs) loss = criterion(outputs, targets) loss.backward() torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0) optimizer.step() model.eval() test_loss = 0 with torch.no_grad(): for inputs, targets in test_loader: outputs = model(inputs) test_loss += criterion(outputs, targets).item() * inputs.size(0) test_loss /= len(test_loader.dataset) if epoch % 100 == 0: test_losses.append(test_loss) print(f'Epoch {epoch+1}, Test Loss: {test_loss}') print("Training completed with best hyperparameters.") plt.figure(figsize=(10, 5)) plt.plot(range(1, len(test_losses) * 100, 100), test_losses, label='Test Loss') plt.xlabel('Epoch') plt.ylabel('Test Loss') plt.title('Test Loss over Epochs') plt.legend() plt.show()