[비전공자를 위한 딥러닝] 2.7 신경망 (5) - 역전파로 학습하기





신경망 모델은 위와 같이 학습을 진행한다.

모델이 "데이터"를 입력으로 받아 층별로 계산을 한 뒤 "예측" 값을 내놓는 과정까지를 순전파(forward propagation)라고 한다.

그 예측과 정답과의 거리를 계산하고 평균을 내 "비용"을 계산한 뒤, 모델이 더 좋은 예측을 할 수 있는 방향으로 (비용이 적어지는 방향으로) 가중치들을 업데이트하는 과정을 역전파(backpropagation)라고 한다.

이 과정을 반복하면서 모델은 점점 더 예측을 잘 할 수 있게 되는데, 이를 학습이라고 한다.



순전파 단계에서는 가중치가 고정되어 있으며, 이전 층의 노드(동그라미)와 가중치(연결선)의 가중합을 통해 다음 층의 노드가 계산된다. 이 노드의 값을 엑티베이션이라고 한다.

역전파 단계에서는 계산된 비용을 거꾸로 전파시키는데, 가중치들을 올바른 방향으로 업데이트시키는 것을 목적으로 한다. 올바른 방향이란 비용을 낮추는 방향을 말하며, 이는 각 가중치별 기울기(각 가중치가 변할 때 비용이 변하는 정도) 계산을 통해 알 수 있다.
역전파를 자세히 살펴보기 전에 대략적으로 설명하자면, 마지막 층부터 왼쪽으로 가면서 만나는 가중치들에게 각각 "너는 얼마나 비용의 증가에 기여했는지"를 따져서 그 반대 방향으로 업데이트시켜준다고 생각하면 된다.

이전 장에서도 설명했듯이 하나의 데이터에 대한 예측과 정답의 거리는 "오차"라고 하며, 모든 데이터에 대한 오차의 평균을 구하면 비용이 된다.


위와 같이 하나의 가중치만 놓고 생각을 해보자.
이전 장에서 다뤘듯이, 가중치들은 위와 같은 계산식을 통해 업데이트된다. 업데이트 되는 값의 의미를 잠깐 복습해보자면 다음과 같다.


이때 기울기란 가중치 w가 변할 때 오차가 얼마나 변하는지 그 정도를 의미한다.

즉, 계산식이 의미하는 바는 원래값에서 기울기 반대 방향, 즉 오차를 줄이는 방향으로 가중치를 업데이트한다는 것이다. 이때 너무 크게 변화를 주지 않도록 아주 작은 값(학습률)을 곱해준다.

편미분이나 학습률이 헷갈린다면 2.5  신경망 (3) - 경사하강법을 복습하자.


이렇듯 모든 가중치에 대해서 위의 식을 사용해 업데이트하면 역전파를 할 수 있을 것이다. (이때는 딱히 오른쪽에서 왼쪽으로 계산 순서를 정할 필요도 없다.)
하지만 이런 방식으로 계산하게 되면 계산량이 굉장히 커지는 문제점이 있다.



각 가중치가 변할 때 오차가 얼마나 변하는지(기울기) 일일이 계산하는 일은 매우 비효율적이다. 그렇다면 어떤 대안이 있을까?



기울기는 편미분을 통해 계산되는데, 이때 두 층 사이의 기울기는 각 층 기울기의 곱으로 표현할 수 있다. 즉, 초록색 기울기와 노란색 기울기를 곱한 것이 빨간색 기울기와 일치한다는 것이다.


이를 식으로 표현한다면 위와 같다. A에서 B로 가는 기울기와 B에서 C로 가는 기울기를 곱하는 방식으로 A에서 C로 가는 기울기를 구할 수 있다는 것이다. 이것을 연쇄 법칙(chain rule)이라고 한다. 


우리가 구하려고 한 가중치를 살펴보면, 해당 가중치의 오차에 대한 기울기는 위와 같이 기울기 두 개의 곱으로 바꿔볼 수 있다. 이렇게 두 개의 곱으로 표현하면 어떤 점이 좋을까?

첫째로는 두 기울기 중 하나가 이미 계산되어 있다는 점이다.



노란색 기울기를 살펴보면, 이는 역전파를 진행해오면서 이미 계산된 적이 있는 기울기임을 알 수 있다.


