본문 바로가기
인공신경망(DL)/Neural Networks

Neural Network Hyperparameter

by kiimy 2021. 8. 16.
728x90
728x90
  • Part 1: 대표적인 하이퍼 파라미터를 설명 할 수 있습니다
  • Part 2: ETF (Experiment Tracking Framework)에 대해 알아보고 적용할 수 있습니다.
  • Part 3: (Optional) RandomSearch를 사용해서 하이퍼 파라미터 공간에서 최적의 하이퍼 파라미터를 찾을 수 있습니다

진행방식

  • 데이터를 다운로드 받고 읽어옴(load)
  • 데이터 클리닝을 진행 (필수는 아니지만 추천) / StandardScaler, MinMaxScaler
  • Keras MLP model을 만들고, 학습 진행

* Hyperparameter

  • batch_size
  • training epochs
  • optimizer
  • learning rate (optimizer에 따라서 해당되면)
  • momentum (optimizer에 따라서 해당되면)
  • activation functions
  • network weight initialization
  • dropout regularization
  • number of neurons in the hidden layer

하이퍼파라미터 튜닝방식

  • 1. 노가다
  • 2. Grid Search
  • 3. Random Search ==  keras-tuner

# Grid = 특정 파라미터 지정

# Random = 범위를 지정

  • 4. Bayesian Methods ==  keras-tune

-  실험자가 결과를 보고 추후 탐색에 그 결과에서 얻은 정보를 반영

== 하이퍼 파라미터 튜닝 방식의 "하이퍼 파라미터 튜닝"

GridSearchCV

import numpy as np
import keras
import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Flatten, Dense, Dropout
from keras.wrappers.scikit_learn import KerasClassifier
from sklearn.model_selection import GridSearchCV
import kerastuner as kt
from tensorflow.keras.constraints import MaxNorm
from tensorflow.keras import regularizers

# 데이터 불러오기
(X_train, y_train), (X_test, y_test) = cifar100.load_data()

# 정규화(전처리)
### Your Code Here ### ==> train data 가장 큰 숫자 확인 (0~1로 만들어주기)

X_train = X_train / 255.
X_test = X_test /255.


# 모델 함수 정의 ( KerasClassfifer 사용을 위한 )
def model_builder():
  model= Sequential(
      [

       Flatten(input_shape=(32,32,3)), # train data.shape ==> 1차원형태로 변경
       Dense(128, activation='relu'),
       Dense(64, activation='relu'),
       Dense(100, activation='softmax') # test data == class가 100개 / np.unique(y_test)
      ]
  )


  # 모델 컴파일( 학습과정 선택 )
  model.compile(optimizer='adam',
                loss='sparse_categorical_crossentropy',
                metrics='acc')
                
  return model


# kerasclassifier로 모델 생성
model= KerasClassifier(build_fn=model_builder, verbose=0)


# param_grid 설정
batch_size = [32, 64, 128, 256]
epochs = [10, 20, 30, 40]
param_grid= dict(batch_size=batch_size, epochs=epochs)


# GridSearchCV / cv=3
grid= GridSearchCV(estimator=model, param_grid=param_grid, n_jobs=-1, cv=3)
grid_result = grid.fit(X_train, y_train)

# best_params 선정 (epochs, batch_size) 가 나옴
print(f'best_score:{grid_result.best_score_}, bset_params:{grid_result.best_params}')

