MLflow와 Optuna를 함께 사용 해보도록 하겠다.
시작하기 전, MLflow만 실습한 내용과 Optuna만 실습한 내용 각각은 아래 링크를 참고.
1. MLflow + Optuna 파일 작성
주의 해야 할 부분
- def objective(trial) : objective 함수 작성하고 가장 먼저 탐색할 파라미터 및 범위를 지정함
- mlflow.log_params(trial.params) : 파라미터 로깅시에 params를 따로 변수 지정하지 않고 옵튜나의 'trial.params'로 지정
- Classifier(n_estimators=trial.params['n_estimators'] : params를 classifier에 지정할 때 'trial.params[~]'
- if __name__ == '__main__' : 스크립트 실행 코드. set mlflow, optuna study, optuna optimize 파트를 실행부에 적어줌
- 'hpo-tutorial' : mlflow (set_experiment) 와 optuna (study_name) 의 실행 이름 맞춰주기
<optuna_train.py 파일 내용>
import mlflow
import optuna
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score
def objective(trial) :
# suggest new parameter
trial.suggest_int('n_estimators',100,1000, step=100)
trial.suggest_int('max_depth', 3,10)
with mlflow.start_run():
# log parameter
mlflow.log_params(trial.params)
# load data
iris = load_iris(as_frame=True)
X, y = iris['data'], iris['target']
X_train, X_valid, y_train, y_valid = train_test_split(X,y,test_size=0.3, random_state=2024)
# train data
clf = RandomForestClassifier(n_estimators=trial.params['n_estimators'], max_depth=trial.params['max_depth'], random_state=2024)
clf.fit(X_train, y_train)
# evaluate data
y_pred = clf.predict(X_valid)
acc_score = accuracy_score(y_valid, y_pred)
# log metrics
mlflow.log_metrics({'accuracy': acc_score})
return acc_score
if __name__ == '__main__' :
# set mlflow
mlflow.set_tracking_uri('http://0.0.0.0:5001')
mlflow.set_experiment('hpo-tutorial')
# study
sampler = optuna.samplers.RandomSampler(seed=2024)
study = optuna.create_study(sampler=sampler, study_name = 'hpo-tutorial', direction='maximize')
# optimize
study.optimize(objective, n_trials=5)
2. optuna_train.py 파일 실행하기
2-1) Docker Compose 실행하기
mlflow 실행을 설정했던 도커 compose 파일의 폴더 경로로 가서, compose 파일 다시 실행
아래 코드는 Docker compose 파일에 정의된 Docker 컨테이너를 백그라운드 모드로 실행하는 명령어임.
Docker compose가 구성 파일을 읽고 해당 파일에 지정된 컨테이너를 시작함.
$ docker compose up -d
2-2) MLflow 실행 확인
http://0.0.0.0:5001/ 를 주소창에 입력해 MLflow를 실행한다
2-3) optuna_train.py 파일을 실행한다
터미널에서 optuna_train.py를 실행
$ python3 optuna_train.py
3. 실행 결과 확인
다시 MLflow로 가보면, 'hpo-tutorial'이라는 이름으로 5개의 실험이 추가된 것을 확인 가능,
각각의 경우의 max_depth 와 n_estimator에 따른 accuracy 값을 확인 가능함
기본 View
compare 기능
4. Run name을 추가하기
중복된 파일 실행시, MLflow에서는 5개씩 실험이 쌓일뿐 서로 다른 실험인지 구분되지 않음.
(위의 경우 1개의 실험에 peaceful-lamb ~ grandiose ~ 까지 5개 실험이 쌓였는데, 또 다른 5개가 쌓여도 이름상 구분은 어려움)
5개씩 하나의 실험에서 나왔다는 것, 서로 다른 실험 여부를 표시하기 위한 run name, prefix를 지정해줄 필요가 있음.
uuid를 활용하여 run name에 UNIQUE_PREFIX라는 고유한 8자리의 숫자를 붙여줌으로써 실험 단위로 구분할 수 있도록 처리
import uuid
'''
'''
UNIQUE_PREFIX = str(uuid.uuid4())[:8]
def objective(trial) :
# suggest new parameter
trial.suggest_int('n_estimators', 100, 1000, step=100)
trial.suggest_int('max_depth', 3, 10)
prefix = str(uuid.uuid4())[:8]
run_name = f'{UNIQUE_PREFIX}-{trial.number}'
with mlflow.start_run(run_name=run_name) :
# log parameter
mlflow.log_params(trial.params)
'''
'''
최종 실행 코드
<optuna_train.py의 내용>
import uuid
import mlflow
import optuna
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score
UNIQUE_PREFIX = str(uuid.uuid4())[:8]
def objective(trial) :
# suggest new parameter
trial.suggest_int('n_estimators',100,1000, step=100)
trial.suggest_int('max_depth', 3,10)
run_name = f'{UNIQUE_PREFIX}-{trial.number}'
with mlflow.start_run(run_name=run_name):
# log parameter
mlflow.log_params(trial.params)
# load data
iris = load_iris(as_frame=True)
X, y = iris['data'], iris['target']
X_train, X_valid, y_train, y_valid = train_test_split(X,y,test_size=0.3, random_state=2024)
# train data
clf = RandomForestClassifier(n_estimators=trial.params['n_estimators'], max_depth=trial.params['max_depth'], random_state=2024)
clf.fit(X_train, y_train)
# evaluate data
y_pred = clf.predict(X_valid)
acc_score = accuracy_score(y_valid, y_pred)
# log metrics
mlflow.log_metrics({'accuracy': acc_score})
return acc_score
if __name__ == '__main__' :
# set mlflow
mlflow.set_tracking_uri('http://0.0.0.0:5001')
mlflow.set_experiment('hpo-tutorial')
# study
sampler = optuna.samplers.RandomSampler(seed=2024)
study = optuna.create_study(sampler=sampler, study_name = 'hpo-tutorial', direction='maximize')
# optimize
study.optimize(objective, n_trials=5)
실행 결과 다시 확인
$ python3 optuna_train.py
연속으로 여러번 py파일을 실행해도, 이제 동일한 실험은 고유 id로 묶여있기 때문에, 서로 구분이 쉬워짐. (22695a51, 549a803c)
* 프로그래머스의 마키나락스 MLOPS 강의를 참고하여 작성함
'MLOps' 카테고리의 다른 글
[MLOps] 12. 데이터 관리 (feat.MinIO 소개) (0) | 2024.04.22 |
---|---|
[MLOps] 11. 교차검증 (Cross-validation) (0) | 2024.04.22 |
[MLOps] 9. Optuna 실습 (0) | 2024.04.22 |
[MLOps] 8. 하이퍼파라미터 최적화 (1) | 2024.04.18 |
[MLOps] 7. MLflow 로깅 실습 (1) | 2024.04.18 |