Normalization of loss functions based on max weight
17
analysis/PendulumController.py
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
import torch
|
||||||
|
import torch.nn as nn
|
||||||
|
|
||||||
|
class PendulumController(nn.Module):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
self.net = nn.Sequential(
|
||||||
|
nn.Linear(4, 64),
|
||||||
|
nn.ReLU(),
|
||||||
|
nn.Linear(64, 64),
|
||||||
|
nn.ReLU(),
|
||||||
|
nn.Linear(64, 1)
|
||||||
|
)
|
||||||
|
|
||||||
|
def forward(self, x):
|
||||||
|
raw_torque = self.net(x)
|
||||||
|
return torch.clamp(raw_torque, -250, 250)
|
||||||
BIN
analysis/__pycache__/PendulumController.cpython-310.pyc
Normal file
BIN
analysis/constant copy.png
Normal file
|
After Width: | Height: | Size: 4.8 MiB |
BIN
analysis/constant.png
Normal file
|
After Width: | Height: | Size: 1.1 MiB |
@ -7,19 +7,7 @@ from mpl_toolkits.mplot3d import Axes3D
|
|||||||
from multiprocessing import Pool, cpu_count
|
from multiprocessing import Pool, cpu_count
|
||||||
|
|
||||||
# Define PendulumController class
|
# Define PendulumController class
|
||||||
class PendulumController(nn.Module):
|
from PendulumController import PendulumController
|
||||||
def __init__(self):
|
|
||||||
super().__init__()
|
|
||||||
self.net = nn.Sequential(
|
|
||||||
nn.Linear(4, 64),
|
|
||||||
nn.ReLU(),
|
|
||||||
nn.Linear(64, 64),
|
|
||||||
nn.ReLU(),
|
|
||||||
nn.Linear(64, 1)
|
|
||||||
)
|
|
||||||
|
|
||||||
def forward(self, x):
|
|
||||||
return self.net(x)
|
|
||||||
|
|
||||||
# ODE solver (RK4 method)
|
# ODE solver (RK4 method)
|
||||||
def pendulum_ode_step(state, dt, desired_theta, controller):
|
def pendulum_ode_step(state, dt, desired_theta, controller):
|
||||||
@ -64,9 +52,9 @@ dt = 0.02 # Time step
|
|||||||
num_steps = 500 # Simulation time steps
|
num_steps = 500 # Simulation time steps
|
||||||
|
|
||||||
# Directory containing controller files
|
# Directory containing controller files
|
||||||
loss_function = "cubic_time_weight"
|
loss_function = "constant"
|
||||||
#controller_dir = f"/home/judson/Neural-Networks-in-GNC/inverted_pendulum/training/{loss_function}/controllers"
|
controller_dir = f"/home/judson/Neural-Networks-in-GNC/inverted_pendulum/training/normalized/training/{loss_function}/controllers"
|
||||||
controller_dir = f"C:/Users/Judson/Desktop/New Gitea/Neural-Networks-in-GNC/inverted_pendulum/training/{loss_function}/controllers"
|
#controller_dir = f"C:/Users/Judson/Desktop/New Gitea/Neural-Networks-in-GNC/inverted_pendulum/training/{loss_function}/controllers"
|
||||||
controller_files = sorted([f for f in os.listdir(controller_dir) if f.startswith("controller_") and f.endswith(".pth")])
|
controller_files = sorted([f for f in os.listdir(controller_dir) if f.startswith("controller_") and f.endswith(".pth")])
|
||||||
|
|
||||||
# Sorting controllers by epoch
|
# Sorting controllers by epoch
|
||||||
@ -74,7 +62,7 @@ controller_epochs = [int(f.split('_')[1].split('.')[0]) for f in controller_file
|
|||||||
sorted_controllers = [x for _, x in sorted(zip(controller_epochs, controller_files))]
|
sorted_controllers = [x for _, x in sorted(zip(controller_epochs, controller_files))]
|
||||||
|
|
||||||
# **Epoch Range Selection**
|
# **Epoch Range Selection**
|
||||||
epoch_range = (0, 100) # Set your desired range (e.g., (0, 5000) or (0, 100))
|
epoch_range = (0, 500) # Set your desired range (e.g., (0, 5000) or (0, 100))
|
||||||
|
|
||||||
filtered_controllers = [
|
filtered_controllers = [
|
||||||
f for f in sorted_controllers
|
f for f in sorted_controllers
|
||||||
@ -86,7 +74,8 @@ N = 1 # Change this value to adjust granularity (e.g., every 5th controller)
|
|||||||
selected_controllers = filtered_controllers[::N] # Take every Nth controller within the range
|
selected_controllers = filtered_controllers[::N] # Take every Nth controller within the range
|
||||||
|
|
||||||
# Initial condition
|
# Initial condition
|
||||||
theta0, omega0, alpha0, desired_theta = (-np.pi, 0, 0.0, 0.0) # Example initial condition
|
# theta0, omega0, alpha0, desired_theta = (-np.pi, -2*np.pi, 0.0, -1.3*np.pi) # Example initial condition
|
||||||
|
theta0, omega0, alpha0, desired_theta = (-np.pi, 0.0, 0.0, 0.0) # Example initial condition
|
||||||
|
|
||||||
# Parallel function must return epoch explicitly
|
# Parallel function must return epoch explicitly
|
||||||
def run_simulation(controller_file):
|
def run_simulation(controller_file):
|
||||||
@ -115,14 +104,13 @@ if __name__ == "__main__":
|
|||||||
with Pool(processes=num_workers) as pool:
|
with Pool(processes=num_workers) as pool:
|
||||||
results = pool.map(run_simulation, selected_controllers)
|
results = pool.map(run_simulation, selected_controllers)
|
||||||
|
|
||||||
# **Sort results by epoch to ensure correct order**
|
# Sort results by epoch to ensure correct order
|
||||||
results.sort(key=lambda x: x[0])
|
results.sort(key=lambda x: x[0])
|
||||||
epochs, theta_over_epochs = zip(*results) # Unzip sorted results
|
epochs, theta_over_epochs = zip(*results) # Unzip sorted results
|
||||||
|
|
||||||
# Convert results to NumPy arrays
|
# Convert results to NumPy arrays
|
||||||
theta_over_epochs = np.array(theta_over_epochs)
|
theta_over_epochs = np.array(theta_over_epochs)
|
||||||
|
|
||||||
|
|
||||||
# Create 3D line plot
|
# Create 3D line plot
|
||||||
fig = plt.figure(figsize=(10, 7))
|
fig = plt.figure(figsize=(10, 7))
|
||||||
ax = fig.add_subplot(111, projection='3d')
|
ax = fig.add_subplot(111, projection='3d')
|
||||||
@ -144,6 +132,15 @@ if __name__ == "__main__":
|
|||||||
ax.set_zlabel("Theta (rad)")
|
ax.set_zlabel("Theta (rad)")
|
||||||
ax.set_title(f"Pendulum Angle Evolution for {loss_function}")
|
ax.set_title(f"Pendulum Angle Evolution for {loss_function}")
|
||||||
|
|
||||||
|
# Add a horizontal line at desired_theta across all epochs and time steps
|
||||||
|
epochs_array = np.array([epoch for epoch, _ in zip(epochs, theta_over_epochs)])
|
||||||
|
ax.plot(
|
||||||
|
epochs_array, # X-axis spanning all epochs
|
||||||
|
[time_steps.max()] * len(epochs_array), # Y-axis at the maximum time step
|
||||||
|
[desired_theta] * len(epochs_array), # Constant Z-axis value of desired_theta
|
||||||
|
color='r', linestyle='--', linewidth=2, label='Desired Theta at End Time'
|
||||||
|
)
|
||||||
|
|
||||||
# Improve visibility
|
# Improve visibility
|
||||||
ax.view_init(elev=20, azim=-135) # Adjust 3D perspective
|
ax.view_init(elev=20, azim=-135) # Adjust 3D perspective
|
||||||
|
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 2.4 MiB After Width: | Height: | Size: 2.4 MiB |
|
Before Width: | Height: | Size: 2.3 MiB After Width: | Height: | Size: 2.3 MiB |
|
Before Width: | Height: | Size: 3.0 MiB After Width: | Height: | Size: 3.0 MiB |
|
Before Width: | Height: | Size: 2.9 MiB After Width: | Height: | Size: 2.9 MiB |
|
Before Width: | Height: | Size: 2.8 MiB After Width: | Height: | Size: 2.8 MiB |
|
Before Width: | Height: | Size: 2.6 MiB After Width: | Height: | Size: 2.6 MiB |