# 이후에 해당 param로 적용한 다음 최적화 알고리즘 또한 찾을 수 있다.
def model_builder(구하고하는 param 설정):
'''
# param 종류
* activation= , ( Dense( activation= ) )
* optimizer= , ( compile(optimier= ) )
* metrics= , ( compile(metrics= [ ] ) )
* initializer(init_mode)= , ( Dense(kernel_initializer= ) )

① Sigmoid ⇒ Xavier 초기화를 사용하는 것이 유리
② ReLU ⇒ He 초기화 사용하는 것이 유리
['uniform', 'lecun_uniform', 'normal', 'zero', 'glorot_normal', 'glorot_uniform', 'he_normal', 'he_uniform']

* dropout_rate= , weight_constraint=
( Seuqential( [ Dropout(dropout_rate) ] /
Dense(kernel_constraint= MaxNorm(weight_constraint)) )

* neurons(units)= ( Dense(units=units) )

* learn_rate, momentum = learning_rate decay

from keras.optimizers import Adam, SGD ...
Sequential에 생성 optimizer = Adam( lr= learn_rate, momentum= momentum )
그리고 compile( optimizer =optimizer )
'''

  model= Sequential(
      [
       Flatten(input_shape=(32,32,3)), # train data.shape ==> 1차원형태로 변경
       Dense(128, activation='relu'),
       Dense(64, activation='relu'),
       Dense(100, activation='softmax') # test data == class가 100개 / np.unique(y_test)
      ]
  )

  # 모델 컴파일( 학습과정 선택 )
  model.compile(optimizer='adam',
                loss='sparse_categorical_crossentropy',
                metrics='acc')
                
  return model

model= KerasClassifier(build_fn=model_builder, batch_size= 최적, epochs= 최적, verbose=0)
'''
# param_grid 설정
param = [   .....  ]
param_grid = dict(param= param)

# GridSearchCV / cv=3
grid= GridSearchCV(estimator=model, param_grid=param_grid, n_jobs=-1, cv=3)
grid_result = grid.fit(X_train, y_train)

# best_params 선정 (epochs, batch_size) 가 나옴
print(f'best_score:{grid_result.best_score_}, bset_params:{grid_result.best_params}')
'''
# parameter 결과 접근 방법

scores_df = pd.DataFrame(grid_dtree.cv_results_)

# or 

means = grid_result.cv_results_['mean_test_score']
stds = grid_result.cv_results_['std_test_score']
params = grid_result.cv_results_['params']
for mean, stdev, param in zip(means, stds, params):
    print(f"Means: {mean}, Stdev: {stdev} with: {param}")

Keras-tuner

!pip install -U keras-tuner 모듈 설치
import kerastuner as kt
from keras.optimizers import Adam, SGD ...

def build_model(hp): 
  model = Sequential(
      [
       Flatten(input_shape=(28,28)),
       
       # 첫 번째 Dense layer에서 노드 수를 조정(32-512)합니다.
       Dense(hp.Int('units',
                    min_value=32,
                    max_value=512,
                    step=32), activation='relu'),
       Dense(10, activation='softmax')
      ]
  )

     # Dense Layer에 unit수 선택 ( 첫번째 Dense layer
     # 정수형 타입 32부터 512까지 step 32 범위 내에서 탐색 # activation 은 relu 사용 
     # 변수 지정해서 사용시
     hp_learning_rate = hp.Choice( 'learninr_rate', values = [1e-2, 1e-3, 13-4] )

     # 학습률은 자주 쓰이는 0.01, 0.001, 0.0001 3개의 값 중 탐색
     model.compile(optimizer=Adam(hp.Choice('learning_rate',
                                                   values=[1e-2, 1e-3, 1e-4])),
                           loss='sparse_categorical_crossentropy', metrics=['accuracy']) 

     return model

'''
튜너 인스터스화 진행
'''

튜너를 인스턴스화하고 하이퍼 튜닝을 수행

Hyperband

Hyperband tuning 알고리즘은 적응형 리소스 할당 및 early-stopping 기능을

사용하여 고성능 모델을 신속하게 통합

from kerastuner.tuners import RandomSearch
from kerastuner.tuners import Hyperband
import kerastuner as kt

# [ RandomSearch, Hyperband, Hypermodel, Hyperparameter ]

