[모두의 딥러닝] 16. 과적합(overfitting), 테스트셋 구분, 모델 저장과 재사용 - 초음파 광물 예측 데이터

초음파 광물 예측 데이터

- 수중 음파 탐지기로 쏜 결과를 보고 광석인지 일반 암석인지 구분

from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense

import pandas as pd

df = pd.read_csv('./data/sonar3.csv', header=None)

# 음파 관련 속성을 X로, 광물의 종류를 y로 저장
X = df.iloc[:,0:60]
y = df.iloc[:,60]

# 모델 설정
model = Sequential()
model.add(Dense(24,  input_dim=60, activation='relu'))
model.add(Dense(10, activation='relu'))
model.add(Dense(1, activation='sigmoid'))

# 모델 컴파일
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])

# 모델 실행
history=model.fit(X, y, epochs=200, batch_size=10)

200번 반복된 결과를 보면 정확도가 100%

※ 과적합 발생!

 

 

 

과적합(overfitting)

- 훈련 데이터에 지나치게 맞추어져서 새로운 데이터에 대한 일반화 성능이 저하되는 현상

- 모델이 훈련 데이터에 과도하게 적합되면 잡음이나 이상치까지 학습하여 일반적인 패턴을 잘 파악하지 못하게 됨

- 층이 너무 많거나 변수가 복잡하거나 테스트셋과 학습셋이 중복될 때 발생

 

  • 과적합 방지법

: 학습을 하는 데이터셋과 테스트할 데이터셋을 구분한 후 학습과 동시에 테스트를 병행하며 진행

 

 

 

학습셋과 테스트셋 구분

- 예를 들어, 총 100개의 데이터셋이 있다면 70개의 샘플로 학습을 진행한 후 나머지 30개의 샘플로 테스트

- 학습이 계속되면 학습셋에서의 에러는 계속해서 작아지지만, 테스트셋에서는 과적합 발생

 

 

1. 환경 및 데이터 준비

from tensorflow.keras.models import Sequential, load_model
from tensorflow.keras.layers import Dense
from sklearn.model_selection import train_test_split

import pandas as pd

df = pd.read_csv('./data/sonar3.csv', header=None)

# 음파 관련 속성을 X로, 광물의 종류를 y로 저장합니다.
X = df.iloc[:,0:60]
y = df.iloc[:,60]

 

 

2. 학습셋과 테스트셋 구분

  • train_test_split()

: 저장된 X 데이터와 y 데이터에서 각각 정해진 비율만큼 학습셋과 테스트셋으로 분리

: scikit-learn에 존재

- test_size : 테스트셋의 비율을 나타내는 옵션

from sklearn.model_selection import train_test_split

# 학습 셋과 테스트 셋을 구분
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, shuffle=True)

※ scikit-learn 라이브러리가 설치되어 있지 않다면 '!pip install sklearn'로 먼저 설치

 

 

3. 모델 실행

# 모델 설정
model = Sequential()
model.add(Dense(24,  input_dim=60, activation='relu'))
model.add(Dense(10, activation='relu'))
model.add(Dense(1, activation='sigmoid'))

# 모델 컴파일
model.compile(loss='binary_crossentropy', optimizer='adam', metrics=['accuracy'])

# 모델 실행
history=model.fit(X_train, y_train, epochs=200, batch_size=10)

 

  • evaluate()

: loss와 accuracy를 계산해 출력

: Sequential()에 존재

# 모델을 테스트셋에 적용해 정확도를 구함
score=model.evaluate(X_test, y_test)
print('Test accuracy:', score[1])

학습셋의 정확도와 달리 테스트셋의 정확도는 79% 정도를 보여줌

 

 

모델 저장과 재사용

- 학습셋으로 학습을 진행한 후 나온 결과를 모델이라고 함

 

 

  • save()

: 모델의 구조와 가중치 저장

: Sequential()에 존재

- hdf5 포맷 : 주로 과학 기술 데이터 작업에서 사용하며, 크고 복잡한 데이터를 저장하는데 사용

# 모델 이름과 저장할 위치를 함께 지정
model.save('./data/model/my_model.hdf5')

 

  • load_model

: 저장된 모델 불러옴

: keras에 존재

from tensorflow.keras.models import Sequential, load_model

# 테스트를 위해 조금 전 사용한 모델을 메모리에서 삭제
del model 

# 모델을 새로 불러옴
model = load_model('./data/model/my_model.hdf5')

 

- 불러온 모델을 테스트셋에 적용

# 불러온 모델을 테스트셋에 적용해 정확도를 구함
score=model.evaluate(X_test, y_test)
print('Test accuracy:', score[1])

이전에 실행한 것과 같은 결과값이 나옴

 

 

 

'모두의 딥러닝 개정 3판'의 내용과 https://github.com/taehojo/deeplearning의 코드 참고