Часто в машинном обучении нам всегда нужно оптимизировать функции или параметры. Вот почему использование алгоритмов оптимизации в нескольких методах машинного обучения становится очень распространенным. Существует несколько алгоритмов оптимизации, но генетический алгоритм нашел применение во многих областях машинного обучения. В этом уроке я попытаюсь объяснить, что такое генетический алгоритм. Мы также реализуем простую версию генетического алгоритма и объясним его интуицию. После этого мы попытаемся понять некоторые варианты использования генетического алгоритма в машинном обучении.
Что такое генетический алгоритм?
Генетический алгоритм - это алгоритм оптимизации, основанный на теории эволюции. Он сосредоточен на выборе лучших параметров или составляющих популяции на основе функции приспособленности, которая показывает, насколько хорошо они удовлетворяют желаемой задаче оптимизации. Затем эти параметры видоизменяются в надежде, что они дадут более здоровое потомство. По сути, это основная интуиция, лежащая в основе генетического алгоритма.
Реализация генетического алгоритма с нуля
Базовый генетический алгоритм состоит из следующих этапов:
- Инициализировать популяцию
- Создать функцию расчета фитнеса
- Определить брачный пул
- Выберите родителей
- Перейти к мату
- Мутировать
- Получите потомство, которое будет новой популяцией для шага 1.
- Вернитесь к 2 и повторяйте, пока не будет выполнено условие остановки.
Вот простая блок-схема, объясняющая
Теперь приступим к реализации генетического алгоритма с нуля. Мы будем стремиться оптимизировать простое линейное уравнение, которое - F (X) = A1X1 + A2X2 + A3X3 + A4X4. Где X1 = 4, X2 = -2, X3 = 3,5 и X4 = -4,2
Все выбрано случайно.
Генетический алгоритм поможет нам определить лучшие множители - значения A - которые дадут максимальное значение F (X) в количестве данного поколения. Мы создали несколько функций, которые помогают нам выполнять расчет пригодности, родительский отбор, кроссовер и мутацию.
Мы проведем нашу аналитическую оценку на протяжении десяти поколений и будем иметь по 6 решений в каждом поколении.
Наш основной генетический алгоритм будет состоять из следующих этапов:
Инициализация популяции: это включает в себя инициализацию вашего образца решения. Для нашей совокупности решений они инициализируются между -5 и плюс 5 (выбираются случайным образом), как показано ниже:
#Import numpy library import numpy as np #Set seed for reproducability np.random.seed(100)
Создание функции расчета пригодности. Теперь мы перейдем к циклическому перебору количества поколений и вычислению пригодности каждого решения в поколении, начиная с нашего первоначального решения. Эта фитнес-функция будет рассчитана с помощью нашей уже созданной фитнес-функции, которая помогает нам максимизировать линейное уравнение F (X). Расчет пригодности для каждого поколения можно увидеть ниже:
#Calcuate fitness of population def calculate_fitness(inputs, population): ''' Description: This function calculates the fitness of our solutions Input Arguments: input values and a population of weights Output: Fitness - a fitness value ''' fitness = np.sum(population*inputs, axis=1) return fitness
Выберите родителей для спаривания: мы перейдем к выбору родительского пула для создания следующего поколения на основе функции пригодности. Это означает, что мы выберем наиболее подходящих родителей в каждом поколении и будем использовать их для создания потомков следующего поколения. Мы сделаем это с помощью нашей функции choose_mating. Из каждого поколения мы выберем трех наиболее приспособленных родителей, как показано ниже:
#Choose parents to mate def choose_mating(population, fitness, number_of_parents): ''' Description: This function chooses the most fit solutions to mate in order to yield the next generation Input Arguments: a population, the fitness and the number of parents required to mate Output: the parents to mate ''' #initialize empty numpy array to hold parents parents = np.empty((number_of_parents, population.shape[1])) #loop to fill the created parents array with the fittest solutions and stop at the required number of parents for number in range(number_of_parents): maximum_fitness_index = np.where(fitness == np.max(fitness)) maximum_fitness_index = maximum_fitness_index[0][0] parents[number, :] = population[maximum_fitness_index, :] fitness[maximum_fitness_index] = -99999999999 return parents
Спаривание родителей. Затем мы приступим к спариванию родителей, выбранных из предыдущего поколения, чтобы создать следующее поколение. Мы воспользуемся пересечением в одну точку и выберем точку пересечения в центре родителей. Это означает, что ген первой половины первого родителя будет первым геном потомства и таким же геном второй половины второго родителя. Это выполняется с помощью кода ниже:
#Perform cross over def crossingover(parents, size_of_offspring): ''' Description: This function performs a one point cross over operation on the parents. Input Arguments: Parents - the parents pool to be crossed over size of offspring - the size of offspring required Output: offspring - the crossed over offspring ''' # initialize an empty numpy array to hold the offsprings offspring = np.empty(size_of_offspring) # specify the point of cross over - at the center in our case point_of_crossover = np.uint8(size_of_offspring[1]/2) #loop over the number of offspring required to get the required offsprings for k in range(size_of_offspring[0]): # get index of first parent to be mated parent1_index = k%parents.shape[0] # get index of second parent to be mated parent2_index = (k+1)%parents.shape[0] # proceed to assign the first half of the first parents gene to the first half gene of the offspring offspring[k, 0:point_of_crossover] = parents[parent1_index, 0:point_of_crossover] # proceed to assign the second half of the second parents gene to the second half gene of the offspring offspring[k, point_of_crossover:] = parents[parent2_index, point_of_crossover:] return offspring
- Выполните мутацию. Затем мы вызовем небольшие случайные изменения в гене потомства, чтобы уменьшить чрезмерную симметрию между родителями и потомками. Это делается ниже:
#perform mutation def mutation(cross_over_offspring): ''' Description: This function performs some random variation to the genes of the solutions by adding a random bias number. Input - cross_over_offspring - offspring obtained from the cross over function Output - Mutated offspring ''' #loop over the offsprings and add a random bias number to their genes for number in range(cross_over_offspring.shape[0]): # Create the random bias number to be used for muation. The arguments taken are the limits(low and high) and the size random_bias_number = np.random.uniform(-1.5, 1.5, 1) #Proceed to mutate by adding the bias number cross_over_offspring[number, 3] = cross_over_offspring[number, 3] + random_bias_number return cross_over_offspring
Получить наилучшее решение: пройдя цикл по каждому поколению, мы перейдем к получению наиболее подходящего решения из решений в последнем поколении. Это будет нашим наиболее подходящим решением, полученным с помощью генетического алгоритма. Теперь мы приступим к выполнению генетического алгоритма на простом примере функции, стремясь максимизировать ее.
Это уравнение задается как F (X) = A1X1 + A2X2 + A3X3 + A4X4F (X) = A1X1 + A2X2 + A3X3 + A4X4, где X1 = 4 X2 = -2 X3 = 3,5 X4 = -4,2 Все выбираются случайным образом.
Мы будем стремиться оптимизировать значения - A1, A2, A3 и A4, чтобы максимизировать функцию F (X). Мы начнем с набора входных данных X, а затем укажем количество весов. Затем мы указываем количество поколений, через которые будет происходить спаривание, и в конце выбираем лучшие решения.
Созданные ранее функции будут объединены для создания генетического алгоритма, который поможет нам получить максимум за указанные поколения.
''' Implementing the GA ''' # Specify inputs of the equation ( X values) inputs = [4,-2,3.5,-4.2] # Specify the number of weights or multipliers (A values, in our case) for each input which we are looking to optimize number_of_weights = 4 # Specify the number of solutions in each generation. Each solution will have the number of weights solutions = 6 #Specify the number of parents mating to yield the specified number of solutions number_of_parents_mating = 3 # Define the population size based on the number of parents mating and the number of solutions population_size = (solutions,number_of_weights) #randomly create the inital population according to the specified population size new_population = np.random.uniform(low=-5.0, high=5.0, size=population_size) #Print out the initialized population print(new_population) #Specify the number of generations to mutate through number_of_generations = 10 #Loop over the specified number of generations for generation in range(number_of_generations): #Print the generation in which we are currently looping through to keep track print("Generation : ", generation) # Calculate the fitness of the population in the current generation fitness = calculate_fitness(inputs, new_population) # Proceed to select the most fit parents to mate parents = choose_mating(new_population, fitness, number_of_parents_mating) # Proceed to create offsprings via the one point cross over crossover = crossingover(parents, size_of_offspring=(population_size[0]-parents.shape[0], number_of_weights)) # Proceed to add random bias to the genes of the created offspring via the mutation function mutated = mutation(crossover) # Proceed to create the new population from the parents and the mutated new_population[0:parents.shape[0], :] = parents new_population[parents.shape[0]:, :] = mutated # Get the best or most fit solution in this current generation print("Best result : ", np.max(np.sum(new_population*inputs, axis=1))) #Calculate fitness of final generation fitness = calculate_fitness(inputs, new_population) # Get most fit solution of final generation most_fit_index = np.where(fitness == np.max(fitness)) #Print out the best solution print("Best solution : ", new_population[most_fit_index, :]) print("Best solution fitness : ", fitness[most_fit_index])
Использование генетического алгоритма в машинном обучении
- Выбор функций. Генетический алгоритм (GA) можно использовать для выбора функций для обучения алгоритмов машинного обучения. GA будет стремиться оптимизировать показатель производительности модели машинного обучения, выбирая лучшие функции, которые дают это. Учеными было выполнено много работ по использованию GA для выбора функций в алгоритмах машинного обучения - здесь и
- Настройка гиперпараметров: гиперпараметры алгоритмов машинного обучения и нейронных сетей могут быть настроены для оптимизации производительности модели с использованием генетического алгоритма. Это потребует использования ГА для поиска наиболее подходящих гиперпараметров, которые оптимизируют производительность модели и уменьшают функцию затрат.
- Обучение с подкреплением. Обучение с подкреплением идеально подходит для генетического алгоритма, поскольку оба они направлены на оптимизацию решений на основе предыдущих. Было много применений генетического алгоритма в обучении с подкреплением, например, здесь и
Генетический алгоритм - один из самых популярных алгоритмов оптимизации. Как видите, он также имеет широкий спектр областей применения в машинном обучении. Области применения ограничены только вашим воображением. Теперь, когда вы знаете все, что нужно знать о генетическом алгоритме, вы можете эффективно использовать его для оптимизации своих моделей машинного обучения.
Вот путь к Jupyter Notebook
Первоначально опубликовано на www.tech-quantum.com 7 октября 2018 г.