SMASIF

cGAN_WPT_20240920

Oct 25th, 2024 (edited)
258
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 7.80 KB | None | 0 0
  1. # Import necessary libraries
  2. import torch
  3. import numpy as np
  4. import pandas as pd
  5. from sklearn.preprocessing import MinMaxScaler
  6. from torch import nn
  7. from torch.optim import Adam
  8. from torch.optim.lr_scheduler import StepLR
  9. import time
  10. # Set random seeds for reproducibility
  11. np.random.seed(42)
  12. torch.manual_seed(42)
  13.  
  14. # Define device
  15. device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
  16.  
  17. # Load the dataset with incorrect geometry
  18. # incorrect_data = pd.read_csv(r'C:\Users\Andrew\PycharmProjects\pythonProject\Data\cleaned_mutual_inductance_dataset_9th_sept_correct_geometry.csv')
  19. incorrect_data = pd.read_csv(r'C:\Users\Andrew\PycharmProjects\pythonProject\Data\sorted_valid_samples_20240923.csv')
  20.  
  21. # Preprocess the data
  22. features = ['Final Mutual Inductance (nH)']
  23. target = ['Trace Width (Rx L mm)', 'Trace Thickness (Rx L mm)', 'Number of Turns (Rx L)',
  24.           'Trace Width (Rx L+C mm)', 'Trace Thickness (Rx L+C mm)', 'Number of Turns (Rx L+C)',
  25.           'Gap Between Segments (mm)', 'Center Area Percentage', 'Capacitor Area Length (mm)',
  26.           'Capacitor Area Width (mm)', 'Rx Coil Area Length (mm)', 'Rx Coil Area Width (mm)',
  27.           'Tx Coil Area Length (mm)', 'Tx Coil Area Width (mm)', 'Final Mutual Inductance (nH)']
  28.  
  29. # Extract features and target variables
  30. X_incorrect = incorrect_data[features].values
  31. y_incorrect = incorrect_data[target].values
  32.  
  33. # Normalize the data
  34. scaler_X = MinMaxScaler()
  35. scaler_y = MinMaxScaler()
  36. X_incorrect_scaled = scaler_X.fit_transform(X_incorrect)
  37. y_incorrect_scaled = scaler_y.fit_transform(y_incorrect)
  38.  
  39. # Convert to torch tensors
  40. X_incorrect_tensor = torch.tensor(X_incorrect_scaled, dtype=torch.float32).to(device)
  41. y_incorrect_tensor = torch.tensor(y_incorrect_scaled, dtype=torch.float32).to(device)
  42.  
  43. # Define the Generator model
  44. class Generator(nn.Module):
  45.     def __init__(self, input_dim, output_dim):
  46.         super(Generator, self).__init__()
  47.         self.model = nn.Sequential(
  48.             nn.Linear(input_dim, 128),
  49.             nn.LeakyReLU(0.2),
  50.             nn.BatchNorm1d(128),
  51.             nn.Linear(128, 256),
  52.             nn.LeakyReLU(0.2),
  53.             nn.BatchNorm1d(256),
  54.             nn.Linear(256, output_dim)
  55.         )
  56.         self.apply(self.weights_init)  # Apply weights initialization
  57.  
  58.     def forward(self, x):
  59.         return self.model(x)
  60.  
  61.     @staticmethod
  62.     def weights_init(m):
  63.         if isinstance(m, nn.Linear):
  64.             nn.init.xavier_uniform_(m.weight)  # Xavier initialization
  65.  
  66. # Define the Discriminator model
  67. class Discriminator(nn.Module):
  68.     def __init__(self, input_dim):
  69.         super(Discriminator, self).__init__()
  70.         self.model = nn.Sequential(
  71.             nn.Linear(input_dim, 256),
  72.             nn.LeakyReLU(0.2),
  73.             nn.Dropout(0.3),
  74.             nn.Linear(256, 128),
  75.             nn.LeakyReLU(0.2),
  76.             nn.Dropout(0.3),
  77.             nn.Linear(128, 1),
  78.             nn.Sigmoid()
  79.         )
  80.         self.apply(self.weights_init)  # Apply weights initialization
  81.  
  82.     def forward(self, x):
  83.         return self.model(x)
  84.  
  85.     @staticmethod
  86.     def weights_init(m):
  87.         if isinstance(m, nn.Linear):
  88.             nn.init.xavier_uniform_(m.weight)  # Xavier initialization
  89.  
  90. # Initialize models
  91. latent_dim = 100  # Dimension of the noise vector
  92. input_dim = latent_dim + X_incorrect_tensor.shape[1]  # Noise + input features
  93. output_dim = y_incorrect_tensor.shape[1]  # Design parameters output
  94.  
  95. generator = Generator(input_dim, output_dim).to(device)
  96. discriminator = Discriminator(output_dim + X_incorrect_tensor.shape[1]).to(device)
  97.  
  98. # Define the loss functions and optimizers
  99. loss_fn = nn.BCELoss()
  100. feature_matching_loss = nn.L1Loss()  # Feature matching loss
  101. optimizer_G = Adam(generator.parameters(), lr=0.0002)
  102. optimizer_D = Adam(discriminator.parameters(), lr=0.0002)
  103.  
  104. # Learning rate schedulers
  105. scheduler_G = StepLR(optimizer_G, step_size=1000, gamma=0.9)
  106. scheduler_D = StepLR(optimizer_D, step_size=1000, gamma=0.9)
  107.  
  108. # Training the cGAN
  109. num_epochs = 50000  # Adjust based on your needs
  110. batch_size = 8
  111. # Start time measurement for training
  112. start_time = time.time()
  113. for epoch in range(num_epochs):
  114.     # Train Discriminator
  115.     real_labels = torch.ones(batch_size, 1).to(device)
  116.     fake_labels = torch.zeros(batch_size, 1).to(device)
  117.  
  118.     # Sample real data
  119.     idx = np.random.randint(0, X_incorrect_tensor.size(0), batch_size)
  120.     real_data = y_incorrect_tensor[idx]
  121.     real_features = X_incorrect_tensor[idx]
  122.  
  123.     # Generate fake data
  124.     noise = torch.randn(batch_size, latent_dim).to(device)
  125.     generator_input = torch.cat((noise, real_features), dim=1)
  126.     fake_data = generator(generator_input)
  127.  
  128.     # Discriminator forward pass with real data
  129.     real_input = torch.cat((real_data, real_features), dim=1)
  130.     real_output = discriminator(real_input)
  131.     loss_real = loss_fn(real_output, real_labels)
  132.  
  133.     # Discriminator forward pass with fake data
  134.     fake_input = torch.cat((fake_data, real_features), dim=1)
  135.     fake_output = discriminator(fake_input.detach())
  136.     loss_fake = loss_fn(fake_output, fake_labels)
  137.  
  138.     # Discriminator loss and backprop
  139.     d_loss = loss_real + loss_fake
  140.     optimizer_D.zero_grad()
  141.     d_loss.backward()
  142.     optimizer_D.step()
  143.  
  144.     # Train Generator
  145.     fake_output = discriminator(fake_input)
  146.     g_loss = loss_fn(fake_output, real_labels)
  147.  
  148.     # Feature matching loss for Generator
  149.     feature_loss = feature_matching_loss(fake_data, real_data)
  150.     total_g_loss = g_loss + feature_loss
  151.  
  152.     optimizer_G.zero_grad()
  153.     total_g_loss.backward()
  154.     optimizer_G.step()
  155.  
  156.     # Step the learning rate schedulers
  157.     scheduler_G.step()
  158.     scheduler_D.step()
  159.  
  160.     if epoch % 100 == 0:
  161.         print(f"Epoch [{epoch}/{num_epochs}] | D Loss: {d_loss.item():.4f} | G Loss: {total_g_loss.item():.4f}")
  162. # End time measurement for training
  163. end_time = time.time()
  164.  
  165. # Calculate elapsed time in seconds
  166. elapsed_time = end_time - start_time
  167. elapsed_time_minutes = elapsed_time / 60
  168. print(f"Total time required to train the model: {elapsed_time:.2f} seconds ({elapsed_time_minutes:.2f} minutes)")
  169.  
  170. # Start time measurement for generation
  171. start_generation_time = time.time()
  172. # Generate new design samples
  173. num_samples = 100000
  174. noise = torch.randn(num_samples, latent_dim).to(device)
  175. input_indices = np.random.choice(X_incorrect_tensor.shape[0], num_samples, replace=True)
  176. input_features = X_incorrect_tensor[input_indices]
  177.  
  178. # Concatenate noise and input features for the generator
  179. generator_input = torch.cat((noise, input_features), dim=1)
  180.  
  181. # Generate design parameters
  182. generator.eval()
  183. with torch.no_grad():
  184.     generated_params = generator(generator_input)
  185. # End time measurement for generation
  186. end_generation_time = time.time()
  187.  
  188. # Calculate elapsed time for generation in seconds
  189. generation_time = end_generation_time - start_generation_time
  190. generation_time_minutes = generation_time / 60
  191. print(f"Time required to generate {num_samples} designs: {generation_time:.2f} seconds ({generation_time_minutes:.2f} minutes)")
  192. # Scale back to original values
  193. generated_params_np = generated_params.cpu().numpy()
  194. generated_params_original = scaler_y.inverse_transform(generated_params_np)
  195.  
  196. # Create DataFrame with generated parameters
  197. df_generated = pd.DataFrame(generated_params_original, columns=target)
  198.  
  199. # Convert the 'Final Mutual Inductance (H)' column to nH
  200. # df_generated['Final Mutual Inductance (nH)'] = df_generated['Final Mutual Inductance (H)'] * 1e9
  201.  
  202. # Drop the original 'Final Mutual Inductance (H)' column if not needed
  203. # df_generated.drop('Final Mutual Inductance (H)', axis=1, inplace=True)
  204.  
  205. # Save the generated WPT parameters to a CSV file
  206. df_generated.to_csv('generated_wpt_parameters_from_valid_samples_20240924_8.csv', index=False)
  207. print("Generated WPT parameters saved to 'generated_wpt_parameters.csv'.")
  208.  
Advertisement
Add Comment
Please, Sign In to add comment