Post

인공신경망 ( ANN ) 5 오차역전파법(backpropagation)

numerical_gradient에서는 수치 미분을 통해 기울기를 계산했었는데 이는 다음과 같은 두가지 문제점이 있다.

  1. 정확한 미분값이 아니라, 근사값이다.
  2. 속도가 너무 느리다. \(w_1, …, w_n\)까지 있으면, 기울기를 계산하기 위해 이 각각을 대상으로 \(\frac{loss(x+h) - loss(x-h)}{2h}\)를 구해야 한다.

sol1. 해석적 미분을 사용한다. sol2. 중복 계산을 피하기 위해 오차역전파를 사용한다.

역전파 :역방향으로 해당 함수의 국소적 미분을 곱해 나가는 것

역전파의 핵심은 국소적 계산연쇄법칙(chain rule) 이다.

국소적 계산 : 현재 계산이 이전 계산이나 다음 계산의 영향을 받지 않는다.

연쇄 법칙 ( chain rule )

연쇄 법칙은 그냥 우리가 흔히 아는 미분법 생각하면 된다. \(h(g(f(x))’ = h’(g(f(x))) \cdot g’(f(x)) \cdot f’(x)\)

e.g.,

\(a = f(w)\), \(b = g(a)\), \(E = h(b)\) 이면

\(E = h(g(f(w)))\) 이다.

이 때 \(\frac{\partial E}{\partial w}\) 를 구하려면, (엄밀히 따지면 틀렸는지 모르겠지만,)

\(\frac{\partial E}{\partial w} = E’(w) = h’(g(f(w))) \cdot g’(f(w)) \cdot f’(w)\) \( = h’(b) \cdot g’(a) \cdot f’(w)\) \( = \frac{\partial E}{\partial b} \cdot \frac{\partial b}{\partial a} \cdot \frac{\partial a}{\partial w}\)

이므로 \(\frac{\partial E}{\partial w}\)는 이렇게 바꿀 수 있다. \[\frac{\partial E}{\partial w} = \frac{\partial E}{\partial b} \cdot \frac{\partial b}{\partial a} \cdot \frac{\partial a}{\partial w} \] * 이런 식으로 생각해도 좋고, 그냥 분모 분자에 \(\frac{1}{\partial b}\frac{\partial b}{1}\)같은걸 곱해나가면서 바꾼 거라고 생각해도 좋다.

따라서 특정 노드i는 \(\frac{\partial w_{i+1}}{\partial w_i}\)를 계산할 수 있는, 자기 자신의 도함수를 가지고 있는 상태에서 이전 노드 i+1에서 온 입력에 대해 미분값을 계산하고 이를 노드 i-1 등등이 사용할 수 있도록 가지고 있도록 구성한다면 중복 계산을 피할 수 있다는 것이다.

를 구하기 위해 역방향으로 국소적 미분을 곱해 나가면, 첫번째 계산에서는 = 1 을 두번째 계산에서는을 세번째 계산에서는을 곱하게 되므로 결과적으로가 나온다.

덧셈 노드의 역전파

z = x+y를 미분해보면 x에 대해서 미분하든, y에 대해서 미분하든 1이 나오기 때문에 입력을 그대로 흘려보낸다 고 생각하면 된다.

곱셉 노드의 역전파

z = xy를 미분해보면 x에 대해 미분하면 y, y에 대해 미분하면 x가 나오기 때문에 입력을 서로 바꾼 값을 역전파 하게 된다. 순방향 입력 신호 값이 무엇이었는지 역전파 시점에 알 수 없기 때문에 순전파 시점에 입력값을 저장해두어야 한다.

이런 식으로 순방향 입력 신호를 저장해야 하기 때문에, 보통 각 layer를 하나의 클래스로 구현하게 된다.

활성화 함수 계층

위와 같은 방식을 조합하면 ReLU, Sigmoid 등의 좀 더 복잡한 활성화 함수도 forward, backword method를 가진 layer로 구현할 수 있다.

Affine layer

순전파에서 입력값 X와 가중치 W를 내적한 다음 편향 b를 더했다. 수식으로 표현하면 Y = XW + b이고 이를 구현한 layer를 Affine layer라고 한다. * f(x) = ax + b 형태의 선형 변환을 의미하는 Affine transformation에서 따온 듯.

Softmax-with-Loss layer

분류에서 사용하는 소프트맥스 함수와 교차 엔트로피 오차 함수를 묶은 계층이 Softmax-with-Loss layer다. 이 layer의 최종 역전파 결과는이다.

y는 softmax 계층의 순전파 출력 이고 t는 정답 레이블 이므로 y - t는 오차 로 해석할 수 있다.

이렇게
오차가 앞 계층에 전해지기 때문에 오차역전파법(backpropagation)이라 한다.

왜 softmax 계층의 역전파가 저렇게 깔끔하게 떨어지냐면, 애초에 교차 엔트로피 함수가 그런 결과를 내도록 설계되었기 때문이다. 그래서 소프트맥스 함수와 교차 엔트로피 함수는 함께 사용한다. * 항등 함수의 손실 함수로 평균 제곱 오차를 사용하는 이유도 같다. 이 역시 역전파 결과가이다.

오차가 크면 클 수록 앞 계층으로 큰 오차를, 작으면 작은 오차를 전달하므로 오차가 클 수록 학습 정도가 크다.

신경망의 학습 과정

수치 미분을 사용하면 매번 loss에 w, b,를 넣어 \(\frac{loss(x+h) - loss(x-h)}{2h}\)를 구해야 하지만 오차 역전파를 사용하면 이 부분을 역전파로 대체하게 된다.

loss를 딱 한번만 호출해도 모든 기울기를 구할 수 있기 때문에 속도가 많이 빨라진다.

기울기 산출에서 오차역전파법을 사용했을 경우 신경망이 데이터를 학습해가는 과정을 정리하면 다음과 같다.

  1. 하이퍼 파라미터를 초기화한다. 1~3을 반복한다.

  2. 미니배치 훈련 데이터 중 일부를 무작위로 뽑아 미니배치를 만든다.
  3. 기울기 산출 가중치 매개변수에 대한 손실 함수의 gradient를 구한다. 이 때 보통 gradient(x, t)를 넘겨 내부에서 y를 계산하도록 한다.
    • gradient 호출
    • gradient에서 loss 호출
    • loss에서 predict 호출하고 출력 y를 SoftmaxWithLoss.forward(y, t)에 입력 후 출력 lossValue 리턴… 하지만 여기서는 이를 사용하지는 않는다. - backward 호출해서 gradient 계산 및 인스턴스 변수에 저장 - 인스턴스 변수에 저장된 gradient 값 사용

loss의 출력 lossValue는 loss를 계산해야 할 때 따로 호출한다.

  1. 매개변수 갱신경사법을 사용해 가중치 매개변수를 2에서 계산한 gradient를 지표로 갱신한다.
train_loss_graph:

범용성 평가

훈련 데이터에 대한 손실 함수의 값이 감소한다고 해서 다른 데이터에 대해서 같은 정확도를 보일거라는 보장은 없다. 훈련 데이터에 대해서만 좋은 결과를 내는 경우, 훈련 데이터에 오버피팅(overfitting) 되었다고 말한다.

따라서 학습 도중 정기적으로 훈련 데이터와 시험 데이터를 대상으로 정확도를 기록해서 비교해야 한다. 이 때 주로 에폭 단위로 기록/비교하게 된다. 1에폭(epoch)은 학습에서 훈련 데이터만큼 데이터를 뽑아냈을 때의 횟수에 해당한다. 10000개의 데이터에서 배치 사이즈가 100이면, 100회 반복해야 10000개의 데이터를 사용하게 된다. 이 경우 100회가 1에폭이다. * 랜덤으로 100개를 100번 뽑는 거니까, 10000개를 하나씩 모두 사용한 것이라고 할 수는 없다.

보통 에폭이 진행될수록 훈련 데이터, 시험 데이터에 대한 정확도가 모두 높아지는데, 일정 횟수가 지나면 시험 데이터에 대한 정확도가 떨어지기 시작한다.(훈련 데이터에 대한 정확도는 계속 상승한다.) 이 때가 오버피팅이 시작되는 시점이며 여기서 학습을 중단하는 것을 조기 종료라고 한다.

train_acc & test_acc:

This post is licensed under CC BY 4.0 by the author.