본문 바로가기
네이버클라우드/AI

AI 3일차 (2023-05-10) 인공지능 기초 - Validation split, 과적합(Overfitting)과 Early Stopping

by prometedor 2023. 5. 10.

Validation split

ㄴ validation은 모델이 학습하는 동안 학습에 사용되지 않은 데이터셋으로 모델의 일반화 성능을 평가하기 위해 사용

ㄴ 일반화 성능을 평가하기 위해 학습 데이터와 별도로 유효성 검사(validation) 데이터를 사용하여 모델의 성능을 평가

ㄴ 일반적으로 학습 데이터(train), 유효성 검사 데이터(validation), 테스트 데이터(test)를 6:2:2 로 분할함

 

tf12_validation03.py

import numpy as np
from keras.models import Sequential
from keras.layers import Dense
from sklearn.model_selection import train_test_split
from sklearn.metrics import r2_score
# from sklearn.datasets import load_boston  # 윤리적 문제로 제공 안 됨
from sklearn.datasets import fetch_california_housing
import time


# 1. 데이터
# datasets = load_boston()
datasets = fetch_california_housing()
x = datasets.data
y = datasets.target

print(datasets.feature_names)
# ['MedInc', 'HouseAge', 'AveRooms', 'AveBedrms', 'Population', 'AveOccup', 'Latitude', 'Longitude']

# print(datasets.DESCR)   # DESCR 세부적으로 보겠다
# 속성 정보:
# - 그룹의 중위수 소득
# - 그룹의 주택 연령 중위수
# - 가구당 평균 객실 수
# - 평균 가구당 침실 수
# - 모집단 그룹 모집단
# - 평균 가구원수
# - Latitude 그룹 위도
# - 경도 그룹 경도

print(x.shape)  # (20640, 8)
print(y.shape)  # (20640,)

x_train, x_test, y_train, y_test = train_test_split(
    x, y, train_size=0.6, test_size=0.2, random_state=100, shuffle=True
)

print(x_train.shape)    # (14447, 8)    # 8(열) - input_dim
print(y_train.shape)    # (14447,)


# 2. 모델구성
model = Sequential()
model.add(Dense(100, input_dim = 8))
model.add(Dense(100))
model.add(Dense(50))
model.add(Dense(20))
model.add(Dense(10))
model.add(Dense(1))     # 주택 가격


# 3. 컴파일, 훈련
model.compile(loss='mse', optimizer='adam')

start_time = time.time()
hist = model.fit(x_train, y_train, epochs=500, batch_size=200,      #batch_size 커야 훈련시간 단축됨
          validation_split=0.2)    # validation data => 0.2 (train 0.6 / test 0.2)
end_time = time.time() - start_time


# 4. 평가, 예측
loss = model.evaluate(x_test, y_test)
y_predict = model.predict(x_test)
r2 = r2_score(y_test, y_predict)
print('r2스코어 : ', r2)

print('걸린 시간 : ', end_time)

## 시각화
import matplotlib.pyplot as plt
plt.figure(figsize=(9,6))
plt.plot(hist.history['loss'], marker='.', c='orange', label='loss')
plt.plot(hist.history['val_loss'], marker='.', c='blue', label='val_loss')
plt.title('Loss & Val_loss')
plt.ylabel('loss')
plt.xlabel('epochs')
plt.legend()
plt.show()

hist = model.fit(x_train, y_train, epochs=500, batch_size=200,  validation_split=0.2)    

ㄴ validation data  = >  0.2 (train : 0.6 / test : 0.2) 

 

pyplot 을 이용한  validation_split 시각화 결과

 

 

과적합 (Overfitting)

https://upload.wikimedia.org/wikipedia/commons/thumb/1/19/Overfitting.svg/250px-Overfitting.svg.png

 

모델이 학습 데이터에 너무 과도하게 적합화되어, 새로운 데이터에 대한 예측 성능이 저하되는 현상
ㄴ 모델이 학습 데이터에만 맞추어져 새로운 데이터에 대해 일반화(generalization) 능력이 부족하게 되는 것

ㄴ 위 그림에서 초록색 선은 과적합된 모델을, 검은색 선은 일반 모델을 뜻함

 

Early Stopping

과적합을 방지하기 위한 방법 중 하나
ㄴ 학습 중 모델의 성능을 모니터링하다가 학습 데이터에 대한 성능은 계속해서 향상되지만 검증 데이터에 대한 성능은 향상되지 않거나 감소하는 지점에서 학습을 조기 종료하는 것
ㄴ 일반적으로, 학습 데이터와 검증 데이터를 나누어 학습하면서 적용됨

