[모두의 딥러닝] 베스트 모델 만들기
위 글은 [모두의 딥러닝 (개정 2판)] 을 바탕으로 학습하여 작성한 글입니다.
와인의 종류 예측
해당 예시는 레드와인과 화이트와인을 구분하는 실험입니다.
데이터 확인 코드
# 데이터 입력
df_pre = pd.read_csv('../dataset/wine.csv', header=None)
df = df_pre.sample(frac=1)
sample( ) 함수는 원본 데이터에서 정해진 비율만큼 랜덤으로 뽑아오는 함수입니다.
frac = 1 이면 원본데이터의 100%, frac = 0.5이면 50%만 추출합니다.
그 중 처음 5줄을 출력하는 코드를 작성합니다.
print(df.head(5))
정보를 토대로 X 값과 Y 값을 지정합니다.
dataset = df.values
X = dataset[:,0:12]
Y = dataset[:,12]
4개의 은닉층을 만들어 30, 12, 8, 1개의 노드를 지정합니다.
이항분류 문제이므로 오차 함수 binary_crossentropy 사용합니다.
최적화 함수 adam( ) 사용합니다.
전체 샘플 200번 반복합니다.
# 모델 설정
model = Sequential()
model.add(Dense(30, input_dim=12, activation='relu'))
model.add(Dense(12, activation='relu'))
model.add(Dense(8, activation='relu'))
model.add(Dense(1, activation='sigmoid'))
#모델 컴파일
model.compile(loss='binary_crossentropy',
optimizer='adam',
metrics=['accuracy'])
모델 업데이트
모델 저장과 재사용은 save( )함수와 load_model( ) 함수를 통해 사용합니다.
epoch 마다 모델의 정확도를 함께 기록하면서 저장하는 방법입니다.
파일 확장자 hdf5로 저장합니다.
예를 들어, 100번째 에포크를 실행하고 난 결과 오차가 0.0612라면 100-0.0612.hdf5가 저장됩니다.
import os
# 모델 저장 폴더 설정
MODEL_DIR = './model/'
if not os.path.exists(MODEL_DIR):
os.mkdir(MODEL_DIR)
# 모델 저장 조건 설정
modelpath="./model/{epoch:02d}-{val_loss:.4f}.hdf5"
모델 저장을 위해 케라스의 콜백 함수인 ModelCheckpoint( ) 함수를 호출합니다.
checkpointer 변수를 만들어 모니터할 값을 지정합니다.
테스트 오차는 val_loss, 학습 정확도는 acc, 테스트셋 정확도는 val_acc, 학습셋 오차는 loss로 각각 기록합니다.
모델이 저장될 곳을 앞서 만든 modelpath로 지정합니다.
verbose의 값을 1로 하면 함수의 진행사항이 출력, 0이면 출력되지 않습니다.
save_best_only=True 를 지정하여서 함수 모델이 저장한 모델보다 나아졌을 때만 저장합니다.
from keras.callbacks import ModelCheckpoint
# 모델 저장 조건 설정
checkpointer = ModelCheckpoint(filepath=modelpath, monitor='val_loss', verbose=1, save_best_only=True)
# 모델 실행 및 저장
model.fit(X, Y, validation_split=0.2, epochs=200, batch_size=200, verbose=0, callbacks=[checkpointer])
실행 결과
Epoch 00190: val_loss improved from 0.05280 to 0.05262, saving model to ./model/190-0.0526.hdf5
Epoch 00191: val_loss improved from 0.05262 to 0.05254, saving model to ./model/191-0.0525.hdf5
# 이전 모델보다 성능이 좋지못함.
Epoch 00192: val_loss did not improve from 0.05254
Epoch 00193: val_loss improved from 0.05254 to 0.05242, saving model to ./model/193-0.0524.hdf5
그래프로 확인
모델이 학습되는 과정을 histroy 변수에 저장합니다.
epochs=3500 : 긴 학습의 예를 관찰하기 위해 epoch를 3500으로 설정합니다.
sample(frac=0.15) : 시간이 너무 오래걸리지 않도록 sample( ) 함수를 이용하여 전체 샘플 중 15% 만 사용합니다.
batch_size=500 : 배치 크기는 500으로 하여 딥러닝을 가동할 때 더많이 입력되게 사용
validation_split=0.33 : 불러온 샘플 중 33%는 분리하여 테스트셋으로 사용합니다.
df = df_pre.sample(frac=0.15)
# 모델 실행 및 저장
history = model.fit(X, Y, validation_split=0.33, epochs=3500, batch_size=500)
그래프를 그리기 위한 라이브러리가 필요합니다.
y_vloss에는 테스트셋(33%)으로 실험한 결과의 오차 값을 저장합니다.
y_acc에 학습셋(67%)으로 측정한 정확도의 값을 저장합니다.
import matplotlib.pyplot as plt
# y_vloss에 테스트셋으로 실험 결과의 오차 값을 저장
y_vloss=history.history['val_loss']
# y_acc 에 학습 셋으로 측정한 정확도의 값을 저장
y_acc=history.history['accuracy']
x 좌표의 단위를 지정하고 정확도를 파란색 오차를 빨간색으로 표시합니다.
# x값을 지정하고 정확도를 파란색으로, 오차를 빨간색으로 표시
x_len = numpy.arange(len(y_acc))
plt.plot(x_len, y_vloss, "o", c="red", markersize=3)
plt.plot(x_len, y_acc, "o", c="blue", markersize=3)
결과
학습의 자동 중단
학습이 진행될수록 학습셋의 정확도는 올라가지만 과적합 때문에 테스트셋의 실험 결과는 점점 나빠집니다.
케라스에는 학습이 진행되어도 테스트셋 오차가 줄지 않으면 학습을 멈추게하는 함수가 필요합니다.
from keras.callbacks import EarlyStopping
EarlyStopping( ) 함수에 모니터할 값과 테스트 오차가 좋아지지 않아도 몇 번까지 기다릴지 정합니다.
# 자동 중단 설정
early_stopping_callback = EarlyStopping(monitor='val_loss', patience=100)
# 모델 실행
model.fit(X, Y, validation_split=0.2, epochs=2000, batch_size=500, callbacks=[early_stopping_callback])
에포크를 2,000으로 설정했지만 도중에 계산이 멈추는 것을 확인할 수 있습니다.
Epoch 1530/2000
780/780 [==============================] - 0s 6us/step - loss: 0.0290 - accuracy: 0.9872 - val_loss: 0.0571 - val_accuracy: 0.9846
Epoch 1531/2000
780/780 [==============================] - 0s 8us/step - loss: 0.0303 - accuracy: 0.9872 - val_loss: 0.0586 - val_accuracy: 0.9795
Epoch 1532/2000
780/780 [==============================] - 0s 6us/step - loss: 0.0308 - accuracy: 0.9859 - val_loss: 0.0627 - val_accuracy: 0.9795
Epoch 1533/2000
780/780 [==============================] - 0s 8us/step - loss: 0.0294 - accuracy: 0.9872 - val_loss: 0.0599 - val_accuracy: 0.9795
975/975 [==============================] - 0s 16us/step