def crossover(father, mother, alpha=0.5):
    layers = []
    for lt, ls, fl, ml in zip(father.get_layer_types(),
                              father.get_layer_shapes(), father.get_layers(),
                              mother.get_layers()):
        if lt == "conv":
            lyr = ConvLayer(image_shape=ls[0], filter_shape=ls[1])
            # Loop for each filter
            for i in range(ls[1][0]):
                parent = ml
                # Randomly pick either mother or father gene based on alpha
                if random.random() < alpha:
                    parent = fl
                lyr.set_filter(index=i, filtr=deepcopy(parent.get_filter(i)))
            layers.append(lyr)
        elif lt == "dense" or lt == "soft":
            weights = []
            biases = []
            lyr = DenseLayer(layer_shape=ls[0])
            if lt == "soft":
                lyr = SoftmaxLayer(layer_shape=ls[0])

            # Loop for each neuron
            for i in range(ls[0][0]):
                parent = ml
                # Randomly pick either mother or father gene based on alpha
                if random.random() < alpha:
                    parent = fl
                weights.append(deepcopy(parent.get_weights(i)))
                biases.append(deepcopy(parent.get_biases(i)))
            lyr.set_weights_biases(weights, biases)
            layers.append(lyr)
    child = Individual(deepcopy(father.get_layer_types()),
                       deepcopy(father.get_layer_shapes()),
                       deepcopy(father.get_conv_layer_types()), layers)
    child = mutate_individual(child)
    return child