딥러닝 기초 이론/딥러닝 파이썬 실습
Fashion_mnist.load_data로 케라스 튜너 사용해서 성능 높여보기
nosungmin
2023. 2. 10. 17:23
import tensorflow as tf
from tensorflow import keras
import IPython
!pip install -U keras-tuner
import kerastuner as kt
(img_train, label_train), (img_test, label_test) = keras.datasets.fashion_mnist.load_data()
ashion_mnist.load_data를 다운받습니다.
# Normalize pixel values between 0 and 1
img_train = img_train.astype('float32') / 255.0
img_test = img_test.astype('float32') / 255.0
정규화를 시켜줍니다.
def model_builder(hp):
model = keras.Sequential()
model.add(keras.layers.Flatten(input_shape=(28, 28)))
# Tune the number of units in the first Dense layer
# Choose an optimal value between 32-512
hp_units = hp.Int('units', min_value = 32, max_value = 512, step = 32)
model.add(keras.layers.Dense(units = hp_units, activation = 'relu'))
model.add(keras.layers.Dense(10))
# Tune the learning rate for the optimizer
# Choose an optimal value from 0.01, 0.001, or 0.0001
hp_learning_rate = hp.Choice('learning_rate', values = [1e-2, 1e-3, 1e-4])
model.compile(optimizer = keras.optimizers.Adam(learning_rate = hp_learning_rate),
loss = keras.losses.SparseCategoricalCrossentropy(from_logits = True),
metrics = ['accuracy'])
return model
이 코드는 파이썬의 Keras 라이브러리를 사용하여, 딥러닝 모델을 구축하는 코드입니다.
- hp_units: hp.Int 함수를 사용하여, 모델의 첫 번째 완전 연결(dense) 층의 뉴런 개수를 튜닝할 수 있는 값을 정의합니다. min_value = 32, max_value = 512, step = 32 옵션을 사용하여, 뉴런 개수를 결정하는 값의 범위와 단위를 지정합니다.
- model: 모델을 구축하는 코드입니다. keras.layers.Dense 함수를 사용하여, 모델에 첫 번째 완전 연결 층과 두 번째 완전 연결 층을 추가합니다. 첫 번째 완전 연결 층의 뉴런 개수는 hp_units에서 결정한 값으로, 두 번째 완전 연결 층의 뉴런 개수는 10으로 지정합니다.
- hp_learning_rate: hp.Choice 함수를 사용하여, 최적화 알고리즘(optimizer)의 학습률(learning rate)을 튜닝할 수 있는 값을 정의합니다. values = [1e-2, 1e-3, 1e-4] 옵션을 사용하여, 학습률을 지정할 수 있습니다.
tuner = kt.Hyperband(model_builder,
objective='val_accuracy',
max_epochs= 10,
factor=3,
directory='my_dir',
project_name='theFirstKT')
이 코드는 Keras Tuner의 Hyperband 알고리즘을 사용하여 모델 튜닝을 수행하기 위한 코드입니다.
Hyperband 클래스의 생성자의 인수들에 대한 설명은 다음과 같습니다.
- model_builder : 모델을 빌드하는 함수이다.
- objective : 튜닝 과정에서 최적화하려는 목표로 사용할 지표이다. 'val_accuracy'로 설정되어 있으므로, 검증 데이터에서의 정확도가 목표가 된다.
- max_epochs : 튜닝 과정에서 각 모델이 훈련될 최대 에포크 수이다. 이 예제에서는 10이라는 값으로 설정되어 있다.
- factor : 튜닝 과정에서 모델의 개수를 얼마나 줄일지 정의하는 팩터이다. 3으로 설정되어 있다.
- directory : 튜닝 과정의 결과를 저장할 디렉토리의 경로이다. 'my_dir'으로 설정되어 있다.
- project_name : 튜닝 과정의 결과를 구분할 수 있는 프로젝트의 이름이다. 'theFirstKT'로 이름을 설정한다.
class ClearTrainingOutput(tf.keras.callbacks.Callback):
def on_train_end(*args, **kwargs):
IPython.display.clear_output(wait = True)
이 코드는 TensorFlow의 keras.callbacks.Callback 클래스를 상속하는 ClearTrainingOutput 클래스를 정의하고 있습니다.
on_train_end 메서드는 훈련이 끝났을 때 호출되는 함수입니다. IPython.display.clear_output(wait = True)는 텐서플로우의 훈련 출력을 지워주는 함수입니다. 이 코드는 Jupyter Notebook 환경에서 텐서플로우의 훈련 중간 결과를 지우는 것을 목적으로 합니다.
이 클래스를 훈련 과정에서 콜백으로 사용할 수 있습니다. 이를 통해 훈련 과정 중 화면이 계속 쌓이지 않고 깨끗하게 유지될 수 있습니다.
tuner.search(img_train, label_train, epochs = 10, validation_data = (img_test, label_test), callbacks = [ClearTrainingOutput()])
# Get the optimal hyperparameters
best_hps = tuner.get_best_hyperparameters(num_trials = 1)[0]
이 코드는 케라스 튜너(tuner)를 사용하여 훈련을 진행하고 최적의 하이퍼파라미터를 결정하는 과정을 보여줍니다.
tuner.search() 메서드는 학습을 진행하기 위해 사용되는 데이터(img_train, label_train)와 검증 데이터(img_test, label_test), 학습 에포크 수(epochs = 10), 그리고 콜백(callbacks)을 인자로 전달합니다. 콜백으로 전달된 ClearTrainingOutput()은 훈련이 끝날 때 표시되는 출력을 정리하는 역할을 합니다.
그 다음, tuner.get_best_hyperparameters(num_trials = 1) 메서드를 호출하여 최적의 하이퍼파라미터를 결정합니다. num_trials 인자는 검색할 하이퍼파라미터 개수를 나타내며, 여기서는 1개만 검색하도록 지정되어 있습니다. 이 메서드의 결과로 반환된 하이퍼파라미터를 best_hps 변수에 할당하여 관리할 수 있습니다.
# Build the model with the optimal hyperparameters and train it on the data
model = tuner.hypermodel.build(best_hps)
history = model.fit(img_train, label_train, epochs = 10, validation_data = (img_test, label_test))
이 코드는 튜너(tuner)에서 검색한 최적의 하이퍼파라미터(best_hps)를 사용하여 케라스 모델(model)을 생성하는 것입니다. tuner.Hypermodel은 Hypermodel 클래스의 객체이고, build 메소드를 사용하여 best_hps를 입력으로 받아서 모델을 생성합니다. 이렇게 생성된 모델은 이후 훈련을 통해 최적의 성능을 갖도록 튜닝된 모델이 됩니다.
import matplotlib.pyplot as plt
def plot_graphs(history, metric):
plt.plot(history.history[metric])
plt.plot(history.history['val_'+metric], '')
plt.xlabel("Epochs")
plt.ylabel(metric)
plt.legend([metric, 'val_'+metric])
plt.show()
plot_graphs(history, 'accuracy')
plot_graphs(history, 'loss')
학습 결과가 그렇게 좋지는 않지만....그래도 이정도면 양호하다고 생각합니다.