# Hyperband
tuner = kt.Hyperband(
    hypermodel= keras_model, # HyperModel
    objective= 'val_accuracy', # 최적화할 하이퍼모델
    max_epochs=10, # 각 모델별 학습 회수
    factor = 3, # 한 번에 훈련할 모델 수 결정 변수
    directory = 'my_dir' # 저장폴더
    project_name = 'keras_tuner' # 사용된 파라미터 저장
)

# RandomSearch
tuner = RandomSearch(
    build_model, # HyperModel
    objective='val_accuracy', #  최적화할 하이퍼모델
    max_trials=5,
    executions_per_trial=3, # 각 모델별 학습 회수
    directory='my_dir', # 사용된 parameter 저장할 폴더
    project_name='helloworld') # 사용된 parameter 저장할 폴더


# 모든 교육단계가 끝날 때마다 학습 출력 지우도록 콜백 정의

import IPython
class ClearTrainingOutput(tf.keras.callbacks.Callback):
         def on_train_end(*args, **kwargs):
              IPython.display.clear_output(wait = True)

# parameter search
tuner.search( X_train, y_train, epochs= 10, validation_data=(X_test, y_test),
                 callbacks=[ClearTrainingOutput()]) == fit

# tunning parameter 
best_hps = tuner.get_best_hyperparameters(num_trials=1/ default) [0]


# parameter 확인
best_hps.get('name') => name= 'units', 'learning_rate' ....


# best_parameter 모델에 적용
model = tuner.hypermodel.build(best_hps)

# 모델 fit
model.fit(X_train, y_train, epochs=10, validation_data=(X_test, y_test))

Wandb 실험기록

# 아래의 커맨드를 실행합니다

wandb.login = wandb에 로그인

!pip install wandb

import wandb
from wandb.keras import WandbCallback


wandb login # quickstart key
# !git clone http://github.com/wandb/tutorial
# !cd tutorial; pip install --upgrade -r requirements.txt;

wandb.init(project=my-test-project, # == > 자신이 만든 프로젝트 이름
              group= ,
              config ={
                    'layer_1': 512,
                    'activation_1': 'relu',
                     .... 'optimizer': 'adam'
                     'loss': 'sparse_  .. ',
                     'metrics': 'acc',
                     'epochs': 10,
                     'batch_size': 32) 

config = wandb.config
# config.learning_rate = 0.01
# wandb.config.epochs = 50
# wandb.config.batch_size = 10

def model_builder():
  model= Sequential(
      [
       Flatten(input_shape=(32,32,3)), # train data.shape ==> 1차원형태로 변경
       Dense(128, activation='relu'),
       Dense(64, activation='relu'),
       Dense(100, activation='softmax') # test data == class가 100개 / np.unique(y_test)
      ]
  )

  # 모델을 컴파일 합니다
  model.compile(optimizer='adam', loss='mse', metrics=['mse', 'mae'])
  return model


# 모델을 학습합니다
model.fit(X, y, validation_split=0.3,
            epochs=config.epochs, # init에서 가져오지 않을 경우에는 wandb.config.epochs
            batch_size=config.batch_size,
            callbacks=[WandbCallback()] )

# 성능이 마음에 안든다면 추가로 학습을 더 시키는 방법
wnadb.init(config 파라미터 수치 수정)
wandb.config.epochs = 20
wandb.config.batch_size = 512

# keras.tuner( fit() X -> search() ) = CV

컴퓨터 비전 응용 프로그램에 HyperXception  HyperResNet이라는 두 가지 미리 정의된

HyperModel 클래스를 사용할 수도 있습니다. ( Transfer learning 같은것 )

https://keras.io/api/keras_tuner/hypermodels/

 

Keras documentation: KerasTuner HyperModels

KerasTuner HyperModels The HyperModel base class makes the search space better encapsulated for sharing and reuse. A HyperModel subclass only needs to implement a build(self, hp) method, which creates a keras.Model using the hp argument to define the hyper

keras.io

728x90

댓글