Skip to content

Commit 7627dcb

Browse files
committed
more tests
1 parent b58d524 commit 7627dcb

File tree

5 files changed

+198
-1
lines changed

5 files changed

+198
-1
lines changed

pygad/cnn/cnn.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ def layers_weights_as_matrix(model, vector_weights):
7878
layer_weights_size = layer.initial_weights.size
7979

8080
weights_vector=vector_weights[start:start + layer_weights_size]
81-
# matrix = pygad.nn.DenseLayer.to_array(vector=weights_vector, shape=layer_weights_shape)
81+
# matrix = pygad.nn.DenseLayer.to_array(vector=weights_vector, shape=layer_weights_shape)
8282
matrix = numpy.reshape(weights_vector, (layer_weights_shape))
8383
network_weights.append(matrix)
8484

tests/test_cnn.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import pygad.cnn
2+
import numpy
3+
4+
def test_cnn_layers_and_model():
5+
"""Test pygad.cnn layers and Model class."""
6+
# Dummy data
7+
data_inputs = numpy.random.uniform(0, 1, (4, 10, 10, 3))
8+
# The test do not care about the outputs predicted by the network.
9+
# data_outputs = numpy.array([0, 1, 1, 0])
10+
11+
input_layer = pygad.cnn.Input2D(input_shape=(10, 10, 3))
12+
conv_layer = pygad.cnn.Conv2D(num_filters=2,
13+
kernel_size=3,
14+
previous_layer=input_layer,
15+
activation_function="relu")
16+
max_pooling_layer = pygad.cnn.MaxPooling2D(pool_size=2,
17+
previous_layer=conv_layer,
18+
stride=2)
19+
flatten_layer = pygad.cnn.Flatten(previous_layer=max_pooling_layer)
20+
dense_layer = pygad.cnn.Dense(num_neurons=2,
21+
previous_layer=flatten_layer,
22+
activation_function="softmax")
23+
24+
model = pygad.cnn.Model(last_layer=dense_layer,
25+
epochs=1,
26+
learning_rate=0.01)
27+
28+
# Test predict
29+
predictions = model.predict(data_inputs=data_inputs)
30+
assert len(predictions) == 4
31+
32+
# Test summary (just to ensure it doesn't crash)
33+
model.summary()
34+
35+
# Test layers_weights
36+
weights = pygad.cnn.layers_weights(model)
37+
assert isinstance(weights, list)
38+
assert len(weights) > 0
39+
40+
# Test layers_weights_as_vector
41+
weights_vector = pygad.cnn.layers_weights_as_vector(model)
42+
assert isinstance(weights_vector, numpy.ndarray)
43+
assert weights_vector.ndim == 1
44+
45+
print("test_cnn_layers_and_model passed.")
46+
47+
if __name__ == "__main__":
48+
test_cnn_layers_and_model()
49+
print("\nAll CNN tests passed!")

tests/test_gacnn.py

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import pygad.cnn
2+
import pygad.gacnn
3+
import pygad
4+
import numpy
5+
6+
def test_gacnn_evolution():
7+
"""Test pygad.gacnn with pygad.GA."""
8+
# Small dummy data
9+
data_inputs = numpy.random.uniform(0, 1, (4, 10, 10, 3))
10+
data_outputs = numpy.array([0, 1, 1, 0])
11+
12+
input_layer = pygad.cnn.Input2D(input_shape=(10, 10, 3))
13+
conv_layer = pygad.cnn.Conv2D(num_filters=2,
14+
kernel_size=3,
15+
previous_layer=input_layer,
16+
activation_function="relu")
17+
flatten_layer = pygad.cnn.Flatten(previous_layer=conv_layer)
18+
dense_layer = pygad.cnn.Dense(num_neurons=2,
19+
previous_layer=flatten_layer,
20+
activation_function="softmax")
21+
22+
model = pygad.cnn.Model(last_layer=dense_layer,
23+
epochs=1,
24+
learning_rate=0.01)
25+
26+
gacnn_instance = pygad.gacnn.GACNN(model=model,
27+
num_solutions=4)
28+
29+
def fitness_func(ga_instance, solution, sol_idx):
30+
predictions = gacnn_instance.population_networks[sol_idx].predict(data_inputs=data_inputs)
31+
correct_predictions = numpy.where(predictions == data_outputs)[0].size
32+
solution_fitness = (correct_predictions/data_outputs.size)*100
33+
return solution_fitness
34+
35+
def callback_generation(ga_instance):
36+
population_matrices = pygad.gacnn.population_as_matrices(population_networks=gacnn_instance.population_networks,
37+
population_vectors=ga_instance.population)
38+
gacnn_instance.update_population_trained_weights(population_trained_weights=population_matrices)
39+
40+
initial_population = pygad.gacnn.population_as_vectors(population_networks=gacnn_instance.population_networks)
41+
42+
ga_instance = pygad.GA(num_generations=2,
43+
num_parents_mating=2,
44+
initial_population=initial_population,
45+
fitness_func=fitness_func,
46+
on_generation=callback_generation,
47+
suppress_warnings=True)
48+
49+
ga_instance.run()
50+
assert ga_instance.run_completed
51+
assert ga_instance.generations_completed == 2
52+
53+
print("test_gacnn_evolution passed.")
54+
55+
if __name__ == "__main__":
56+
test_gacnn_evolution()
57+
print("\nAll GACNN tests passed!")

