머신러닝 & 딥러닝
[딥러닝] 9. 언더피팅 & 오버피팅
김초송
2023. 5. 10. 15:00
언더피팅 문제 해결
1. 배치 정규화
- 층이 깊어질수록 정규분포 모양이 틀어지는 것을 막는 방법
- 신경망에 들어오는 데이터에 대한 학습 가중치(W) 에 대해서 강제로 정규성을 유지함
- 활성화함수 전에 실행
import tensorflow as tf # 텐써 플로우 2.0
from tensorflow.keras.datasets.mnist import load_data # 텐써플로우에 내장되어있는 mnist 데이터를 가져온다.
from tensorflow.keras.models import Sequential # 모델을 구성하기 위한 모듈
from tensorflow.keras.layers import Dense, Flatten, BatchNormalization # 완전 연결계층을 구성하기 위한 모듈
from tensorflow.keras.utils import to_categorical # one encoding 하는 모듈
import numpy as np
tf.random.set_seed(777)
(x_train, y_train), (x_test, y_test) = load_data(path='mnist.npz') # mnist 데이터 로드
# 2. 정규화 진행
x_train = (x_train.reshape((60000, 28 * 28))) / 255
x_test = (x_test.reshape((10000, 28 * 28))) / 255
# 3. 정답 데이터를 준비한다.
# 하나의 숫자를 one hot encoding 한다. (예: 4 ---> 0 0 0 0 1 0 0 0 0 0 )
y_train = to_categorical(y_train) # 훈련 데이터의 라벨(정답)을 원핫 인코딩
y_test = to_categorical(y_test) # 테스트 데이터의 라벨(정답)을 원핫 인코딩
# 4. 모델을 구성합니다. 2층 신경망으로 구성
# (100, 784) ◎ ( 784, 100) = (100, 100) ◎ (100, 50 ) = (100, 50) ◎ (50, 10 ) = (100,10)
model = Sequential()
model.add(Flatten(input_shape=(784, ))) # 입력층(0층)
model.add(BatchNormalization())
model.add(Dense(100, activation='sigmoid' )) # 은닉층(1층)
model.add(BatchNormalization())
model.add(Dense(50, activation ='sigmoid')) # 은닉층 (2층)
model.add(Dense(10, activation='softmax')) # 출력층 (3층)
# 5. 모델을 설정합니다. ( 경사하강법, 오차함수를 정의해줍니다. )
model.compile(optimizer='SGD',
loss = 'categorical_crossentropy',
metrics=['acc']) # 학습과정에서 정확도를 보려고
#6. 모델을 훈련시킵니다.
history = model.fit(x_train, y_train,
epochs=30, # 30에폭
batch_size=100,
validation_data=(x_test, y_test))
# 7.모델을 평가합니다. (오차, 정확도가 출력됩니다.)
model.evaluate(x_test, y_test)
# 위의 코드들 밑에 바로 구현
train_acc_list = history.history['acc']
test_acc_list = history.history['val_acc']
print(train_acc_list)
print(test_acc_list)
# 시각화
import matplotlib.pyplot as plt
x = np.arange(len(train_acc_list))
plt.plot(x, train_acc_list, label='train acc')
plt.plot(x, test_acc_list, label='test acc', linestyle='--')
plt.legend(loc='lower right')
plt.xlabel('epochs')
plt.ylabel('accuracy')
plt.show()
2. 경사하강법 + 활성화 함수
- SGD
- 확률적 경사하강법
- 가중치 = 가중치 - 학습률 * 기울기
- 배치단위로 복원 추출한 데이터를 학습
- Adam
- 관성을 이용해 local minimum 을 빠져나오는 Momentum
+ 학습률을 자동조절하는 Adagrade 를 결합 - 모멘텀
- 속도 = 마찰계수 * 속도 - 학습률 * 기울기
- 가중치 = 가중치 + 속도
- RMSprop
- Adagrade + 학습률 조절할 때 이전 경험을 바탕으로 조절
- Adagrade
- h = h + 기울기 ◎ 기울기
- 가중치 = 가중치 - 러닝레이트 * 기울기 * ( 1 / √h )
오버피팅 문제 해결
1. Drop out
- 뉴런을 임의로 삭제하면서 학습 시키는 방법
- 너무 많이 삭제하게 되면 훈련 데이터, 테스트 데이터 둘 다 정확도 떨어짐
- 배치 정규화 다음에 실행
import tensorflow as tf # 텐써 플로우 2.0
from tensorflow.keras.datasets.mnist import load_data # 텐써플로우에 내장되어있는 mnist 데이터를 가져온다.
from tensorflow.keras.models import Sequential # 모델을 구성하기 위한 모듈
from tensorflow.keras.layers import Dense, Flatten, BatchNormalization, Dropout # 완전 연결계층을 구성하기 위한 모듈
from tensorflow.keras.utils import to_categorical # one encoding 하는 모듈
import numpy as np
tf.random.set_seed(777)
(x_train, y_train), (x_test, y_test) = load_data(path='mnist.npz') # mnist 데이터 로드
# 2. 정규화 진행
x_train = (x_train.reshape((60000, 28 * 28))) / 255
x_test = (x_test.reshape((10000, 28 * 28))) / 255
# 3. 정답 데이터를 준비한다.
# 하나의 숫자를 one hot encoding 한다. (예: 4 ---> 0 0 0 0 1 0 0 0 0 0 )
y_train = to_categorical(y_train) # 훈련 데이터의 라벨(정답)을 원핫 인코딩
y_test = to_categorical(y_test) # 테스트 데이터의 라벨(정답)을 원핫 인코딩
# 4. 모델을 구성합니다. 2층 신경망으로 구성
# (100, 784) ◎ ( 784, 100) = (100, 100) ◎ (100, 50 ) = (100, 50) ◎ (50, 10 ) = (100,10)
model = Sequential()
model.add(Flatten(input_shape=(784, ))) # 입력층(0층)
model.add(BatchNormalization())
model.add(Dropout(0.2))
model.add(Dense(100, activation='sigmoid' )) # 은닉층(1층)
model.add(BatchNormalization())
model.add(Dropout(0.2))
model.add(Dense(50, activation ='sigmoid')) # 은닉층 (2층)
model.add(Dense(10, activation='softmax')) # 출력층 (3층)
# 5. 모델을 설정합니다. ( 경사하강법, 오차함수를 정의해줍니다. )
model.compile(optimizer='RMSprop',
loss = 'categorical_crossentropy',
metrics=['acc']) # 학습과정에서 정확도를 보려고
#6. 모델을 훈련시킵니다.
history = model.fit(x_train, y_train,
epochs=30, # 30에폭
batch_size=100,
validation_data=(x_test, y_test))
# 7.모델을 평가합니다. (오차, 정확도가 출력됩니다.)
model.evaluate(x_test, y_test)
# 위의 코드들 밑에 바로 구현
train_acc_list = history.history['acc']
test_acc_list = history.history['val_acc']
print(train_acc_list)
print(test_acc_list)
# 시각화
import matplotlib.pyplot as plt
x = np.arange(len(train_acc_list))
plt.plot(x, train_acc_list, label='train acc')
plt.plot(x, test_acc_list, label='test acc', linestyle='--')
plt.legend(loc='lower right')
plt.xlabel('epochs')
plt.ylabel('accuracy')
plt.show()
2. Early Stopping
# 오버피팅 전에 epoch 중지
from tensorflow.keras.callbacks import EarlyStopping
callbacks = [EarlyStopping(monitor='val_acc', patience=4, verbose=1)]
model.fit(x_train, y_train, batch_size=100, validation_data=(x_test, y_test),
epochs=200, callbacks=callbacks)
- monitor: 관찰하고자 하는 항목, val_loss / val_acc
- val_acc: 테스트데이터 정확도
- patience: 학습을 하는 도중 개선의 여지가 없어도 pass 하는 횟수
- verbose: 훈련 되는 과정에서 조기종료한 이유 출력, 0 / 1 / 2, 숫자 클수록 자세히
3. 가중치 감소
- 큰 가중치에 대해서 그에 상응하는 패널티 부여
- dropout 다음에 실행
# L2 정규화 코드
model.add(Dense( 50, kernel_regular='l2', activation='relu'))
본 내용은 아이티윌 '빅데이터&머신러닝 전문가 양성 과정' 을 수강하며 작성한 내용입니다.