오른쪽에서부터 왼쪽으로 역전파를 진행하기 때문에, 노란색 기울기는 이전 단계에서 노란색 가중치를 업데이트할 때 계산되었다. 이 기울기는 가중치 업데이트에 사용되고 버려지는 것이 아니라, 앞으로 왼쪽으로 역전파를 진행하는 데 있어 계속 쓰일 것이기 때문에 따로 저장해놓는다. 이 기울기들을 저장해놓은 행렬을 야코비안 행렬(Jacobian matrix)이라고 한다.

둘째로는 나머지 초록색 항의 계산량이 기존에 비해 훨씬 적다는 것이다. 다음 그림을 통해 살펴보자.


왼쪽의 경우, 한 층 사이의 기울기를 구하는 것이므로 단 한 번만 편미분을 하면 된다.
반면 오른쪽의 경우, 세 개의 층을 건너뛰어 기울기를 계산하는 과정에는 훨씬 큰 연산량(계산량)이 요구된다. 신경망이 층별로 여러 개의 노드가 서로 연결된 복잡한 형태를 하고 있기 때문에, 여러 층을 건너뛰어 단번에 기울기를 계산하려면 그 사이에 있는 기울기를 다시 구하고 더하는 과정이 필요하다. 한 번 했던 계산을 또 하지 않게 하는 것만으로도 굉장히 효율적인 연산이 가능해진다고 생각하면 쉬울 것이다.



이 연쇄 법칙을 활용한다면 아무리 복잡한 신경망 모델이라도 쉽게 역전파를 할 수 있다.

1. 단순히 "이전 층과 다음층 사이의 기울기"들만 계산해서,
2. 해당 가중치와 오차까지 연결된 기울기들을 곱해서 "해당 가중치의 오차에 대한 기울기"를 계산할 수 있다.

*실제로는 엑티베이션이 계산된 후 비선형함수를 통과했기 때문에, 이 활성화함수에 대한 편미분도 계산해서 곱해줘야한다. 너무 계산이 복잡해지면 이해하기가 어려워지기 때문에 생략했다.



이제 순전파에서 했던 예시를 이어가보자.
역전파의 경우 복잡한 편미분 과정은 과감하게 생략했기 때문에 어렵지 않게 따라올 수 있을 것이다.*

*마찬가지로 예시에서는 가중치의 기울기만 계산해서 곱했지만, 실제로는 활성화함수에 대한 편미분도 곱해줘야한다. 예측과 정답 사이의 거리를 구할 때 제곱을 했기 때문에 이 역시 계산에 포함해줘야한다.


지난 시간에 순전파를 통해 예측 값이 나오고, 정답과의 거리를 계산해 오차를 구했었다.



이제 이 오차를 거꾸로 신경망에 전파시키면서, 각 가중치를 오차에 대한 기울기를 계산해서 업데이트시킬 것이다.



위와 같이 세 가중치의 오차에 대한 기울기가 각각 계산되었다고 생각해보자.*

* 복잡한 계산 없이 직관적인 예시를 들기 위해서 각 기울기에 대한 수치는 계산하지 않으며, + 혹은 - 방향과 업데이트되는 정도도 임의로 선택했다.

(가중치의 기존값에서 학습률과 기울기를 곱한 값을 빼는) 수식을 통해 가중치의 업데이트 방향이 그림과 같이 -, +, - 라고 가정한다면, 각각 해당하는 방향으로 조금씩 업데이트될 것이다. [0.2, 0.1, 0.0]에서 [0.19, 0.11, -0.01]로 업데이트되었다고 치자.

다음 순서로는 왼쪽 층의 가중치가 업데이트될 것이다.
앞서 설명한 연쇄 법칙을 통해 한 층 사이의 가중치만 계산한 뒤 곱셈을 통해 오차에 대한 기울기를 계산할 수 있을 것이다. 자세한 계산은 생략하며, 위와 같이 가중치 업데이트 방향이 계산되었다고 한다면, 다음과 같이 가중치가 업데이트될 것이다.*

* 물론 가중치 업데이트 수식에서 알 수 있듯이, 단순히 업데이트 방향뿐만이 아니라 얼마나 업데이트될 지 그 정도도 가중치 마다 다르게 계산된다. 이해하기 쉽도록 방향만 언급했다.



