FazBrowse GitHub Viewer | Trending |
URL:
| Home
Tools: [Download Repo ZIP]   [Original HTTPS Page]

docs: split the long ML tutorial pages into one page per example · ahmedfgad/GeneticAlgorithmPython@f5477e3 · GitHub

Commit f5477e3

Browse files
committed
docs: split the long ML tutorial pages into one page per example
For nn, gann, kerasga, and torchga, keep the module reference (intro, classes, functions, and steps) on the main page and move each worked example to its own page, linked from an Examples card grid and a nested toctree. cnn and gacnn (single example each) are unchanged. No internal links break: example sections are not referenced, and cnn.html#reading-the-data stays on the cnn page.
1 parent 6959c25 commit f5477e3

21 files changed

Lines changed: 2393 additions & 2273 deletions

‎docs/source/gann.md‎

Lines changed: 33 additions & 584 deletions
Large diffs are not rendered by default.
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
# Image Classification
2+
3+
In the documentation of the `pygad.nn` module, a neural network is created for classifying images from the Fruits360 dataset without being trained using an optimization algorithm. This section discusses how to train such a classifier using the genetic algorithm with the help of the `pygad.gann` module.
4+
5+
Please make sure that the training data files [dataset_features.npy](https://github.com/ahmedfgad/NumPyANN/blob/master/dataset_features.npy) and [outputs.npy](https://github.com/ahmedfgad/NumPyANN/blob/master/outputs.npy) are available. For downloading them, use these links:
6+
7+
1. [dataset_features.npy](https://github.com/ahmedfgad/NumPyANN/blob/master/dataset_features.npy): The features https://github.com/ahmedfgad/NumPyANN/blob/master/dataset_features.npy
8+
2. [outputs.npy](https://github.com/ahmedfgad/NumPyANN/blob/master/outputs.npy): The class labels https://github.com/ahmedfgad/NumPyANN/blob/master/outputs.npy
9+
10+
After the data is available, here is the complete code that builds and trains a neural network using the genetic algorithm for classifying images from 4 classes of the Fruits360 dataset.
11+
12+
Because there are 4 classes, the output layer is assigned has 4 neurons according to the `num_neurons_output` parameter of the `pygad.gann.GANN` class constructor.
13+
14+
```python
15+
import numpy
16+
import pygad
17+
import pygad.nn
18+
import pygad.gann
19+
20+
def fitness_func(ga_instance, solution, sol_idx):
21+
global GANN_instance, data_inputs, data_outputs
22+
23+
predictions = pygad.nn.predict(last_layer=GANN_instance.population_networks[sol_idx],
24+
data_inputs=data_inputs)
25+
correct_predictions = numpy.where(predictions == data_outputs)[0].size
26+
solution_fitness = (correct_predictions/data_outputs.size)*100
27+
28+
return solution_fitness
29+
30+
def callback_generation(ga_instance):
31+
global GANN_instance, last_fitness
32+
33+
population_matrices = pygad.gann.population_as_matrices(population_networks=GANN_instance.population_networks,
34+
population_vectors=ga_instance.population)
35+
36+
GANN_instance.update_population_trained_weights(population_trained_weights=population_matrices)
37+
38+
print(f"Generation = {ga_instance.generations_completed}")
39+
print(f"Fitness = {ga_instance.best_solution()[1]}")
40+
print(f"Change = {ga_instance.best_solution()[1] - last_fitness}")
41+
42+
last_fitness = ga_instance.best_solution()[1].copy()
43+
44+
# Holds the fitness value of the previous generation.
45+
last_fitness = 0
46+
47+
# Reading the input data.
48+
data_inputs = numpy.load("dataset_features.npy") # Download from https://github.com/ahmedfgad/NumPyANN/blob/master/dataset_features.npy
49+
50+
# Optional step of filtering the input data using the standard deviation.
51+
features_STDs = numpy.std(a=data_inputs, axis=0)
52+
data_inputs = data_inputs[:, features_STDs>50]
53+
54+
# Reading the output data.
55+
data_outputs = numpy.load("outputs.npy") # Download from https://github.com/ahmedfgad/NumPyANN/blob/master/outputs.npy
56+
57+
# The length of the input vector for each sample (i.e. number of neurons in the input layer).
58+
num_inputs = data_inputs.shape[1]
59+
# The number of neurons in the output layer (i.e. number of classes).
60+
num_classes = 4
61+
62+
# Creating an initial population of neural networks. The return of the initial_population() function holds references to the networks, not their weights. Using such references, the weights of all networks can be fetched.
63+
num_solutions = 8 # A solution or a network can be used interchangeably.
64+
GANN_instance = pygad.gann.GANN(num_solutions=num_solutions,
65+
num_neurons_input=num_inputs,
66+
num_neurons_hidden_layers=[150, 50],
67+
num_neurons_output=num_classes,
68+
hidden_activations=["relu", "relu"],
69+
output_activation="softmax")
70+
71+
# population does not hold the numerical weights of the network instead it holds a list of references to each last layer of each network (i.e. solution) in the population. A solution or a network can be used interchangeably.
72+
# If there is a population with 3 solutions (i.e. networks), then the population is a list with 3 elements. Each element is a reference to the last layer of each network. Using such a reference, all details of the network can be accessed.
73+
population_vectors = pygad.gann.population_as_vectors(population_networks=GANN_instance.population_networks)
74+
75+
# To prepare the initial population, there are 2 ways:
76+
# 1) Prepare it yourself and pass it to the initial_population parameter. This way is useful when the user wants to start the genetic algorithm with a custom initial population.
77+
# 2) Assign valid integer values to the sol_per_pop and num_genes parameters. If the initial_population parameter exists, then the sol_per_pop and num_genes parameters are useless.
78+
initial_population = population_vectors.copy()
79+
80+
num_parents_mating = 4 # Number of solutions to be selected as parents in the mating pool.
81+
82+
num_generations = 500 # Number of generations.
83+
84+
mutation_percent_genes = 10 # Percentage of genes to mutate. This parameter has no action if the parameter mutation_num_genes exists.
85+
86+
parent_selection_type = "sss" # Type of parent selection.
87+
88+
crossover_type = "single_point" # Type of the crossover operator.
89+
90+
mutation_type = "random" # Type of the mutation operator.
91+
92+
keep_parents = -1 # Number of parents to keep in the next population. -1 means keep all parents and 0 means keep nothing.
93+
94+
ga_instance = pygad.GA(num_generations=num_generations,
95+
num_parents_mating=num_parents_mating,
96+
initial_population=initial_population,
97+
fitness_func=fitness_func,
98+
mutation_percent_genes=mutation_percent_genes,
99+
parent_selection_type=parent_selection_type,
100+
crossover_type=crossover_type,
101+
mutation_type=mutation_type,
102+
keep_parents=keep_parents,
103+
on_generation=callback_generation)
104+
105+
ga_instance.run()
106+
107+
# After the generations complete, a plot is shown that summarizes how the fitness values evolve over the generations.
108+
ga_instance.plot_fitness()
109+
110+
# Returning the details of the best solution.
111+
solution, solution_fitness, solution_idx = ga_instance.best_solution()
112+
print(f"Parameters of the best solution : {solution}")
113+
print(f"Fitness value of the best solution = {solution_fitness}")
114+
print(f"Index of the best solution : {solution_idx}")
115+
116+
if ga_instance.best_solution_generation != -1:
117+
print(f"Best fitness value reached after {ga_instance.best_solution_generation} generations.")
118+
119+
# Predicting the outputs of the data using the best solution.
120+
predictions = pygad.nn.predict(last_layer=GANN_instance.population_networks[solution_idx],
121+
data_inputs=data_inputs)
122+
print(f"Predictions of the trained network : {predictions}")
123+
124+
# Calculating some statistics
125+
num_wrong = numpy.where(predictions != data_outputs)[0]
126+
num_correct = data_outputs.size - num_wrong.size
127+
accuracy = 100 * (num_correct/data_outputs.size)
128+
print(f"Number of correct classifications : {num_correct}.")
129+
print(f"Number of wrong classifications : {num_wrong.size}.")
130+
print(f"Classification accuracy : {accuracy}.")
131+
```
132+
133+
After training completes, here are the outputs of the print statements. The number of wrong classifications is only 1 and the accuracy is 99.949%. This accuracy is reached after 482 generations.
134+
135+
```
136+
Fitness value of the best solution = 99.94903160040775
137+
Index of the best solution : 0
138+
Best fitness value reached after 482 generations.
139+
Number of correct classifications : 1961.
140+
Number of wrong classifications : 1.
141+
Classification accuracy : 99.94903160040775.
142+
```
143+
144+
The next figure shows how fitness value evolves by generation.
145+
146+
![Training Neural Networks using Genetic Algorithm](https://user-images.githubusercontent.com/16560492/82152993-21898180-9865-11ea-8387-b995f88b83f7.png)

‎docs/source/gann_regression_1.md‎

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
# Regression Example 1
2+
3+
To train a neural network for regression, follow these instructions:
4+
5+
1. Set the `output_activation` parameter in the constructor of the `pygad.gann.GANN` class to `"None"`. It is possible to use the ReLU function if all outputs are nonnegative.
6+
7+
```python
8+
GANN_instance = pygad.gann.GANN(...
9+
output_activation="None")
10+
```
11+
12+
2. Wherever the `pygad.nn.predict()` function is used, set the `problem_type` parameter to `"regression"`.
13+
14+
```python
15+
predictions = pygad.nn.predict(...,
16+
problem_type="regression")
17+
```
18+
19+
3. Design the fitness function to calculate the error (e.g. mean absolute error).
20+
21+
```python
22+
def fitness_func(ga_instance, solution, sol_idx):
23+
...
24+
25+
predictions = pygad.nn.predict(...,
26+
problem_type="regression")
27+
28+
solution_fitness = 1.0/numpy.mean(numpy.abs(predictions - data_outputs))
29+
30+
return solution_fitness
31+
```
32+
33+
The next code builds a complete example for building a neural network for regression.
34+
35+
```python
36+
import numpy
37+
import pygad
38+
import pygad.nn
39+
import pygad.gann
40+
41+
def fitness_func(ga_instance, solution, sol_idx):
42+
global GANN_instance, data_inputs, data_outputs
43+
44+
predictions = pygad.nn.predict(last_layer=GANN_instance.population_networks[sol_idx],
45+
data_inputs=data_inputs, problem_type="regression")
46+
solution_fitness = 1.0/numpy.mean(numpy.abs(predictions - data_outputs))
47+
48+
return solution_fitness
49+
50+
def callback_generation(ga_instance):
51+
global GANN_instance, last_fitness
52+
53+
population_matrices = pygad.gann.population_as_matrices(population_networks=GANN_instance.population_networks,
54+
population_vectors=ga_instance.population)
55+
56+
GANN_instance.update_population_trained_weights(population_trained_weights=population_matrices)
57+
58+
print(f"Generation = {ga_instance.generations_completed}")
59+
print(f"Fitness = {ga_instance.best_solution(pop_fitness=ga_instance.last_generation_fitness)[1]}")
60+
print(f"Change = {ga_instance.best_solution(pop_fitness=ga_instance.last_generation_fitness)[1] - last_fitness}")
61+
62+
last_fitness = ga_instance.best_solution(pop_fitness=ga_instance.last_generation_fitness)[1].copy()
63+
64+
# Holds the fitness value of the previous generation.
65+
last_fitness = 0
66+
67+
# Preparing the NumPy array of the inputs.
68+
data_inputs = numpy.array([[2, 5, -3, 0.1],
69+
[8, 15, 20, 13]])
70+
71+
# Preparing the NumPy array of the outputs.
72+
data_outputs = numpy.array([[0.1, 0.2],
73+
[1.8, 1.5]])
74+
75+
# The length of the input vector for each sample (i.e. number of neurons in the input layer).
76+
num_inputs = data_inputs.shape[1]
77+
78+
# Creating an initial population of neural networks. The return of the initial_population() function holds references to the networks, not their weights. Using such references, the weights of all networks can be fetched.
79+
num_solutions = 6 # A solution or a network can be used interchangeably.
80+
GANN_instance = pygad.gann.GANN(num_solutions=num_solutions,
81+
num_neurons_input=num_inputs,
82+
num_neurons_hidden_layers=[2],
83+
num_neurons_output=2,
84+
hidden_activations=["relu"],
85+
output_activation="None")
86+
87+
# population does not hold the numerical weights of the network instead it holds a list of references to each last layer of each network (i.e. solution) in the population. A solution or a network can be used interchangeably.
88+
# If there is a population with 3 solutions (i.e. networks), then the population is a list with 3 elements. Each element is a reference to the last layer of each network. Using such a reference, all details of the network can be accessed.
89+
population_vectors = pygad.gann.population_as_vectors(population_networks=GANN_instance.population_networks)
90+
91+
# To prepare the initial population, there are 2 ways:
92+
# 1) Prepare it yourself and pass it to the initial_population parameter. This way is useful when the user wants to start the genetic algorithm with a custom initial population.
93+
# 2) Assign valid integer values to the sol_per_pop and num_genes parameters. If the initial_population parameter exists, then the sol_per_pop and num_genes parameters are useless.
94+
initial_population = population_vectors.copy()
95+
96+
num_parents_mating = 4 # Number of solutions to be selected as parents in the mating pool.
97+
98+
num_generations = 500 # Number of generations.
99+
100+
mutation_percent_genes = 5 # Percentage of genes to mutate. This parameter has no action if the parameter mutation_num_genes exists.
101+
102+
parent_selection_type = "sss" # Type of parent selection.
103+
104+
crossover_type = "single_point" # Type of the crossover operator.
105+
106+
mutation_type = "random" # Type of the mutation operator.
107+
108+
keep_parents = 1 # Number of parents to keep in the next population. -1 means keep all parents and 0 means keep nothing.
109+
110+
init_range_low = -1
111+
init_range_high = 1
112+
113+
ga_instance = pygad.GA(num_generations=num_generations,
114+
num_parents_mating=num_parents_mating,
115+
initial_population=initial_population,
116+
fitness_func=fitness_func,
117+
mutation_percent_genes=mutation_percent_genes,
118+
init_range_low=init_range_low,
119+
init_range_high=init_range_high,
120+
parent_selection_type=parent_selection_type,
121+
crossover_type=crossover_type,
122+
mutation_type=mutation_type,
123+
keep_parents=keep_parents,
124+
on_generation=callback_generation)
125+
126+
ga_instance.run()
127+
128+
# After the generations complete, a plot is shown that summarizes how the fitness values evolve over the generations.
129+
ga_instance.plot_fitness()
130+
131+
# Returning the details of the best solution.
132+
solution, solution_fitness, solution_idx = ga_instance.best_solution(pop_fitness=ga_instance.last_generation_fitness)
133+
print(f"Parameters of the best solution : {solution}")
134+
print(f"Fitness value of the best solution = {solution_fitness}")
135+
print(f"Index of the best solution : {solution_idx}")
136+
137+
if ga_instance.best_solution_generation != -1:
138+
print(f"Best fitness value reached after {ga_instance.best_solution_generation} generations.")
139+
140+
# Predicting the outputs of the data using the best solution.
141+
predictions = pygad.nn.predict(last_layer=GANN_instance.population_networks[solution_idx],
142+
data_inputs=data_inputs,
143+
problem_type="regression")
144+
print(f"Predictions of the trained network : {predictions}")
145+
146+
# Calculating some statistics
147+
abs_error = numpy.mean(numpy.abs(predictions - data_outputs))
148+
print(f"Absolute error : {abs_error}.")
149+
```
150+
151+
The next figure shows how the fitness value changes for the generations used.
152+
153+
![example_regression](https://user-images.githubusercontent.com/16560492/92948154-3cf24b00-f459-11ea-94ea-952b66ab2145.png)

0 commit comments

Comments
 (0)

Back | FazBrowse Home | New Git URL