안녕하세요. 오늘 정리할 아티클은 머신러닝 기반 응용에서 가장 중요한 하이퍼파라미터 최적화와 관련된 내용을 정리하도록 하겠습니다. 아래의 원본 링크를 참조하였습니다.
현재 머신러닝에서 하이퍼파라미터를 최적화하는 방법에는 여러가지가 있지만 가장 간단한 방법은 하이퍼파라미터 검색 공간(searching space)를 미리 정의해놓고 이 중에서 가장 높은 성능을 가지는 하이퍼파라미터를 찾으면 됩니다. 이번 포스팅에서는 3가지 단계를 이용해서 최적화해보도록 하겠습니다. 이 과정에서 사용하는 주요 라이브러리는 아래와 같습니다.
numpy
scikit-learn
scikit-optimize
neptune-client
neptune-contrib['monitoring']
위의 라이브러리들을 pip install을 이용해서 미리 설치해주시길 바랍니다. 먼저 단일 하이퍼파라미터를 이용해서 학습하는 경우입니다.
# Step 1 : Decouple search parameters from code
import pandas as pd
import lightgbm as lgb
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_iris
from sklearn.preprocessing import binarize
SEARCHING_PARAMS = {'learning_rate' : 0.4,
'max_depth' : 15,
'num_leaves' : 20,
'feature_fraction' : 0.8,
'subsample' : 0.2}
iris = load_iris()
X = iris.data
y = iris.target
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=1234)
train_data = lgb.Dataset(X_train, label=y_train)
valid_data = lgb.Dataset(X_test, label=y_test, reference=train_data)
params = {'objective' : 'multiclass',
'metric' : 'multi_logloss',
'num_class' : 3,
**SEARCHING_PARAMS}
model = lgb.train(params, train_data,
num_boost_round=300,
early_stopping_rounds=30,
valid_sets=[valid_data],
valid_names=['valid'])
score = model.best_score['valid']['multi_logloss']
print('validation multi_logloss:', score)
이때 사용하는 모델을 lightgbm이라는 모델입니다. 머신러닝에서 대중적으로 사용하는 모델이죠. 그 다음에 제가 상단에서 미리 말씀드린것처럼 하이퍼파라미터 검색 공간을 정의합니다. 이 경우에는 각 하이퍼파라미터 별로 1개씩만 해서 어떤 결과가 나오는 지 확인해보도록 하겠습니다. 그리고 제가 사용한 데이터셋은 사이킷런의 IRIS 데이터셋입니다. 이 데이터셋을 다운로드받은 뒤에 데이터셋을 train/test로 분리하게 됩니다. lightgbm 모델을 사용하려면 파라미터들을 정의해줘야하는 데 저는 다중 클래스 분류를 수행하기 때문에 objective는 multiclass, num_class에는 클래스의 개수를 적어주면 됩니다. 그러면 학습 결과가 아래와 같습니다.
.
.
.
[48] valid's multi_logloss: 0.0181457
[49] valid's multi_logloss: 0.0173856
[50] valid's multi_logloss: 0.0174167
[51] valid's multi_logloss: 0.0172946
[52] valid's multi_logloss: 0.0178999
[53] valid's multi_logloss: 0.0179912
[54] valid's multi_logloss: 0.0182791
[55] valid's multi_logloss: 0.0196716
Early stopping, best iteration is:
[25] valid's multi_logloss: 0.0103058
validation multi_logloss: 0.010305830734946463
이번에는 스크립트로 만들면 되는 데 아주 간단합니다. 그냥 위의 코드를 함수화시킨 뒤 main 네임스페이스를 정의하면 됩니다.
# Step 2 : Wrap training and evaluation into a function
import pandas as pd
import lightgbm as lgb
from sklearn.model_selection import train_test_split
from sklearn.datasets import load_iris
from sklearn.preprocessing import binarize
SEARCHING_PARAMS = {'learning_rate' : 0.4,
'max_depth' : 15,
'num_leaves' : 20,
'feature_fraction' : 0.8,
'subsample' : 0.2}
def train_evaluate(search_params) :
iris = load_iris()
X = iris.data
y = iris.target
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=1234)
train_data = lgb.Dataset(X_train, label=y_train)
valid_data = lgb.Dataset(X_test, label=y_test, reference=train_data)
params = {'objective' : 'multiclass',
'metric' : 'multi_logloss',
'num_class' : 3,
**SEARCHING_PARAMS}
model = lgb.train(params, train_data,
num_boost_round=300,
early_stopping_rounds=30,
valid_sets=[valid_data],
valid_names=['valid'])
score = model.best_score['valid']['multi_logloss']
return score
if __name__=="__main__" :
score = train_evaluate(SEARCHING_PARAMS)
print('validation multi_logloss:', score)
.
.
.
[50] valid's multi_logloss: 0.0174167
[51] valid's multi_logloss: 0.0172946
[52] valid's multi_logloss: 0.0178999
[53] valid's multi_logloss: 0.0179912
[54] valid's multi_logloss: 0.0182791
[55] valid's multi_logloss: 0.0196716
Early stopping, best iteration is:
[25] valid's multi_logloss: 0.0103058
validation multi_logloss: 0.010305830734946463
다음 스텝에서 sklearn-optimize를 이용해서 하이퍼파라미터 검색을 수행하면 됩니다.
# Step 3 : Run Hyperparameter Tuning Script
!pip install scikit-optimize
import skopt
SPACE = [
skopt.space.Real(0.01, 0.4, name='learning_rate', prior='log-uniform'),
skopt.space.Integer(1, 30, name='max_depth'),
skopt.space.Integer(2, 200, name='num_leaves'),
skopt.space.Real(0.1, 1.0, name='feature_fraction', prior='uniform'),
skopt.space.Real(0.1, 1.0, name='subsample', prior='uniform')
]
@skopt.utils.use_named_args(SPACE)
def objective(**params) :
return -1.0 * train_evaluate(params)
results = skopt.forest_minimize(objective, SPACE, n_calls=30, n_random_starts=10)
best_params = results.x
print('best parameters : ', best_params)
[50] valid's multi_logloss: 0.0174167
[51] valid's multi_logloss: 0.0172946
[52] valid's multi_logloss: 0.0178999
[53] valid's multi_logloss: 0.0179912
[54] valid's multi_logloss: 0.0182791
[55] valid's multi_logloss: 0.0196716
Early stopping, best iteration is:
[25] valid's multi_logloss: 0.0103058
best parameters : [0.15372668305868545, 13, 91, 0.9484021687593301, 0.921562802302639]
그러면 위에 처럼 가장 좋은 성능에 대한 하이퍼파라미터가 나오게 됩니다. 각각 learning rate, max-depth, num-leaves, feature-fraction, subsample입니다. 만약, 위 학습과정을 시각화하고 싶다면 neptune 라이브러리를 사용하면 됩니다.
# Step 4 : Visulizing Train process
!pip install neptune-client neptune-contrib['monitoring']
import neptune
import neptunecontrib.monitoring.skopt as sk_utils
import skopt
neptune.init(project_qualified_name='shared/onboarding',
api_token='ANONYMOUS',
)
neptune.create_experiment('hpo-on-any-script', upload_source_files=['*.py'])
SPACE = [
skopt.space.Real(0.01, 0.4, name='learning_rate', prior='log-uniform'),
skopt.space.Integer(1, 30, name='max_depth'),
skopt.space.Integer(2, 200, name='num_leaves'),
skopt.space.Real(0.1, 1.0, name='feature_fraction', prior='uniform'),
skopt.space.Real(0.1, 1.0, name='subsample', prior='uniform')
]
@skopt.utils.use_named_args(SPACE)
def objective(**params) :
return -1.0 * train_evaluate(params)
monitor = sk_utils.NeptuneMonitor()
results = skopt.forest_minimize(objective, SPACE, n_calls=100, n_random_starts=10, callback=[monitor])
sk_utils.log_results(results)
neptune.stop()
그러면 아래 그림과 같이 가장 좋은 성능을 가지는 하이퍼파라미터를 선택하는 것을 볼 수 있습니다.
'인공지능 > 아티클 정리' 카테고리의 다른 글
아티클 정리 - What is Self-Supervised-Learning in computer vision? A simple Introduction. (2) | 2021.02.25 |
---|---|
아티클 정리 - DCGAN Under 100 Lines of Code (0) | 2020.10.16 |
아티클 정리 - Volumetric Medical Image Segmentation with Vox2Vox (0) | 2020.09.11 |
아티클 정리 - Policy Gradient Reinforcement Learning in PyTorch (0) | 2020.09.09 |
아티클 정리 - Building a Face Recognizer in Python (0) | 2020.09.06 |