훈련 데이터를 잘 맞히는 모델이 새로운 데이터도 잘 맞히는 것은 아니다. 과적합(Overfitting)은 훈련 데이터의 특수한 패턴이나 잡음까지 학습해, 새로운 데이터에서 성능이 떨어지는 현상이다. 과적합을 줄이는 목적은 훈련 점수를 높이는 데서 나아가 일반화(Generalization), 즉 보지 못한 데이터에도 배운 관계를 적용하는 능력을 높이는 것이다.
앞 글에서는 은닉층을 추가한 MNIST 분류기를 살펴봤다. 이번에는 모델이 훈련 데이터에 지나치게 맞춰지는 것을 줄이는 방법을 정리한다.
훈련 손실이 계속 낮아지는데 검증 손실은 높아지는 흐름은 과적합의 대표적인 신호이다. 훈련 손실만 보면 이런 변화를 놓칠 수 있다.
검증 데이터(Validation data)는 모델 구조나 규제 강도 같은 설정을 선택할 때 사용하는 데이터이다. 가중치는 훈련 데이터로 학습하고, 설정 변경이 도움이 되는지는 검증 데이터로 확인한다. 테스트 데이터는 설정을 정한 뒤 최종 성능을 평가하는 데 남겨 둔다. 테스트 결과를 보며 반복해서 설정을 고르면 그 데이터에까지 맞춰질 수 있다.
다양한 훈련 데이터를 확보하면 일부 표본에만 나타나는 패턴과 여러 표본에 공통으로 나타나는 관계를 구분하는 데 도움이 된다. 기존 데이터를 변형해 훈련에 사용하는 방법을 데이터 증강(Data augmentation)이라고 한다.
이미지를 조금 이동하거나 회전시키는 것이 예이다. 다만 변형 후에도 정답이 유지되어야 한다. 손글씨를 너무 크게 회전해 다른 숫자처럼 보이게 만들면서 원래 정답을 붙이면 잘못된 학습 신호가 된다. 증강은 단순히 개수를 늘리는 일이 아니라, 같은 정답을 갖는 입력의 변화를 보여 주는 일이다.
은닉층이나 뉴런 수를 줄여 모델이 표현할 수 있는 관계를 제한하는 방법도 있다. 그러나 무조건 작게 만드는 것이 목표는 아니다. 지나치게 줄이면 훈련 데이터의 중요한 관계조차 학습하지 못하는 과소적합(Underfitting)이 생길 수 있다. 모델 크기는 검증 성능을 보며 조절한다.
가중치 규제(Weight regularization)는 예측 손실에 가중치 크기에 대한 벌점을 더하는 방법이다. 모델은 정답을 잘 맞히는 것과 가중치를 작게 유지하는 것을 함께 고려하며 학습한다. 층을 없애지 않아도 학습되는 가중치에 제약을 줄 수 있다.
예측 손실을 , 규제할 가중치를 , 규제 강도를 이라 하면 대표적인 두 방식은 다음과 같다.
L1 규제는 절댓값의 합을 더해 일부 가중치가 0이 되는 희소한 해를 유도한다. L2 규제는 제곱합을 더하므로 큰 가중치에 더 큰 벌점을 주며, 보통 가중치를 0에 가깝게 줄이는 경향이 있다. 어느 방식이 더 나은지는 데이터와 모델에 따라 달라진다.
규제 강도가 너무 크면 정답을 맞히는 데 필요한 가중치까지 억제할 수 있다. 또한 규제 항을 더한 훈련 손실은 규제 전 손실과 구성 자체가 다르다. 모델을 비교할 때는 같은 기준의 검증 손실이나 정확도를 확인해야 한다.
드롭아웃(Dropout)은 훈련 중 일부 중간값을 무작위로 0으로 만드는 방법이다. 매번 사용할 수 있는 값이 달라지므로, 모델이 특정 뉴런의 출력이나 조합에 지나치게 의존하는 것을 줄이는 데 도움이 된다.
PyTorch의 nn.Dropout(p=0.5)는 각 값을 0으로 만들 확률이 0.5라는 뜻이다. 매번 정확히 절반이 0이 되는 것은 아니다. 훈련 때는 남은 값에 를 곱해 출력의 기댓값을 유지하며, 이 식은 에서 적용된다.
평가할 때는 model.eval()로 드롭아웃을 끈다. 이때 nn.Dropout은 입력을 그대로 전달한다. torch.no_grad()는 기울기 기록을 끄는 설정이므로 드롭아웃의 평가 모드 전환을 대신하지 않는다.
이 방법들은 훈련 정확도를 낮추더라도 검증 성능을 높일 수 있다. 적용 여부와 강도는 훈련 점수의 상승보다, 새로운 데이터에 대한 성능이 실제로 좋아지는지를 기준으로 정한다.