Bayesian Optimization
베이지안 최적화(Bayesian Optimization)란?#
베이지안 최적화는 머신러닝에서 하이퍼파라미터 튜닝을 똑똑하게, 그리고 효율적으로 수행하기 위한 방법. 하이퍼파라미터는 모델을 학습시키기 전에 사람이 직접 설정해야 하는 값들인데, 이 값들이 모델의 성능에 큰 영향을 미침. 예를 들어 학습률(learning rate)이나 트리의 깊이 같은 것들이 하이퍼파라미터.
문제는 이 값들을 무작정 시도해보는 건 시간도 오래 걸리고 비효율적이라는 점
다른 하이퍼 파라미터 튜닝 방법#
그리드 서치(Grid Search)#
- 가능한 하이퍼파라미터 값들을 미리 정하고, 모든 조합을 하나씩 시도함
- 장점: 최적의 조합을 놓칠 가능성이 적음
- 단점: 조합이 많아지면 시간이 너무 오래 걸림
랜덤 서치(Random Search)#
- 하이퍼파라미터 값 범위에서 무작위로 조합을 골라 테스트함
- 장점: 더 넓은 범위를 빠르게 탐색할 수 있음
- 단점: 운이 나쁘면 좋은 조합을 놓칠 수도 있음
이런 문제들 때문에 베이지안 최적화가 등장함
베이지안 최적화는 이전 테스트 결과를 보고 다음에 시도할 조합을 똑똑하게 예측함
베이지안 최적화의 기본 아이디어 쉽게 이해하기#
베이지안 최적화는 두 가지 중요한 도구를 사용함
대체 모델(Surrogate Model)#
- 우리가 최적화하려는 진짜 함수(목적 함수)를 대신해서 근사해주는 모델
- 진짜 함수를 매번 계산하는 건 비용이 많이 들 수 있으니, 대체 모델이 “이 함수는 대충 이렇게 생겼을 거야"라고 예측함
- 주로 **가우시안 프로세스(Gaussian Process)**라는 통계 모델을 사용함. 이건 함수의 값뿐만 아니라 그 값이 얼마나 확실한지(불확실정)도 같이 알려줌
획득 함수(Acquisition Function)#
- 대체 모델이 예측한 정보를 바탕으로 “다음엔 어디를 시도해볼까?“를 결정하는 함수
- 이 함수는 두 가지를 고려함
- 탐색(Exploration): 아직 잘 모르는 영역을 시도해보자
- 활용(Exploitation): 지금까지 좋은 성능을 보인 곳 근처를 더 파보자
- 이 균형을 잘 맞춰서 다음 시도 지점을 똑똑하게 골라줌
베이지안 최적화의 동작을 단계별로 알아보기#
베이지안 최적화가 실제로 어떻게 작동하는지, 예시를 통해 단계별로 알아보겠음 우리가 어떤 함수의 최소값을 찾고 있다고 생각해보면 ex: $f(x) = (x-2)^2$
- 초기화
- 처음엔 어디가 좋은지 모르니까, 몇 개의 하이퍼파라미터 조합을 무작위로 골라서 성능을 평가함
- ex: $x = 0$일 때 $f(0) = 4, x = 5$일때 $f(5) = 9$ 이런 식으로 몇 번 시도해봄
- 대체 모델 학습
- 이 데이터를 바탕으로 대체 모델(가우시안 프로세스)이 “이 함수는 대략 이렇게 생겼을 거야"라고 예측함
- 동시에 “여긴 확실하고, 여긴 좀 불확실해"라는 정보도 같이 줌
- 획득 함수로 다음 지점 선택
- 획득 함수가 대체 모델을 보고 “여기 시도하면 좋을 것 같아"라고 추천해줌
- ex: “$x = 2$ 근처가 좋아 보이네” 라고 예측할 수 있음
- 모델 평가
- 추천받은 $x = 2$를 실제로 넣어서 함수 값을 계산해봄. $f(2) = 0$이 나옴. “오 이거 좋은데” 싶음
- 이 결과를 다시 데이터에 추가함
- 반복
- 새로운 데이터를 대체 모델에 반영하고, 다시 획득 함수로 다음 지점을 찾는 과정을 반복함
- 점점 더 좋은 값에 가까워짐
베이지안 최적화의 장점과 단점#
장점
- 효율성: 무작위로 시도하는 것보다 훨씬 적은 시도로 좋은 하이퍼파라미터를 찾을 수 있음
- 똑똑한 선택: 이전 결과를 바탕으로 어디를 시도할지 예측하니까 시간과 비용이 절약됨
- 비용이 높은 경우에 특히 유용: 모델 학습에 하루씩 걸리는 상황이라면, 베이지안 최적화가 큰 도움이 됨
단점
- 조금 복잡함: 가우시안 프로세스나 획득 함수를 이해하려면 약간의 수학적 배경이 필요함
- 계산 비용: 대체 모델 자체를 학습시키는 데 시간이 걸릴 수 있음
- 한계: 하이퍼파라미터가 너무 많아지면(고차원) 효율이 떨어질 수 있음
예시 코드#
# 필요한 라이브러리 설치
# !pip install scikit-optimize
# 필요한 라이브러리 임포트
import numpy as np
from skopt import gp_minimize
from skopt.space import Real
# 최적화할 함수 정의
def objective(x):
return (x[0] - 2) ** 2 # x는 리스트이므로 x[0]를 사용
# 하이퍼파라미터 범위 설정
space = [Real(-10, 10, name='x')] # x는 -10에서 10 사이의 실수
# 베이지안 최적화 실행
res = gp_minimize(
objective, # 최적화할 함수
space, # 하이퍼파라미터 범위
n_calls=10, # 총 10번 시도
random_state=0 # 결과 재현성을 위해
)
# 결과 출력
print(f"최적의 x 값: {res.x[0]}") # 최적의 하이퍼파라미터
print(f"최적의 함수 값: {res.fun}") # 그때의 함수 값
을 실행하면
최적의 x 값: 1.8568923645003679
최적의 함수 값: 0.020479795338295567
이렇게 최적화 결과로 res.x[0]
이 약 2
에 가깝게 나오고, rest.fun
은 0
에 가까운 값이 나옴