Itmom's blog

Bayesian Optimization 본문

Machine Learning

Bayesian Optimization

Itmom 2022. 2. 26. 22:00

1. 계기

이전부터 계속 생각은 하고 있었는데, 논문에 나와 있는 각종 최적화 기법을 구현해 오픈 소스로 남겨 오픈 소스 생태계에 기여하고 싶다는 욕심이 있다.

호랑이는 죽어서 가죽을 남기고, 사람은 죽어서 코드를 남긴다.

회사를 다니면서 이모저모 코딩 실력이 늘긴 했지만, 그래도 논문 구현을 하기에는 실력이 부족하다고 생각했고, 이미 구현되어 있는 다른 open source들을 보면서 사람들이 애용하는 논문 구현 오픈 소스는 어떤 식으로 구현되어 있는가를 참고해 보고 싶었다.

가장 먼저 관심있게 찾아봤던 것은 효과적인 최적화를 위한 hyperparameter 탐색 기법 중 하나인 TPE(Tree of Parzen Estimators)를 구현한 hyperopt라는 library였다. 하지만, 기본적인 hyperparameter 탐색 기법부터 이해하구 코드를 분석해보아야겠다는 생각을 하게 되었고, 이에 Bayesian Optimization을 구현한 library인 BayesianOptimization을 보게 되었다. 선정 이유는, 비록 2년전에 개발이 중단된 library이지만, python으로 구현되어 있기도 하고, 코드 수가 5.0k에 불과함에도 5.4k라는 나름 적지 않은 스타 수를 가지고 있어서 흥미가 생겼다.

코드를 하나하나 다 뜯어보고 나니 내 머리에만 담아두기가 아쉬워 (

내 머리를 믿지 못하는 건 안 비밀

) 리뷰 글을 작성하게 되었다.

 

2. Bayesian Optimization이란?

Bayesian Optimization에 대한 이론적 디테일은 다음 논문에서 확인할 수 있다. 다음의 5 step으로 요약해볼 수 있다.

  1. 기존에 알고 있던 입력값-함수값 점들의 모음 ${(x_1, f(x_1)),(x_2, f(x_2)),...,(x_n, f(x_n))}$에 대한 surrogate model을 구한다. (어떤 확률적 추정에 기반해도 상관없지만, 리뷰하고자 하는 library는 Gaussian Process Regression을 이용하였고, kernel로는 Matern Covariance를 사용하였다.)
  2. Surrogate 함수에서 최적인 입력값-함수값 쌍을 찾는다.
  3. 해당 입력값 실제 목적함수에 적용한다.
  4. 실제 목적함수의 입력값에 대한 함수값 (loss 등)을 얻어 입력값-함수값 모음에 추가한다.
  5. 2~4의 과정을 반복한다.

다음 그림과 같은 prediction을 얻을 수 있다.

Gaussian Process RegressionMatern Covariance

 

3. Open Source 사용법

크게 두 가지, Bayesian optimization 기법과 Sequential Domain Reduction 기법이 구현되어 있다.

 

1) Bayesian Optimization 사용 방법

pip install bayesian-optimization

from bayes_opt import BayesianOptimization

# Bounded region of parameter space
pbounds = {'x': (2, 4), 'y': (-3, 3)}

optimizer = BayesianOptimization(
    f=black_box_function,
    pbounds=pbounds,
    random_state=1,
)

optimizer.maximize(
    init_points=2,
    n_iter=3,
)

"""
|   iter    |  target   |     x     |     y     |
-------------------------------------------------
|  1        | -7.135    |  2.834    |  1.322    |
|  2        | -7.78     |  2.0      | -1.186    |
|  3        | -19.0     |  4.0      |  3.0      |
|  4        | -16.3     |  2.378    | -2.413    |
|  5        | -4.441    |  2.105    | -0.005822 |
=================================================
"""

print(optimizer.max)
# {'target': -4.441293113411222, 'params': {'y': -0.005822117636089974, 'x': 2.104665051994087}}

 

2) Sequential Domain Reduction 사용 방법

참고: ON THE ROBUSTNESS OF A SIMPLE DOMAIN REDUCTION
SCHEME FOR SIMULATION-BASED OPTIMIZATION

import numpy as np
from bayes_opt import BayesianOptimization
from bayes_opt import SequentialDomainReductionTransformer

def ackley(**kwargs):
    x = np.fromiter(kwargs.values(), dtype=float)
    arg1 = -0.2 * np.sqrt(0.5 * (x[0] ** 2 + x[1] ** 2))
    arg2 = 0.5 * (np.cos(2. * np.pi * x[0]) + np.cos(2. * np.pi * x[1]))
    return -1.0 * (-20. * np.exp(arg1) - np.exp(arg2) + 20. + np.e)

pbounds = {'x': (-5, 5), 'y': (-5, 5)}
bounds_transformer = SequentialDomainReductionTransformer()

mutating_optimizer = BayesianOptimization(
    f=ackley,
    pbounds=pbounds,
    verbose=0,
    random_state=1,
    bounds_transformer=bounds_transformer
)

더 자세한 example들은 다음 링크에서 확인할 수 있다. github link

 

GitHub - fmfn/BayesianOptimization: A Python implementation of global optimization with gaussian processes.

A Python implementation of global optimization with gaussian processes. - GitHub - fmfn/BayesianOptimization: A Python implementation of global optimization with gaussian processes.

github.com

 

4. 소스 코드 구성

pip에 해당 library를 등록하기 위한 설정 파일들과, coverage 측정을 위한 설정 파일, test 코드들이 있는 폴더 및 파일들이 있지만, 주가 되는 Bayesian optimization에 대한 source 코드는 bayes_opt라는 폴더 안에 모두 담겨 있다.

  • __init__.py: import를 위한 설정 파일
  • bayesian_optimization.py: bayesian optimization의 lifecycle을 관리하는 코드
  • domain_reduction.py: sequential domain reduction의 lifecycle을 관리하는 코드
  • event.py: optimization event에 대한 constant 파일
  • logger.py: logger 추상 클래스와 그 구현체에 대한 파일
  • observer.py: logger를 위한 metric 변화를 check하는 class에 대한 파일
  • target_space.py: optimize를 수행할 space에 대한 정의를 담은 파일
  • util.py: acquisition function에 대한 maximization 함수부터, Upper Confidence Bounds method, Expected Improvement method, Probability Of Improvement criterion 등 다양한 함수 및 class에 대한 구현체가 존재하는 파일

코드의 큰 흐름만 설명하면, BayesianOptimization class가 domain reduction method와 boundary를 포함한 각종 변수값을 주입받고, Logger와 Events, 그리고 TargetSpace class를 적절하게 사용해 optimization의 event lifecycle을 관리하고 로그를 남기는 방식이다.

util은... 음... logging을 위한 색깔에 대한 class까지 있을 정도로 잡다한 function 및 class들이 모아져 있으니 관심 있으면 직접 소스코드를 살펴보기를 바란다. (

설명이 귀찮다

)

'Machine Learning' 카테고리의 다른 글

GNN Explainer  (0) 2022.02.26
Heterogeneous Graphs and RGCN (Relational GCN)  (0) 2022.02.26