Thanks to BOAZ.
보아즈 세션에서 실력이 매우 뛰어나신 분에게 딥러닝의 본격적인 내용을 들었다. 굉장히 설명을 잘해주시고, 그 내용들이 인상깊어서 이곳에 정리하려고 한다. 물론, 그 분의 강의력 만큼 이 글에 녹아낼 수 있을지는 모르겠다.
퍼셉트론이 등장하게 된 배경은 딥러닝의 의의와 관련이 있다. 어떤 데이터를 가져와서 모델에 넣어 결과를 추출하는 머신러닝과는 달리, 딥러닝은 인간의 뇌를 모방하는 것 부터 등장한다. 뇌의 신경, 즉 neuron을 표방하는 것에서 퍼셉트론이 대두된다.
자극을 수용하는 수상 돌기에서 시작되어, 신경 줄기를 타고 들어가 축삭 돌기로 최종적으로 전달되는 것과 같이, 입력 값이 인공 신경망의 입력층으로 타고 들어가 가중치가 설정되어있는 은닉층, 그리고 활성화 함수를 거쳐 최종적으로 출력층으로 결과값이 도출되는 과정이 신경망을 표방한 것과 같다고 할 수 있다.
이 퍼셉트론의 등장으로 학술계는 인간의 뇌를 완벽히 모방할 수 있다는 기대감에 가득차기 시작한다. 그러나...
하나의 퍼셉트론, 즉 single neural network의 한계점이 드러나기 시작한다. 바로 'XOR Problem'이다.
"같다와 다르다의 개념을 선 하나로 표현할 수 있어?"
AND, OR은 충분히 선형적으로 구분할 수 있지만, 퍼셉트론이 과연 같다와 다르다를 구별할 수 있느냐라는 문제가 등장한다. 어떤 식으로 그어도 절대로 저 XOR을 나타낼 수가 없다는 것이다. 결국 퍼셉트론은 이런 평가를 받게 된다.
"이딴 간단한 XOR 문제도 해결 못하는 것이 무슨 신경망이야!"
그렇게 인공 신경망은 암흑기를 맞이하게 된다. 하지만...
단 한개의 퍼셉트론이 이를 해결하지 못하면, 여러개를 사용하면 어떨까라는 해결법의 희망이 대두되고, 실제로 위의 문제를 해결하게 된다. 단, 단순히 층을 여러개 쌓는 것이 아닌, 중간에 어떤 추가적인 요소가 들어가는데, 바로 "활성화 함수"다.
중간의 저 ~모양이 바로 활성화 함수인데, 아마 시그모이드 함수를 나타낸 것처럼 보인다. 실제로 시그모이드 함수의 종류 중 하나인 로지스틱 회귀 모델이 저 모양을 갖추고 있다. 그럼 왜 활성화 함수를 사용하느냐, 바로 모델의 복잡도를 올리기 위해서이다.
모델의 복잡도를 쓸데없이 왜 올리느냐 하면, 바로 위의 XOR Problem같은, 선형으로 절대 풀 수 없는 복잡한 문제들을 해결할 수 있게 된다. 활성화 함수는 선형 함수가 아닌, 비선형 함수로 이루어져 있는데 데이터들이 활성화 함수를 거쳐가면 훨씬 더 복잡한 형태의 데이터로 나타나게 되고, 결과적으로 복잡한 문제들을 해결하며, 훨씬 의미있는 복잡성 높은 데이터들을 도출할 수 있게 된다. 선형으로 나타나지 않는 올바른 데이터를 도출할 수 있도록 학습하기 위해서는, 결국 활성화함수도 비선형 함수여야 하는, 매우 당연한 이치다. 또한, 활성화 함수 뿐만 아니라 중요한다른 기법도 사용하는데, 바로 역전파 (Backpropagation)이다.
머신러닝, 딥러닝을 조금 해봤다면 학습은 한 번이 아닌, 적어도 몇 천번, 또는 수십 억 그 이상을 학습을 시켜야 비로소 모델이 제대로 학습이 된다는 것을 알 것이다. 그런데 아까 설명했듯, 각 신경층 사이에는 매우 복잡한 활성화 함수가 존재하며, 데이터는 이 복잡한 함수를 거쳐 최적화가 된다. 그럼 수십억번을 이 복잡한 층을 처음부터 거쳐야 한다는 것인데, 이러면 계산량이 상당히 많아 엄청나게 비효율적인 과정이 된다. 이를 해결하는 것이 역전파다.
o는 활성화 함수를 거친 이후의 결과값, z는 활성화 함수, w는 가중치, E는 오차(Error)다.
위의 식에서 확인할 수 있다시피, 모든 층에 대하여 미분을 실행할 필요없이 한 층에 대해서만 미분을 실행하여 차례차례로 이를 곱해주기만 하면 된다.
데이터가 신경망을 통과하면 정답과의 오차가 발생하는데, 이 오차는 함수들을 여러번 합성하여 나온 결과, 즉 합성함수의 결과에서 도출된다.
Loss = f1(f2(f3....(fn(x))...)인데, chain rule을 이용하여 역으로 이를 계산하면 미분이 매우 쉽게 된다. 즉, 역순의 계산이 더 유리하다는 것이다. 따라서 각 Gradient를 역으로 단순히 곱하기만 하면 전체에 대한 Loss Gradient가 나온다.
이렇게 들으면 완벽한 신경망인데, 기존의 시그모이드 함수에서 새로운 문제가 대두되기 시작한다. 신경층 한 층을 통과한다는 것은, 그 중간의 활성화 함수의 미분과정이 이루어지는데, 시그모이드 함수의 미분 최대값은 0.25밖에 되지 않는다. (아래 그림 참고)
위 그림은 시그모이드 함수를 미분한 그래프인데, 보다시피 최대값이 0.25밖에 되지 않는다. 미분 최대값이 0.25라는 것은 한 레이어를 거칠 때마다 원래 Gradient의 최대 1/4밖에 반영을 못한다는 것이고, 예를 들어 100층의 레이어를 통과하면 (0.25)^100 ~= 0에 수렴하여 0에 가까운 오차가 발생한다. 결국 모델은 오차가 없는 것으로 인식하여 학습 자체가 이루어지지 않는다. 전파를 시킬 수록 변화가 점점 사라진다고 하여 이른바 Vanishing Problem이 발생한다.
이를 해결하기 위해 새로운 함수가 등장하였으니, 바로 ReLU다. 딥.초.뜯 시리즈에서 ReLU함수를 잠깐 다룬바가 있었는데, 보면 중간 층은 꼭 Sigmoid()가 아닌, ReLU()를 쓰라는 이유가 있었는데, 바로 업데이트가 안된다는 문제점 때문에 ReLu()를 쓰라는 것이었다.
여기서 오류가 바로 Vanishing Problem.
이 이유가 바로 Vanishing Problem을 야기해서 그런 것이다. 그럼 ReLU는 무엇일까?
앞서 말한 시그모이드 함수는 Vanishing Problem으로 인해 뒤쪽 신경망이 학습을 할 수 없으므로 등장한 것이 ReLU다. 단순히 값이 0보다 큰지 확인하고, 0보다 크면 미분값은 1로 고정되므로, Vanishing Problem을 해결한다.
이 개념은 우리 뇌가 모든 상황에서 가급적 좋은 것만을 받아들이려고 하는 것과 유사한 성질에서 유래한 것으로, 미분량이 단순히 0, 1이기 때문에 계산량이 굉장히 적어진다. 매우 단순한 구조의 함수이기 때문에 은닉층에서 주로 사용되고, 마지막 층에서 시그모이드 함수를 사용함으로써 정확도를 올리는 구조다.
본격적인 CNN은 다음 글에서 다루겠다.