Deep Learning from Scratch1 - Ch6 오버피팅 억제
1 minute read
오버피팅(overfitting)
- 신경망이 훈련 데이터에만 지나치게 적응되어 그 외의 데이터에는 제대로 대응하지 못하는 상태
- 기계학습의 목표는 ‘범용성’으로 아직 보지 못한 데이터가 주어져도 바르게 식별해내는 모델이 바람직하다.
- 매개변수가 많고 표현력이 높은 모델, 훈련 데이터가 적은 경우 주로 발생한다.
- 훈련 데이터와 시험 데이터에 대한 정확도가 큰 차이를 보인다.
- 훈련 때 사용하지 않은 데이터에는 제대로 대응하지 못하는 것으로 오버피팅이 발생한 그래프이다.
가중치 감소(weight decay)
- 오버피팅 억제용으로 많이 이용해온 방법
- 오버피팅이 가중치 매개변수의 값이 커서 발생하는 경우가 많기 때문에 큰 가중치에 대해서는 그에 상응하는 큰 페널티를 부과한다.
- 모든 가중치 각각의 손실함수에 가중치의 제곱 노름(L2 노름)을 더하면 가중치가 커지는 것을 억제할 수 있다.
- 가중치의 기울기를 구하는 계산에서는 오차역전파법에 따른 결과에 정규화 항을 미분한 λW를 더한다.
수식(L2노름)
λ=0.1로 가중치 감소 적용
- 훈련 데이터와 시험 데이터의 정확도에는 여전히 차이가 있지만, 가중치 감소를 이용했을 때 그 차이가 줄어든 것을 확인할 수 있다.
- 훈련 데이터에 대한 정확도도 1.0(100%)에 도달하지 못했다.
드롭아웃(Dropout)
- 뉴런을 임의로 삭제하면서 학습하는 방법
- 훈련 때 은닉층의 뉴련을 무작위로 골라 삭제한다.
- 훈련 때는 데이터를 흘릴 때마다 삭제할 뉴런을 무작위로 선택하고, 시험 때는 모든 뉴런에 신호를 전달한다.
- 단, 시험 때는 각 뉴런의 출력에 훈련 때 삭제 안 한 비율을 곱하여 출력한다.
구현
class Dropout:
def __init__(self, dropout_ratio=0.5):
self.dropout_ratio = dropout_ratio
self.mask = None
#훈련시에는 순전파때마다 self.mask에 삭제할 뉴런을 False로 표시한다.
def forward(self, x, train_flg=True):
if train_flg:
# self.mask에 x와 형상이 같은 배열을 무작위로 생성하고
# dropout_ration보다 큰 원소만 True로 설정한다.
self.mask = np.random.rand(*x.shape) > self.dropout_ratio
return x*self.mask
# 시험 때는 훈련 때 삭제 안 한 비율을 곱하여 출력한다.
else:
return x*(1.0-self.dropout_ratio)
# 역전파는 ReLU와 같은 동작을 한다.
# 순전파때 신호를 통과시킨 뉴런은 역전파때도 그대로 통과시키고,
# 그렇지 않은 뉴런은 역전파때 신호를 차단한다.
def backward(self, dout):
return dout*self.mask
드롭아웃 적용(dropout_ratio = 0.15)
- 훈련 데이터와 시험 데이터의 정확도 차이가 줄었다.
- 훈련 데이터에 대한 정확도가 1.0(100%)에 도달하지 않았다.
- 드롭아웃을 사용하면 포현력을 높이면서도 오버피팅을 억제할 수 있다.
앙상블 학습(ensemble learning)
- 개별적으로 학습시킨 여러 모델의 출력을 평균내어 추론하는 방법
- 드롭아웃이 학습 때 뉴런을 무작위로 삭제하는 행위는 매번 다른 모델을 학습시키는 것으로 해석할 수 있고, 추론 때(실제 데이터) 뉴런의 출력에 삭제한 비율(1-dropout_ratio)을 곱합으로써 여러 모델의 평균을 내는 것과 같은 효과를 얻을 수 있다.
- 드롭아웃(dropout)은 앙상블 학습과 같은 효과를 하나의 네트워크로 구현했다고 볼 수 있다.
[참고자료]
Leave a comment