def generate_initial_population(num_population): # [learning_rate, hidden_size, number_of_layers, fitness] learning_rate = np.empty([num_population, 1], dtype=np.float32) hidden_size = np.empty([num_population, 1], dtype=np.int32) number_of_layers = np.empty([num_population, 1], dtype=np.int32) fitness = np.zeros([num_population, 1], dtype=np.float32) for i in range(num_population): learning_rate[i] = round(random.uniform(0.001, 0.1), 3) hidden_size[i] = int(random.randrange(1, 20, step= 1)) number_of_layers[i] = int(random.uniform(1, 6)) population = np.concatenate((learning_rate, hidden_size, number_of_layers, fitness), axis= 1) return population def fitness(population): total = len(population) i = 1 for config in population: # Train MLP model using current hyperparameter combinations, add calculate fitness # print("Training" , i , "of", total) config[3] = round(training_run(Configuration(config[0], 12, int(config[1]), int(config[2]), 200), test=True), 2) i = i + 1 # Split training set into development, and validation set? # Use only subset of training data for model selection? def selection(population): population_count = population.shape[0] number_to_remove = int(population.shape[0]/2) to_remove = [] for i in range(number_to_remove): index = population_count - i -1 to_remove.append(index) # Sort population by fitness, config[3] -> fitness population = population[population[:, 3].argsort()] # Removing half of the worst performers from current generation population = np.delete(population, to_remove, 0) return population def crossover(population): # Single-point crossover, two-point crossover, k-fold num_hyperparameters = population[0].shape[0] -1 # crossover_index = np.random(1, num_hyperparameters) crossover_index = random.randint(1, num_hyperparameters-1) print("crossover_index", crossover_index) children = np.array([]) for parent in range(len(population) -1): if parent % 2 == 0: if crossover_index == 1: children = np.append(children, np.array([ population[parent][0], population[parent+1][1], population[parent+1][2], 0 ])) children = np.append(children, np.array([ population[parent+1][0], population[parent][1], population[parent][2], 0 ])) if crossover_index == 2: children = np.append(children, np.array([ population[parent][0], population[parent][1], population[parent+1][2], 0 ])) children = np.append(children, np.array([ population[parent+1][0], population[parent+1][1], population[parent][2], 0 ])) # children = np.append(children, np.array([ population[parent][0], population[parent+1][1], population[parent+1][2], 0 ])) # children = np.append(children, np.array([ population[parent+1][0], population[parent][1], population[parent][2], 0 ])) children = children.reshape(len(population), num_hyperparameters + 1) return children def mutation(population): # Select random elements from the population # Mutate a single gene (hyperparameter) mutation_rate = 0.4 parameters_to_change = int(mutation_rate * (len(population)*2)) for change in range(parameters_to_change): i = random.randint(0, len(population)-1) param = random.randint(0, population[0].shape[0]-1-1) if param == 0: gene_edit = round(random.uniform(0.001, 0.1), 3) elif param == 1: gene_edit = random.randint(1, 100) elif param == 2: gene_edit = random.randint(1, 12) population[i][param] = gene_edit return population