tests/test_kerasga.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import numpy
2+
import pygad
3+
import pygad.kerasga
4+
import tensorflow.keras
5+
6+
def test_kerasga_evolution():
7+
"""Test pygad.kerasga with pygad.GA."""
8+
9+
# XOR data
10+
data_inputs = numpy.array([[0, 0], [0, 1], [1, 0], [1, 1]])
11+
data_outputs = numpy.array([[1, 0], [0, 1], [0, 1], [1, 0]]) # One-hot encoded
12+
13+
input_layer = tensorflow.keras.layers.Input(2)
14+
dense_layer = tensorflow.keras.layers.Dense(4, activation="relu")(input_layer)
15+
output_layer = tensorflow.keras.layers.Dense(2, activation="softmax")(dense_layer)
16+
17+
model = tensorflow.keras.Model(inputs=input_layer, outputs=output_layer)
18+
19+
keras_ga = pygad.kerasga.KerasGA(model=model, num_solutions=10)
20+
21+
def fitness_func(ga_instance, solution, solution_idx):
22+
model_weights_matrix = pygad.kerasga.model_weights_as_matrix(model=model,
23+
weights_vector=solution)
24+
model.set_weights(weights=model_weights_matrix)
25+
predictions = model.predict(data_inputs, verbose=0)
26+
27+
cce = tensorflow.keras.losses.CategoricalCrossentropy()
28+
loss = cce(data_outputs, predictions).numpy()
29+
fitness = 1.0 / (loss + 0.00000001)
30+
return fitness
31+
32+
ga_instance = pygad.GA(num_generations=2,
33+
num_parents_mating=5,
34+
initial_population=keras_ga.population_weights,
35+
fitness_func=fitness_func,
36+
suppress_warnings=True)
37+
38+
ga_instance.run()
39+
assert ga_instance.run_completed
40+
assert ga_instance.generations_completed == 2
41+
42+
print("test_kerasga_evolution passed.")
43+
44+
if __name__ == "__main__":
45+
test_kerasga_evolution()
46+
print("\nAll KerasGA tests passed!")

tests/test_torchga.py

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import pygad
2+
import torch
3+
4+
def test_torchga_evolution():
5+
"""Test pygad.torchga with pygad.GA."""
6+
7+
# XOR data
8+
data_inputs = torch.tensor([[0.0, 0.0], [0.1, 0.6], [1.0, 0.0], [1.1, 1.3]])
9+
data_outputs = torch.tensor([[1.0, 0.0], [0.0, 1.0], [0.0, 1.0], [1.0, 0.0]]) # One-hot encoded
10+
11+
model = torch.nn.Sequential(
12+
torch.nn.Linear(2, 4),
13+
torch.nn.ReLU(),
14+
torch.nn.Linear(4, 2),
15+
torch.nn.Softmax(dim=1)
16+
)
17+
18+
torch_ga = pygad.torchga.TorchGA(model=model, num_solutions=10)
19+
20+
def fitness_func(ga_instance, solution, solution_idx):
21+
model_weights_dict = pygad.torchga.model_weights_as_dict(model=model,
22+
weights_vector=solution)
23+
model.load_state_dict(model_weights_dict)
24+
predictions = model(data_inputs)
25+
26+
loss_func = torch.nn.CrossEntropyLoss()
27+
loss = loss_func(predictions, data_outputs).detach().numpy()
28+
fitness = 1.0 / (loss + 0.00000001)
29+
return fitness
30+
31+
ga_instance = pygad.GA(num_generations=2,
32+
num_parents_mating=5,
33+
initial_population=torch_ga.population_weights,
34+
fitness_func=fitness_func,
35+
suppress_warnings=True)
36+
37+
ga_instance.run()
38+
assert ga_instance.run_completed
39+
assert ga_instance.generations_completed == 2
40+
41+
print("test_torchga_evolution passed.")
42+
43+
if __name__ == "__main__":
44+
test_torchga_evolution()
45+
print("\nAll TorchGA tests passed!")

0 commit comments

Comments
 (0)