과적합과 복잡도
인간의 사유 과정과 딥러닝 학습 과정의 유사성 1.
연구할 때, 특히 방법론을 연구할 때 코딩을 주로 하게 되는데, 코딩을 할 때마다 인간이 기계가 작동하는 방식과 매우 닮아있다고 느낀다. 사실, 인간의 생각으로 기계를 만들었기에 닮아있는 것이지만 반대도 말이 되긴 하니까..
특히, 머신러닝의 학습과정은 정말 인간의 학습과정과 동일하다고 해도 무방할 정도이다. 기초가 안된 상태로 무턱대고 딥러닝을 해온 사람인지라 다시 딥러닝 공부를 하다가 맞이한 overfitting 내용도 신선했다.
Overfitting 현상은 학습데이터는 설계한 대로 loss가 계속해서 감소하면서 퍼포먼스가 증가하지만 검증용 실제 데이터 (Validation set)에서는 어느 순간부터 loss가 감소하다가 증가하는 방식으로 변화하는 구간이 생기는 것을 뜻한다. 가장 큰 이유로는 모델이 담아낼 수 있는 Capacity와 데이터의 복잡성 간의 관련성에 있다. 만약 데이터가 그리 복잡하지 않은데 너무 복잡한 모델 (즉, 모델의 파라미터양이 많은) 경우에 모델이 데이터에 담긴 노이즈까지 모두 암기해 버려서 다른 데이터에서는 고장이 난다. 반대로, 데이터는 매우 복잡한데 너무 단순한 모델을 사용하게 되면 그냥 퍼포먼스가 잘 안 나오는 모델이 된다. 추가로, 만약 검증용 실제 데이터가 학습 데이터와의 상관관계가 낮은 경우에는, 아무리 모델 학습을 훌륭하게 해도 다른 데이터로 인식하여 학습 데이터에서의 퍼포먼스보다 훨씬 안 좋은 상황을 보인다. 다만, 이런 경우에는 학습을 시작한 순간부터 검증용 데이터에서는 꾸준하게 안 좋은 퍼포먼스를 냈을 것이다.
이러한 Overfitting 현상을 보면서, 인간의 인식에서 겪는 일반화 과정이 필연적이며, overfitting을 막아주는 방식으로 작용하고 있다고 생각하게 되었다. 연역적 과정을 통해 도출된 진리를 제외하고는 귀납적 사고, 즉 경험에서 나온 교훈들을 통해 미래를 바라볼 수밖에 없는 게 현실인데, 이러한 경험은 딥러닝 모델이 마주하는 학습 데이터에 비유할 수 있다. 만약 검증용 데이터를 마주할 때, (즉, 새로운 비슷한 경험을 미래에 마주한다고 가정할 때), 우리는 지금까지 경험한 비슷한 경험들을 모아서 유추해야 한다. 이때 비슷한 경험들을 모은 순간 그 경험이 복잡하다면 일반화를 덜 해야 하는 것이고, 복잡하지 않은 상황이라면 과감하게 일반화를 하는 것이 실제 상황에서 더 높은 퍼포먼스 (즉, 귀납적으로 더 올바른 선택)이 될 가능성이 높다.
그 일반화 과정은 딥러닝에서 작동하는 반복 수와 밀접한 관련이 있는데, 만약 Validation set에서 accuracy가 감소하는 구간에 접어든다면, overfitting을 방지하기 위하여 학습을 종료하는 극단적인 방법을 쓰기도 한다. 이는 너무 과하게 생각에 빠져서 이런저런 고민을 깊게 하다가 오히려 이상한 선택을 하게 되는 경험을 떠오르게 한다. 단순한 문제를 복잡하게 생각해서 틀리는 것이 제 학창 시절 전문분야였어서 매우 공감되는 영역이기도 하다. 술자리에서 나 때는 말이야 로 시작하는 여러 이야기들에 일단 거리감을 두고 귀가 자연스럽게 닫히겠지만, 1) 충분한 경험으로 쌓인 데이터에서도 일관된 결과를 보고 있었으며 (epoch 수가 충분하며), 2) 해당 데이터로 도출하고자 하는 task가 그리 복잡한 일이 아닌 경우이며 (Data complexity가 낮은 경우), 3) 학습 데이터와 현재 주장하는 상황에 해당하는 검증 데이터 간의 상관관계가 충분히 높은 경우 (Data domain이 비슷하게 형성)에는, 과감하게 일반화를 해버리고 주장하는 것들이 최선의 답이 될 수도 있다. 이를 하나씩 다시 쉽게 풀어 설명하면 다음과 같다.
1) 기본적으로 딥러닝 모델이 잘 작동하는지는 학습 데이터에서 epoch이 증가함에 따라 분수함수 꼴을 그리며 꾸준하게 감소하고 있는지를 확인하는 것이다. 만약에 이렇지 않다면 기본적으로 모델 설계에서 오류가 발생했음을 뜻하며 어딘가 코드를 잘못 작성하거나 적용했을 것이다. 그렇지 않다면 학습데이터에 한에서는 loss가 계속해서 감소할 것이다. 이러한 딥러닝 모델을 사람의 생각 과정 (알고리즘)에 비유한다면, 만약 해당 데이터셋에 적합한 방식의 생각 과정을 지녔다면, 비슷한 경험을 계속해서 맞이해도 큰 모순점을 발견하지 못한 채 생각을 발전시킬 수 있었을 것이다. 반대로, 비슷한 경험을 계속해서 맞이하는데 모순이 생겨 일관되지 못하게 사유하고 있다면, 이는 내부적으로 원활하게 작동하는 상태가 아니기에 다시 수정하여 모순점을 없애는 등의 조치를 취해야 한다.
2) 만약 학습데이터로 묶인 데이터의 특징이 매우 단순한 경우 (ex. 강아지 고양이 구분하기 등), 모델이 이 문제를 오랫동안 고민할수록 학습데이터 상황들에 너무나 매몰되어 역효과를 낼 확률만 커지며 (노이즈까지 학습대상으로 삼아서 overfitting이 날 확률이 커진다), 아주 짧게 고민해 본 사람도 쉽게 풀 수 있는 문제라면, 굳이 길게 학습하는 것 자체가 에너지 낭비이다.
3) 현재 주장하는 상황과 학습 데이터 간의 상관관계가 낮은 경우, 1,2번에서 모두 만족했더라도 모든 상황과 무관하게 이상하게 작동하는 모델이 되어버린다. 예를 들어, (1) 20년 전부터 10년 전까지 꾸준하게 적용된 사고방식이며, (2) 이야기하고자 하는 내용이 그리 복잡하지도 않은 경우여도, 10년 전과 현재를 비교했을 때 너무나 달라진 부분에 대해 이야기하려고 한다면, 학습 데이터 (20년 전~10년 전 데이터)와 실제 데이터 (현재)와의 상관관계가 낮기에 적용하기 힘든 모델로 작용한다. 그리고 아마 위에서 말했듯 대부분의 사람들이 나 때는~ 으로 시작하는 이야기를 싫어하는 이유는 바로 이 3번에 있을 것이다.
다만, 일반화 과정을 너무 과하게 사용할 시, 아니면 깊은 생각을 충분히 하지 않고 낮은 epoch에서 학습을 멈춰버릴 시, 세상을 삐뚤게 보는 상황이 나타난다. 세상은 매우 복잡하기 때문에 이를 충분히 이해하기 위해서는 매우 많은 파라미터를 가지고 매우 긴 시간 동안 머리 터지도록 고민해야 할 때가 많을 것이다. 이를 낮은 capacity의 모델로 해석하려고 들면, 분명히 그냥 낮은 퍼포먼스를 내는 결과만 나타날 것이다. 그리고 이는 추천 알고리즘으로 비슷한 콘텐츠를 지속적으로 보게 되는 현대 사회에서는 세상에서 마주하게 되는 데이터셋을 단순할 것이라고 착각을 유발하여 오히려 낮은 capacity의 모델을 사용하게 만든다. 이는 overfitting과 정반대의 상황인데, 이때 사용할 수 있는 방법은 학습 데이터셋 구성을 다시 고민해 보거나 (추천 알고리즘을 부수고 새로운 경험들을 하거나), 고의적으로 파라미터를 늘려서 새로운 모델을 구상 (비슷한 경험을 하더라도 더 깊게 사유하고 생각하지 못한 면이 없나 점검하는 진중한 태도)하여 변화를 모색하는 것이 좋다.