# 3. 컴파일, 훈련
model.compile(loss='mse', optimizer='adam')

## EarlyStopping
from keras.callbacks import EarlyStopping

earlyStopping = EarlyStopping(monitor='val_loss', patience=100, mode='min',  # mode='auto'가 기본 / patience=100 --> 100부터 줄여나가자.
                              verbose=1, restore_best_weights=True) # restore_best_weights --> default 는 False 이므로 True 로 꼭!!! 변경!!!  

start_time = time.time()
hist = model.fit(x_train, y_train, epochs=5000, batch_size=200,
          validation_split=0.2,  	# validation data => 0.2 (train 0.6 / test 0.2)
          callbacks=[earlyStopping],
          verbose=1)    
end_time = time.time() - start_time

** patience

ㄴ 훈련 과정에서 검증 손실이 감소하지 않을 때 얼마나 기다려 줄지를 설정하는 값

 

 

tf14_california_earlyStopping.py

import numpy as np
from keras.models import Sequential
from keras.layers import Dense
from sklearn.model_selection import train_test_split
from sklearn.metrics import r2_score
# from sklearn.datasets import load_boston  # 윤리적 문제로 제공 안 됨
from sklearn.datasets import fetch_california_housing
import time


# 1. 데이터
# datasets = load_boston()
datasets = fetch_california_housing()
x = datasets.data
y = datasets.target

print(datasets.feature_names)
# ['MedInc', 'HouseAge', 'AveRooms', 'AveBedrms', 'Population', 'AveOccup', 'Latitude', 'Longitude']

# print(datasets.DESCR)   # DESCR 세부적으로 보겠다
# 속성 정보:
# - 그룹의 중위수 소득
# - 그룹의 주택 연령 중위수
# - 가구당 평균 객실 수
# - 평균 가구당 침실 수
# - 모집단 그룹 모집단
# - 평균 가구원수
# - Latitude 그룹 위도
# - 경도 그룹 경도

print(x.shape)  # (20640, 8)
print(y.shape)  # (20640,)

x_train, x_test, y_train, y_test = train_test_split(
    x, y, train_size=0.6, test_size=0.2, random_state=100, shuffle=True
)

print(x_train.shape)    # (14447, 8)    # 8(열) - input_dim
print(y_train.shape)    # (14447,)


# 2. 모델구성
model = Sequential()
model.add(Dense(100, input_dim = 8))
model.add(Dense(100))
model.add(Dense(50))
model.add(Dense(20))
model.add(Dense(10))
model.add(Dense(1))     # 주택 가격


# 3. 컴파일, 훈련
model.compile(loss='mse', optimizer='adam')

## EarlyStopping
from keras.callbacks import EarlyStopping

earlyStopping = EarlyStopping(monitor='val_loss', patience=100, mode='min',  # mode='auto'가 기본, patience=100 --> 100부터 줄여나가자
                              verbose=1, restore_best_weights=True) # restore_best_weights --> default 는 False 이므로 True 로 꼭!!! 변경!!!  

start_time = time.time()
hist = model.fit(x_train, y_train, epochs=5000, batch_size=200,      #batch_size 커야 훈련시간 단축됨
          validation_split=0.2,  # validation data => 0.2 (train 0.6 / test 0.2)
          callbacks=[earlyStopping],
          verbose=1)    
end_time = time.time() - start_time


# 4. 평가, 예측
loss = model.evaluate(x_test, y_test)
y_predict = model.predict(x_test)
r2 = r2_score(y_test, y_predict)
print('loss : ', loss)
print('r2스코어 : ', r2)
print('걸린 시간 : ', end_time)


## 시각화
import matplotlib.pyplot as plt
plt.figure(figsize=(9,6))
plt.plot(hist.history['loss'], marker='.', c='orange', label='loss')
plt.plot(hist.history['val_loss'], marker='.', c='blue', label='val_loss')
plt.title('Loss & Val_loss')
plt.ylabel('loss')
plt.xlabel('epochs')
plt.legend()
plt.show()


#===============================================#
# patient : 100 / epochs : 5000
# Epoch 1304: early stopping
# loss :  0.5798053741455078
# r2스코어 :  0.5696849948313032
# 걸린 시간 :  127.47385048866272

# patient : 50 / epochs : 5000
# Epoch 455: early stopping
# loss :  0.6059713363647461
# r2스코어 :  0.5502652751797803
# 걸린 시간 :  48.0907506942749

 

pyplot 을 이용한 EarlyStopping 시각화 결과