TroglodyteDerivations commited on
Commit
3566447
·
verified ·
1 Parent(s): 3b1733c

Create tf_ga_algo.txt

Browse files
Files changed (1) hide show
  1. tf_ga_algo.txt +181 -0
tf_ga_algo.txt ADDED
@@ -0,0 +1,181 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Updated Implementation includes RandomSearch, Best Individual .npy save
2
+
3
+ import numpy as np
4
+ import tensorflow as tf
5
+ import tensorflow_probability as tfp
6
+ import plotly.graph_objs as go
7
+ from keras_tuner import HyperModel, RandomSearch
8
+ from tqdm import tqdm
9
+
10
+ # Define the target X-shape pattern
11
+ target_pattern = np.array([
12
+ [25.76815, -80.1868],
13
+ [25.7743, -80.1937],
14
+ [25.762, -80.18],
15
+ [25.76815, -80.1868],
16
+ [25.7743, -80.18],
17
+ [25.762, -80.1937]
18
+ ])
19
+
20
+ # Convert target pattern to TensorFlow tensor
21
+ target_pattern_tf = tf.constant(target_pattern, dtype=tf.float32)
22
+
23
+ # Define the GA parameters ranges
24
+ population_sizes = [30, 50, 70]
25
+ num_generations = 100000
26
+ mutation_rates = [0.05, 0.1, 0.15]
27
+ crossover_rates = [0.7, 0.8, 0.9]
28
+ elitism_counts = [3, 5, 7]
29
+
30
+ # Define the fitness function using TensorFlow
31
+ def fitness_function(positions):
32
+ return tf.reduce_sum((positions - target_pattern_tf) ** 2, axis=[1, 2])
33
+
34
+ # Selection function (tournament selection) using TensorFlow
35
+ def selection(population, fitness_values):
36
+ selected = []
37
+ for _ in range(len(population)):
38
+ idx1, idx2 = tf.random.uniform(shape=(2,), minval=0, maxval=len(population), dtype=tf.int32)
39
+ if fitness_values[idx1] < fitness_values[idx2]:
40
+ selected.append(population[idx1])
41
+ else:
42
+ selected.append(population[idx2])
43
+ return tf.stack(selected)
44
+
45
+ # Crossover function (single-point crossover) using TensorFlow
46
+ def crossover(parent1, parent2, crossover_rate):
47
+ if tf.random.uniform(()) < crossover_rate:
48
+ crossover_point = tf.random.uniform((), minval=1, maxval=len(parent1), dtype=tf.int32)
49
+ child1 = tf.concat([parent1[:crossover_point], parent2[crossover_point:]], axis=0)
50
+ child2 = tf.concat([parent2[:crossover_point], parent1[crossover_point:]], axis=0)
51
+ return child1, child2
52
+ else:
53
+ return parent1, parent2
54
+
55
+ # Mutation function using TensorFlow Probability
56
+ def mutate(individual, mutation_rate):
57
+ mutation_mask = tfp.distributions.Bernoulli(probs=mutation_rate).sample(sample_shape=tf.shape(individual))
58
+ mutation_noise = tfp.distributions.Normal(loc=0.0, scale=0.1).sample(sample_shape=tf.shape(individual))
59
+ return individual + tf.cast(mutation_mask, tf.float32) * mutation_noise
60
+
61
+ # GA algorithm using TensorFlow
62
+ def genetic_algorithm(population_size, mutation_rate, crossover_rate, elitism_count, num_generations):
63
+ population = tf.random.uniform((population_size, len(target_pattern), 2), dtype=tf.float32)
64
+
65
+ best_fitness_overall = float('inf')
66
+ best_individual_overall = None
67
+
68
+ for generation in tqdm(range(num_generations), desc="Generations"):
69
+ fitness_values = fitness_function(population)
70
+
71
+ # Track the best fitness and individual overall
72
+ best_fitness_current_gen = tf.reduce_min(fitness_values).numpy()
73
+ best_individual_current_gen = population[tf.argmin(fitness_values)].numpy()
74
+
75
+ if best_fitness_current_gen < best_fitness_overall:
76
+ best_fitness_overall = best_fitness_current_gen
77
+ best_individual_overall = best_individual_current_gen
78
+
79
+ # Elitism: Preserve the best individuals
80
+ elite_indices = tf.argsort(fitness_values)[:elitism_count]
81
+ elites = tf.gather(population, elite_indices)
82
+
83
+ # Select parents
84
+ parents = selection(population, fitness_values)
85
+
86
+ # Create offspring through crossover and mutation
87
+ offspring = []
88
+ for i in range(0, len(parents) - 1, 2):
89
+ child1, child2 = crossover(parents[i], parents[i + 1], crossover_rate)
90
+ offspring.append(mutate(child1, mutation_rate))
91
+ offspring.append(mutate(child2, mutation_rate))
92
+
93
+ # Ensure offspring size matches population size - elitism count
94
+ num_offspring_needed = population_size - elitism_count
95
+ offspring = offspring[:num_offspring_needed]
96
+
97
+ # Replace the population with the offspring and elites
98
+ population = tf.concat([tf.stack(offspring), elites], axis=0)
99
+
100
+ return best_fitness_overall, best_individual_overall
101
+
102
+ # HyperModel for Keras Tuner
103
+ class GAHyperModel(HyperModel):
104
+ def __init__(self, num_generations):
105
+ self.num_generations = num_generations
106
+
107
+ def build(self, hp):
108
+ population_size = hp.Choice('population_size', values=population_sizes)
109
+ mutation_rate = hp.Choice('mutation_rate', values=mutation_rates)
110
+ crossover_rate = hp.Choice('crossover_rate', values=crossover_rates)
111
+ elitism_count = hp.Choice('elitism_count', values=elitism_counts)
112
+
113
+ final_fitness, _ = genetic_algorithm(
114
+ population_size, mutation_rate, crossover_rate, elitism_count, self.num_generations
115
+ )
116
+
117
+ return final_fitness
118
+
119
+ # Hyperparameter tuning using Keras Tuner
120
+ tuner = RandomSearch(
121
+ GAHyperModel(num_generations),
122
+ objective='val_loss',
123
+ max_trials=50,
124
+ executions_per_trial=1,
125
+ directory='ga_tuning',
126
+ project_name='genetic_algorithm'
127
+ )
128
+
129
+ tuner.search(x=None, y=None, epochs=1, verbose=1)
130
+
131
+ # Get the best hyperparameters
132
+ best_hyperparams = tuner.get_best_hyperparameters(num_trials=1)[0]
133
+ best_population_size = best_hyperparams.get('population_size')
134
+ best_mutation_rate = best_hyperparams.get('mutation_rate')
135
+ best_crossover_rate = best_hyperparams.get('crossover_rate')
136
+ best_elitism_count = best_hyperparams.get('elitism_count')
137
+
138
+ # Run the GA with the best hyperparameters
139
+ best_fitness, best_individual = genetic_algorithm(
140
+ best_population_size, best_mutation_rate, best_crossover_rate, best_elitism_count, num_generations
141
+ )
142
+
143
+ # Output the best hyperparameters and the corresponding best individual
144
+ print(f"Best hyperparameters: population_size={best_population_size}, mutation_rate={best_mutation_rate}, crossover_rate={best_crossover_rate}, elitism_count={best_elitism_count}")
145
+ print(f"Best fitness: {best_fitness}")
146
+
147
+ # Save the best individual
148
+ np.save('best_individual.npy', best_individual)
149
+
150
+ # Validate the flight path trajectory
151
+ def plot_trajectory(positions):
152
+ fig = go.Figure()
153
+
154
+ # Plot target pattern
155
+ fig.add_trace(go.Scatter(
156
+ x=target_pattern[:, 0],
157
+ y=target_pattern[:, 1],
158
+ mode='markers+lines',
159
+ name='Target Pattern',
160
+ marker=dict(size=10, color='red')
161
+ ))
162
+
163
+ # Plot optimized pattern
164
+ fig.add_trace(go.Scatter(
165
+ x=positions[:, 0],
166
+ y=positions[:, 1],
167
+ mode='markers+lines',
168
+ name='Optimized Pattern',
169
+ marker=dict(size=10, color='blue')
170
+ ))
171
+
172
+ fig.update_layout(
173
+ title='UAV Swarm Intelligence: X-Shape Pattern',
174
+ xaxis_title='X',
175
+ yaxis_title='Y'
176
+ )
177
+
178
+ fig.show()
179
+
180
+ # Plot the final optimized pattern
181
+ plot_trajectory(best_individual)