[PyGAD] Genetic Algorithm (GA) 시작하기

Bobae·2023년 9월 5일
0

PyGAD

목록 보기
1/6

PyGAD는 Genetic Algorithm을 사용할 수 있게 하는 파이썬의 오픈소스입니다. PyGAD는 다양한 종류의 crossover, mutation, parent selection을 지원합니다. 또한, fitness function을 커스터마이징함으로써 다양한 유형의 문제를 최적화 할 수 있습니다.

소스코드를 통한 구현 예시입니다.

이번 포스팅의 예에서는 함수 yy가 주어져 있고, (x1,x2,x3,x4,x5,x6)=(4,2,3.5,5,11,4.7)(x1,x2,x3,x4,x5,x6)=(4,-2,3.5,5,-11,-4.7) 로 정의되어 있다고 가정합니다.

y=w1x1+w2x2+w3x3+w4x4+w5x5+w6x6y = w1x1 + w2x2 + w3x3 + w4x4 + w5x5 + w6x6

함수 yy4444에 근접하게 하는 최적의 w1,w2,w3,w4,w5,w6w1, w2, w3, w4, w5, w6는 무엇일까요?
우리는 이 함수를 최적화 하기 위해서 GA 알고리즘을 사용합니다.

우선 필요한 라이브러리들을 다운받아 줍니다.

!pip install pygad
import pygad
import numpy
import math

파라미터들을 초기화합니다.

num_generations = 100 # Number of generations. - 10, 50, 100
num_parents_mating = 40 # Number of solutions to be selected as parents in the mating pool.
sol_per_pop = 50 # Number of solutions in the population; number of chromosomes 5, 20, 50
num_genes = len(function_inputs)

input 데이터, target output, 파라미터 w1..w6w1..w6의 범위, 그리고 fitness function을 정의합니다.

function_inputs = [4,-2,3.5,5,-11,-4.7] # Function inputs.
desired_output = 44 # Function output.

range_ben = [{'low': -30, 'high': 30}, {'low': -30, 'high': 30}, {'low': -30, 'high': 30}, {'low': -30, 'high': 30}, {'low': -30, 'high': 30}, {'low': -30, 'high': 30}]
def fitness_func(ga_instance, solution, solution_idx):
    # original test function :
    output = numpy.sum(solution*function_inputs)
    fitness = 1000- (numpy.abs(output - desired_output) + 0.000001) # performing minimization desired_output=y=44
    return fitness

다음 on_generation() 메소드는 각 generation별 GA의 결과값을 보여줍니다.

last_fitness = 0
def on_generation(ga_instance):
    global last_fitness
    print("Generation = {generation}".format(generation=ga_instance.generations_completed))
    print("Fitness    = {fitness}".format(fitness=ga_instance.best_solution(pop_fitness=ga_instance.last_generation_fitness)[1]))
    print("Change     = {change}".format(change=ga_instance.best_solution(pop_fitness=ga_instance.last_generation_fitness)[1] - last_fitness))
    last_fitness = ga_instance.best_solution(pop_fitness=ga_instance.last_generation_fitness)[1]

GA를 실행하기 전 파라미터들을 셋팅해줍니다.

ga_instance = pygad.GA(num_generations=num_generations,
                       num_parents_mating=num_parents_mating,
                       sol_per_pop=sol_per_pop,
                       num_genes=num_genes,
                       gene_type=float,
                       gene_space=range_ben,
                       fitness_func=fitness_func,
                       on_generation=on_generation)

GA를 실행합니다. 후속 세대로 갈수록, 점점 fitness value와 우리의 target output값이 비슷해지는 것을 확인할 수 있습니다.

ga_instance.run()

output:

Generation = 1
Fitness    = 997.9177930856762
Change     = 997.9177930856762
Generation = 2
Fitness    = 998.9081446191583
Change     = 0.9903515334821122
Generation = 3
Fitness    = 998.9081446191583
Change     = 0.0
...
Generation = 98
Fitness    = 999.9986527749419
Change     = 0.0
Generation = 99
Fitness    = 999.9986527749419
Change     = 0.0
Generation = 100
Fitness    = 999.9986527749419
Change     = 0.0

실행 후 Generation-Fitness plot을 통해 진행과정을 확인할 수 있습니다. 20세대 이후부터는, 거의 Fitness value가 converge된 것을 확인할 수 있습니다.

ga_instance.plot_fitness()

best_solution() 메소드를 통해 GA를 사용한 최적의 솔루션 결과를 확인할 수 있습니다.

# Returning the details of the best solution.
solution, solution_fitness, solution_idx = ga_instance.best_solution(ga_instance.last_generation_fitness)
print("Parameters of the best solution : {solution}".format(solution=solution))
print("Fitness value of the best solution = {solution_fitness}".format(solution_fitness=solution_fitness))
print("Index of the best solution : {solution_idx}".format(solution_idx=solution_idx))

prediction = numpy.sum(numpy.array(function_inputs)*solution)
print("Predicted output based on the best solution : {prediction}".format(prediction=prediction))
if ga_instance.best_solution_generation != -1:
    print("Best fitness value reached after {best_solution_generation} generations.".format(best_solution_generation=ga_instance.best_solution_generation))

output:

Parameters of the best solution : [  0.61901556 -13.35517528  17.16683406 -10.2892967   -9.90693565
  21.87208391]
Fitness value of the best solution = 999.9986527749419
Index of the best solution : 0
Predicted output based on the best solution : 44.00134622505814
Best fitness value reached after 10 generations.

GA instance를 로컬에 저장합니다.

# Saving the GA instance.
filename = 'genetic' # The filename to which the instance is saved. The name is without extension.
ga_instance.save(filename=filename)

저장한 GA instance를 다시 불러와 사용할 수 있습니다.

# Loading the saved GA instance.
loaded_ga_instance = pygad.load(filename=filename)
loaded_ga_instance

이 외에도, GA 파라미터(the number of generations, population size)를 조정하거나, 다른 Fitness functions들을 사용하여 다양한 실험들을 해볼 수 있습니다.

profile
현재 머신러닝, 딥러닝을 공부하고 있습니다.

0개의 댓글

관련 채용 정보