AI/모두의 딥러닝

[Deep Learning : 딥러닝] 과적합 Overfitting

LiDARian 2021. 6. 25. 18:10
반응형

과적합(overfitting)이란,,,

학습이 이미 학습된 특정한 데이터에만 잘 예측하고, 다른 테스트용/실제 데이터에는 제대로 작동하지 않는 현상을 의미합니다.

 

초음파를 통해 광물과 돌을 구분하는 sonar예제를 통해서 과적합 문제를 살펴봅시다.


아래 코드를 실행하면 매우 오래걸리지만 결국 언젠간 분석해냅니다..

아래 데이터를 보면 20개의 샘플, 60개의 속성, 1개의 클래스로 구성되어고, 마지막 클래스는 자료형이 class이기에 0과 1로 표현해줘야합니다.

# 데이터 입력
from google.colab import files
uploaded = files.upload()
my_data = 'sonar.csv'

#본문에 맞는 텐서플로 버전을 선택합니다.
!pip install -q tensorflow-gpu==1.15.0
%tensorflow_version 1.x

import tensorflow as tf
import pandas as pd
import numpy

from keras.models import Sequential
from keras.layers.core import Dense
from sklearn.preprocessing import LabelEncoder

# seed 값 설정
numpy.random.seed(3)
tf.compat.v1.set_random_seed(3)

#데이터 적용
df = pd.read_csv(my_data, header=None)

# 데이터 개괄 보기
print(df.info())

# 데이터의 일부분 미리 보기
print(df.head())

데이터의 일부분은 아래와 같습니다..

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 208 entries, 0 to 207
Data columns (total 61 columns):
 #   Column  Non-Null Count  Dtype  
---  ------  --------------  -----  
 0   0       208 non-null    float64
 1   1       208 non-null    float64
 2   2       208 non-null    float64
 3   3       208 non-null    float64
 4   4       208 non-null    float64
 5   5       208 non-null    float64
 6   6       208 non-null    float64
 ...
 60  60      208 non-null    object 
dtypes: float64(60), object(1)
memory usage: 99.2+ KB
None
       0       1       2       3       4   ...      56      57      58      59  60
0  0.0200  0.0371  0.0428  0.0207  0.0954  ...  0.0180  0.0084  0.0090  0.0032   R
1  0.0453  0.0523  0.0843  0.0689  0.1183  ...  0.0140  0.0049  0.0052  0.0044   R
2  0.0262  0.0582  0.1099  0.1083  0.0974  ...  0.0316  0.0164  0.0095  0.0078   R
3  0.0100  0.0171  0.0623  0.0205  0.0205  ...  0.0050  0.0044  0.0040  0.0117   R
4  0.0762  0.0666  0.0481  0.0394  0.0590  ...  0.0072  0.0048  0.0107  0.0094   R

[5 rows x 61 columns]

 


아래는 모델을 만들고 실행하는 코드입니다.

dataset = df.values
X = dataset[:,0:60]
Y_obj = dataset[:,60]

# 문자열 One-Hot Incoding
e = LabelEncoder()
e.fit(Y_obj)
Y = e.transform(Y_obj)

# 모델 설정
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='mean_squared_error',
            optimizer='adam',
            metrics=['accuracy'])

# 모델 실행
model.fit(X, Y, epochs=200, batch_size=5)

# 결과 출력
print("\n Accuracy: %.4f" % (model.evaluate(X, Y)[1]))

이에 대한 출력은

.....
Epoch 197/200
208/208 [==============================] - 0s 319us/step - loss: 2.7021e-04 - accuracy: 1.0000
Epoch 198/200
208/208 [==============================] - 0s 314us/step - loss: 2.6859e-04 - accuracy: 1.0000
Epoch 199/200
208/208 [==============================] - 0s 326us/step - loss: 2.5099e-04 - accuracy: 1.0000
Epoch 200/200
208/208 [==============================] - 0s 343us/step - loss: 2.5456e-04 - accuracy: 1.0000
208/208 [==============================] - 0s 152us/step

 Accuracy: 1.0000

100퍼센트의 정확도... 이게 말이 됩니까?
과적합의 냄새가 나지 않습니까?

 

 

과적합은 왜 일어날까?

은닉층의 개수가 너무 많은 경우
변수가 복잡한 경우
테스트셋과 학습셋이 중복되는 경우
...
등 과적합이 일어나는 이유는 많습니다.

중요한 점은
식이 복잡해지고 학습량이 늘어날 수록 학습 데이터셋에 대한 예측은 강화되지만, 그 외의 데이터셋에 대해서는 예측률이 떨어진다는 것입니다..

 

 

과적합을 방지하는 방법

학습 데이터와 테스트 데이터를 구분하고, 학습과 동시에 테스트를 병행하며 학습을 진행하는 방법이 있습니다.
그리고 학습을 진행해도 테스트 결과가 더 이상 좋아지지 않는 지점에서 학습을 멈추는 것입니다.

다음 포스팅에서는 과적합을 방지하기 위해 trainset과 testset를 sklearn함수를 통해서 간단히 나누는 방법을 배울 것입니다.

반응형