Reproducible Result?
- 코랩에서 tensorflow를 활용한 CNN 모델 학습을 진행하다가, 동일한 레이어 및 설정을 해도 결과마다 loss 및 accuracy가 다르게 나오는 경우를 보았다.
- 구글링을 해보니, random seed 및 gpu 연산에 따라서 결과가 다르게 나오는 것이 원인이었다.
- 레이어나 설정에 따라 loss 및 accuracy가 어떻게 변화되는지 확인하고 싶었고, 이에 따라 재현가능한 결과가 나오도록 설정하고 싶었다.
- 이에 따라 몇가지 설정을 적용해서, 동일한 레이어 및 설정에서 동일한 결과가 도출되는 것을 확인하였다.
필요한 설정
- tensorflow의 utils에서 set_random_seed 메서드를 호출하여 시드값을 설정한다.
- tensorflow의 config에서 enable_op_determinism 메서드를 호출한다.
- 노트북 세션을 끊지 않고 계속 테스트를 진행하고자 한다면, tensorflow의 backend에서 clear_session 메서드를 호출한다.
노트북 코드
import tensorflow as tf
import numpy as np
from keras.datasets import cifar10
from keras.utils import to_categorical
from sklearn.model_selection import train_test_split
from keras import models, layers
from keras.callbacks import EarlyStopping, ModelCheckpoint
from sklearn.metrics import confusion_matrix, classification_report
(X_train, y_train), (X_test, y_test) = cifar10.load_data()
print("Train Shape", X_train.shape, y_train.shape)
print("Test Shape", X_test.shape, y_test.shape)
print("Train Data")
print(np.unique(y_train, return_counts=True))
print("Test Data")
print(np.unique(y_test, return_counts=True))
X_train = X_train.astype(float) / 255
X_test = X_test.astype(float) / 255
y_train = to_categorical(y_train)
y_test = to_categorical(y_test)
X_train, X_valid, y_train, y_valid = train_test_split(X_train, y_train, test_size=0.2, random_state=2045)
print("Train Shape:", X_train.shape, y_train.shape)
print("Valid Shape:", X_valid.shape, y_valid.shape)
tf.keras.backend.clear_session()
tf.config.experimental.enable_op_determinism()
tf.keras.utils.set_random_seed(2045)
CIFAR = models.Sequential()
CIFAR.add(layers.Conv2D(64, 2, input_shape=(32, 32, 3,)))
CIFAR.add(layers.MaxPool2D(3))
CIFAR.add(layers.Conv2D(32, 2))
CIFAR.add(layers.MaxPool2D(3))
CIFAR.add(layers.Flatten())
CIFAR.add(layers.Dense(1024, activation='relu'))
CIFAR.add(layers.Dropout(0.6))
CIFAR.add(layers.Dense(512, activation='relu'))
CIFAR.add(layers.Dropout(0.4))
CIFAR.add(layers.Dense(128, activation='relu'))
CIFAR.add(layers.Dense(10, activation='softmax'))
CIFAR.summary()
CIFAR.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy'])
%%time
batch_size = 128
es = EarlyStopping(monitor='accuracy', mode='max', patience=50, verbose=1)
mc = ModelCheckpoint('best_CIFAR.h5', monitor='accuracy', mode='max', save_best_only=True, verbose=1)
Hist_CIFAR = CIFAR.fit(X_train, y_train, epochs=10, batch_size=batch_size,\
callbacks=[es, mc], validation_data=(X_valid, y_valid),\
workers=1)
best_CIFAR = models.load_model('best_CIFAR.h5')
loss, accuracy = best_CIFAR.evaluate(X_test, y_test, verbose=0)
print('Loss = {:.5f}'.format(loss))
print('Accuracy = {:.5f}'.format(accuracy))
y_real = np.argmax(y_test, axis=1)
preditions = best_CIFAR.predict(X_test)
y_pred = np.argmax(preditions, axis=1)
print(confusion_matrix(y_real, y_pred))
print(classification_report(y_real, y_pred))
테스트 결과
- 여러번 시도해도 동일한 결과를 도출한다
- 다만 구동하는 하드웨어가 다른 경우에 하드웨어에 따라 다른 결과를 나타낸다.
- 로컬 실행 결과와 코랩 실행 결과가 다르게 나왔다.