Register
Login
Resources
Docs Blog Datasets Glossary Case Studies Tutorials & Webinars
Product
Data Engine LLMs Platform Enterprise
Pricing Explore
Connect to our Discord channel

rmv_dimension_runner.py 8.8 KB

You have to be logged in to leave a comment. Sign In
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
  1. """
  2. This is the first ablation study, of removing a state dimension of the z-plane during testing.
  3. """
  4. import numpy as np
  5. import pandas as pd
  6. import tensorflow as tf
  7. from keras.layers import Dense
  8. from sklearn.preprocessing import MinMaxScaler
  9. import dagshub
  10. import mlflow
  11. import mlflow.keras
  12. import pickle
  13. import matplotlib.pyplot as plt
  14. mlflow.set_tracking_uri('https://dagshub.com/ML-Purdue/hackathonf23-Stacks.mlflow')
  15. dagshub.init(repo_owner='ML-Purdue', repo_name='hackathonf23-Stacks', mlflow=True)
  16. def get_or_create_experiment_id(name):
  17. exp = mlflow.get_experiment_by_name(name)
  18. if exp is None:
  19. exp_id = mlflow.create_experiment(name)
  20. return exp_id
  21. return exp.experiment_id
  22. class MaxEntIRLReduced:
  23. def __init__(self, state_dim):
  24. self.state_dim = state_dim
  25. self.model = self._create_irl_model()
  26. def _create_irl_model(self):
  27. model = tf.keras.Sequential([
  28. Dense(self.state_dim, input_shape=(self.state_dim,), activation='relu'),
  29. Dense(4096, activation='relu'),
  30. Dense(2048, activation='relu'),
  31. Dense(self.state_dim, activation='linear')
  32. ])
  33. return model
  34. def generateHumanTrajectories(self, num_trajectories, trajectory_length):
  35. human_trajectories = []
  36. for _ in range(num_trajectories):
  37. trajectory = []
  38. state = np.zeros(self.state_dim)
  39. for _ in range(trajectory_length):
  40. direction_probabilities = self._generate_direction_probabilities() # Get direction probabilities
  41. action_coefficients = np.random.choice([-1, 0, 1], p=direction_probabilities)
  42. action = action_coefficients * 0.1
  43. new_state = state[:2] + action # Reduced state by removing the z-direction
  44. trajectory.append((state, action))
  45. state = np.append(new_state, 0) # Pad the state to the original dimension
  46. human_trajectories.append(trajectory)
  47. return human_trajectories
  48. def _generate_direction_probabilities(self):
  49. probabilities = np.random.dirichlet(np.ones(self.state_dim) * 0.1)
  50. return probabilities
  51. def loadDataset(self, file_path):
  52. data = pd.read_csv(file_path) # Load CSV data
  53. scaler = MinMaxScaler()
  54. columns_to_normalize = ['position x [mm]', 'position y [mm]', 'velocity [mm/s]']
  55. data = data[['position x [mm]', 'position y [mm]', 'velocity [mm/s]']]
  56. data[columns_to_normalize] = scaler.fit_transform(data[columns_to_normalize])
  57. return data
  58. def train_irl_with_dataset(self, data, lr=0.001, epochs=3):
  59. state_dim = self.state_dim
  60. optimizer = tf.keras.optimizers.Adam(learning_rate=lr)
  61. # Extract relevant columns from the loaded dataset
  62. positions = data[['position x [mm]', 'position y [mm]']].values # Removed z-direction
  63. velocities = data['velocity [mm/s]'].values
  64. mlflow.tensorflow.autolog()
  65. with mlflow.start_run(experiment_id=get_or_create_experiment_id("Ablation Study 1: Removed Dimension")):
  66. for epoch in range(epochs):
  67. total_loss = 0
  68. state_frequencies = self._calculate_state_frequencies(positions)
  69. for idx in range(len(positions)):
  70. state = positions[idx]
  71. velocity = velocities[idx]
  72. with tf.GradientTape() as tape:
  73. preferences = self.model(state[np.newaxis, :])
  74. prob_human = tf.nn.softmax(preferences)
  75. # Define losses
  76. max_entropy_loss = -tf.reduce_sum(prob_human * tf.math.log(prob_human + 1e-8), axis=1)
  77. alignment_loss = -tf.reduce_sum(state_frequencies * tf.math.log(prob_human + 1e-8), axis=1)
  78. maxent_irl_objective = max_entropy_loss + alignment_loss
  79. # Compute the gradients
  80. grads = tape.gradient(maxent_irl_objective, self.model.trainable_variables)
  81. optimizer.apply_gradients(zip(grads, self.model.trainable_variables))
  82. total_loss += tf.reduce_sum(maxent_irl_objective) # Accumulate the total loss
  83. avg_loss = total_loss / len(positions)
  84. mlflow.log_metric(f"loss", avg_loss, step=epoch)
  85. print(f"Epoch {epoch + 1}/{epochs}, MaxEnt IRL Loss: {avg_loss}")
  86. def train_irl(self, human_trajectories=None, data=None, use_dataset=False, lr=0.001, epochs=3):
  87. if use_dataset and data is not None:
  88. # Train using the loaded dataset
  89. self.train_irl_with_dataset(data, lr=lr, epochs=epochs)
  90. else:
  91. # Train using the generative function
  92. if human_trajectories is None:
  93. human_trajectories = self.generateHumanTrajectories(num_trajectories, trajectory_length)
  94. self._train_irl_generative(human_trajectories, lr=lr, epochs=epochs)
  95. def _train_irl_generative(self, human_trajectories, lr=0.001, epochs=3):
  96. trajectory_length = len(human_trajectories[0])
  97. optimizer = tf.keras.optimizers.Adam(learning_rate=lr)
  98. for epoch in range(epochs):
  99. total_loss = 0
  100. state_frequencies = self._calculate_state_frequencies(human_trajectories, trajectory_length)
  101. for trajectory in human_trajectories:
  102. for state, _ in trajectory:
  103. with tf.GradientTape() as tape:
  104. preferences = self.model(state[np.newaxis, :])
  105. prob_human = tf.nn.softmax(preferences)
  106. # Inside the training loop:
  107. max_entropy_loss = -tf.reduce_sum(prob_human * tf.math.log(prob_human + 1e-8), axis=1)
  108. alignment_loss = -tf.reduce_sum(state_frequencies * tf.math.log(prob_human + 1e-8), axis=1)
  109. maxent_irl_objective = max_entropy_loss + alignment_loss
  110. grads = tape.gradient(maxent_irl_objective, self.model.trainable_variables)
  111. optimizer.apply_gradients(zip(grads, self.model.trainable_variables))
  112. total_loss += maxent_irl_objective
  113. avg_loss = total_loss / (len(human_trajectories) * trajectory_length)
  114. print(f"Epoch {epoch + 1}/{epochs}, MaxEnt IRL Loss: {avg_loss}")
  115. def _calculate_state_frequencies(self, positions):
  116. state_counts = np.sum(positions, axis=0)
  117. state_frequencies = state_counts / (len(positions) * self.state_dim)
  118. return state_frequencies
  119. def save_model(self, file_path):
  120. model_config = self.model.get_config()
  121. with open(file_path, 'wb') as f:
  122. pickle.dump(model_config, f)
  123. @classmethod
  124. def load_model(cls, file_path, state_dim):
  125. with open(file_path, 'rb') as f:
  126. model_config = pickle.load(f)
  127. irl_instance = cls(state_dim)
  128. irl_instance.model = tf.keras.Sequential.from_config(model_config)
  129. return irl_instance
  130. # Indicate test completion status
  131. state_dim = 2 # Dimension of the state space
  132. irl = MaxEntIRLReduced(state_dim)
  133. num_trajectories = 100
  134. trajectory_length = 20
  135. model_path = '/Users/vinay/Desktop/Computer_Science_Projects/ReScience/hackathonf23-Stacks/models/rmv_dim_model.pkl'
  136. # Define the state dimension for the model
  137. state_dim = 2
  138. # Load the model using your custom method
  139. def load_model(file_path, state_dim):
  140. with open(file_path, 'rb') as file:
  141. model_config = pickle.load(file)
  142. irl_instance = MaxEntIRLReduced(state_dim)
  143. irl_instance.model = tf.keras.Sequential.from_config(model_config)
  144. return irl_instance
  145. # Load the model using the custom load_model function
  146. loaded_model = load_model(model_path, state_dim)
  147. # Load the test data from the "test.csv" file
  148. test_data_path = '/Users/vinay/Desktop/Computer_Science_Projects/ReScience/hackathonf23-Stacks/data/test.csv'
  149. data = pd.read_csv(test_data_path)
  150. # Data preprocessing
  151. scaler = MinMaxScaler()
  152. columns_to_normalize = ['position x [mm]', 'position y [mm]']
  153. columns_to_normalize = scaler.fit_transform(data[columns_to_normalize])
  154. # Make predictions using the loaded model
  155. predictions = loaded_model.model.predict(columns_to_normalize)
  156. model_loss = ((predictions - columns_to_normalize))
  157. magnitudes = np.linalg.norm(model_loss, axis=1)
  158. magnitude_columns_to_normalize = np.linalg.norm(columns_to_normalize, axis=1)
  159. percent_error_magnitudes = np.abs(magnitudes - magnitude_columns_to_normalize) / np.abs(magnitude_columns_to_normalize) * 100
  160. avg_displacement_error = np.mean(magnitudes)
  161. print(f"Average Displacement Error with Removed Dimension Model: {avg_displacement_error:.2f}")
  162. plt.figure(figsize=(8, 6))
  163. plt.boxplot(magnitudes, vert=False)
  164. plt.title('Error of Trajectory Magnitudes with Removed Dimension Ablation:')
  165. plt.xlabel('Magnitude (meters)')
  166. plt.yticks([])
  167. plt.show()
Tip!

Press p or to see the previous file or, n or to see the next file

Comments

Loading...