# Example 2: XOR Binary Classification The next code creates a Keras model to build the XOR binary classification problem. Let's highlight the changes compared to the previous example. ```python import tensorflow.keras import pygad.kerasga import numpy import pygad def fitness_func(ga_instance, solution, sol_idx): global data_inputs, data_outputs, keras_ga, model predictions = pygad.kerasga.predict(model=model, solution=solution, data=data_inputs) bce = tensorflow.keras.losses.BinaryCrossentropy() solution_fitness = 1.0 / (bce(data_outputs, predictions).numpy() + 0.00000001) return solution_fitness def on_generation(ga_instance): print(f"Generation = {ga_instance.generations_completed}") print(f"Fitness = {ga_instance.best_solution()[1]}") # Build the keras model using the functional API. input_layer = tensorflow.keras.layers.Input(2) dense_layer = tensorflow.keras.layers.Dense(4, activation="relu")(input_layer) output_layer = tensorflow.keras.layers.Dense(2, activation="softmax")(dense_layer) model = tensorflow.keras.Model(inputs=input_layer, outputs=output_layer) # Create an instance of the pygad.kerasga.KerasGA class to build the initial population. keras_ga = pygad.kerasga.KerasGA(model=model, num_solutions=10) # XOR problem inputs data_inputs = numpy.array([[0, 0], [0, 1], [1, 0], [1, 1]]) # XOR problem outputs data_outputs = numpy.array([[1, 0], [0, 1], [0, 1], [1, 0]]) # Prepare the PyGAD parameters. Check the documentation for more information: https://pygad.readthedocs.io/en/latest/pygad.html#pygad-ga-class num_generations = 250 # Number of generations. num_parents_mating = 5 # Number of solutions to be selected as parents in the mating pool. initial_population = keras_ga.population_weights # Initial population of network weights. # Create an instance of the pygad.GA class ga_instance = pygad.GA(num_generations=num_generations, num_parents_mating=num_parents_mating, initial_population=initial_population, fitness_func=fitness_func, on_generation=on_generation) # Start the genetic algorithm evolution. ga_instance.run() # After the generations complete, a plot is shown that summarizes how the fitness values evolve over the generations. ga_instance.plot_fitness(title="PyGAD & Keras - Iteration vs. Fitness", linewidth=4) # Returning the details of the best solution. solution, solution_fitness, solution_idx = ga_instance.best_solution() print(f"Fitness value of the best solution = {solution_fitness}") print(f"Index of the best solution : {solution_idx}") # Make predictions based on the best solution. predictions = pygad.kerasga.predict(model=model, solution=solution, data=data_inputs) print(f"Predictions : \n{predictions}") # Calculate the binary crossentropy for the trained model. bce = tensorflow.keras.losses.BinaryCrossentropy() print("Binary Crossentropy : ", bce(data_outputs, predictions).numpy()) # Calculate the classification accuracy for the trained model. ba = tensorflow.keras.metrics.BinaryAccuracy() ba.update_state(data_outputs, predictions) accuracy = ba.result().numpy() print(f"Accuracy : {accuracy}") ``` Compared to the previous regression example, here are the changes: * The Keras model is changed according to the nature of the problem. Now, it has 2 inputs and 2 outputs with an in-between hidden layer of 4 neurons. ```python # Build the keras model using the functional API. input_layer = tensorflow.keras.layers.Input(2) dense_layer = tensorflow.keras.layers.Dense(4, activation="relu")(input_layer) output_layer = tensorflow.keras.layers.Dense(2, activation="softmax")(dense_layer) model = tensorflow.keras.Model(inputs=input_layer, outputs=output_layer) ``` * The train data is changed. Note that the output of each sample is a 1D vector of 2 values, 1 for each class. ```python # XOR problem inputs data_inputs = numpy.array([[0, 0], [0, 1], [1, 0], [1, 1]]) # XOR problem outputs data_outputs = numpy.array([[1, 0], [0, 1], [0, 1], [1, 0]]) ``` * The fitness value is calculated based on the binary cross entropy. ```python bce = tensorflow.keras.losses.BinaryCrossentropy() solution_fitness = 1.0 / (bce(data_outputs, predictions).numpy() + 0.00000001) ``` After the previous code completes, the next figure shows how the fitness value change by generation. ![pygad_keras_image_classification_XOR](https://user-images.githubusercontent.com/16560492/93722639-b811da80-fb98-11ea-8951-f13a7a266c04.png) Here is some information about the trained model. Its fitness value is `739.24`, loss is `0.0013527311` and accuracy is 100%. ```python Fitness value of the best solution = 739.2397344644013 Index of the best solution : 7 Predictions : [[9.9694413e-01 3.0558957e-03] [5.0176249e-04 9.9949825e-01] [1.8470541e-03 9.9815291e-01] [9.9999976e-01 2.0538971e-07]] Binary Crossentropy : 0.0013527311 Accuracy : 1.0 ```