마지막으로 그 다음 왼쪽 층의 가중치도 업데이트될 것이다.

이제 우리는 1회 학습을 거쳐, 좀 더 나은 예측을 하는 신경망 모델을 얻게 되었다. 물론 실제로는 단 1개의 데이터로 1회 학습한 것만으로는 의미있는 차이가 나지는 않을 것이다. 이제 다음 데이터를 입력으로 넣고 동일한 과정을 반복해보자.



두번째 데이터가 들어오면, 이전과 동일하게 앞 두 개의 값은 특성1과 특성2로, 마지막 한 개의 값은 정답으로 지정한다.


한차례 업데이트 된 가중치를 이용해, 새로운 엑티베이션 값들을 계산하면서 최종적으로 데이터2에 대한 예측 값을 도출한다. 마찬가지로 예측과 정답 사이의 거리를 계산해 오차를 구한다.


오차를 역전파시키면서 모든 가중치를 업데이트한다. 가중치들은 각각 연쇄 법칙을 통해 계산된 오차에 대한 기울기의 반대 방향으로 업데이트된다.



이런 방식으로 모든 데이터에 대해서 학습을 진행할 수 있을 것이다.
이때는 비용을 따로 계산하는 것이 아니라, 데이터마다 오차를 구해 바로 역전파시키는 방식을 사용했다. 이렇게된다면 데이터가 달라질 때마다 학습이 들쭉날쭉 이 방향 저 방향으로 진행될 가능성이 높다. 그래서 모든 데이터의 오차가 계산될 때까지 역전파를 하지 말고 기다리다가, 모든 오차의 평균을 낸 비용을 가지고 한번에 역전파를 하는 방법이 있다. 이를 배치(batch) 경사하강법이라고 한다.

하지만 이 경우에는 한 번 학습을 하는데 너무 오래 기다려야한다는 단점이 있다. 즉, 학습이 너무 느리게 진행된다는 점이다. 데이터가 우리의 예시처럼 몇 개의 숫자 특성으로 구성된 정형데이터라면 문제가 없겠지만, 이미지나 텍스트 데이터처럼 굉장히 정보와 연산량이 큰 데이터가 많은 숫자로 주어진다면 최종적으로 학습이 끝나는 데까지 몇 일이 걸릴 수도 있다. 그래서 가장 일반적으로는 다음과 같이 미니 배치로 데이터셋(전체 데이터)을 나눠서 학습을 진행한다.



16개의 데이터에 대한 오차를 구한 뒤, 그 평균인 비용을 연전파시키면서 학습하고 다음 미니 배치로 넘어간다. 이때 16개라는 숫자를 배치 사이즈(batch size)라고 하며, 이러한 학습 방법을 미니 배치 경사하강법이라고 한다. 굳이 데이터를 하나씩 순전파시키지 않고, GPU를 활용해 병렬적으로 동시에 연산이 가능하다. GPU의 성능에 따라서 배치 사이즈를 크게 설정할 수 있는데, 배치 사이즈가 클 수록 학습 속도가 빠르며 일반적으로 더 일반화 성능에 도움이 된다. 모든 데이터를 한 번 훑었을 때 1 에포크(epoch)가 지났다고 표현한다.






다음 챕터에서는 신경망 모델을 이용해 할 수 있는 것들과 모델을 잘 학습시키는 방법에 대해서 살펴보도록 하겠다. 최대한 쉽게 설명하기 위해서 간략화하거나 생략한 부분들이 있는데, 역전파에 대해서 좀 더 자세히 알아보려는 비전공자분들께 다음과 같은 자료를 추천한다.



더 알아보기

댓글 쓰기

2 댓글

  1. 비선형 변환이 필요하다고 이전 게시물을 보았는데 역전파시 활성화 함수는 어떻게 처리해야 하나요?

    답글삭제
    답글
    1. 활성화함수에 대해서도 편미분하여 해당 루트로 통과할 값에 곱해줍니다.
      포스트 하단 "더 알아보기"에서 CS231 강의를 참고하시면 역전파 계산 과정을 자세히 볼 수 있습니다.

      삭제