Backpropagation

오차역전파법. 풀어쓰자면 Backward Propagation Of Errors 라고 할 수 있다. 즉, 오차를 역으로(반대방향으로) 전파하는 방법이다.
오차역전파법은 계산 그래프로 이해해 볼 수 있다.
  • 계산 그래프
  • 계산 과정을 그래프로 나타낸 것. 이곳에서 볼 수 있듯이 계산 그래프의 흐름은 일반적으로 아래와 같다.

    간단하게 나타내면

    연산식($+,*$ 같은 간단한 연산부터 $\sqrt{x+\epsilon},**2$ 같은 연산까지)이 각각의 Node가 되고, Edge는 변수혹은 노드들의 국소적 계산 결과가 된다.
    이렇게 국소적 계산을 하는 계산 그래프를 사용하면 역전파를 통해 미분을 효율적으로 계산할 수 있다.
    위와 같이 연산식에 따른 역전파는 상류의 역전파값에 국소적 미분값을 곱해서 하류로 흘려보낸다.
    이렇게 국소적 미분값을 곱해서 흘림으로써, 위에 간단하게 나타낸 그림에서 마지막 $x$로의 역전파 값을 보면 $\partial{z}$와 $\partial{t}$가 사라져
    $$\frac{\partial z}{\partial x} \text{ : x에 대한 z의 미분} $$
    을 구할 수 있다. 같은 방식으로 $t$에 대한$z$의 미분값도 구할 수 있다.
    즉, "중간 결과값들에 대한 최종결과값의 미분"을 구할 수 있다는 것이고, 이를 신경망에 적용해 생각해보면 각 층마다의 가중치와 편향값에 대한 손실 함수의 미분값이 구해진다는 것이다.
  • 어파인 = Affine 계층
  • 신경망의 순전파 때 수행하는 행렬의 내적을 어파인 변환 = Affine Transformation 이라고 한다.
    어파인 계층은 이 어파인 변환을 수행하는 처리를 말한다.
    순전파 : 입력x와 가중치 W의 내적 후 편향을 더해준다.(numpy 브로드캐스트)
    역전파 : 가중치의 미분값에는 전치행렬을 사용하고, 편향의 미분값은 상류의 미분흐름의 총합으로 구해준다.
    입력 데이터가 텐서(4차원 데이터)인 경우도 고려해서 파이썬으로 구현하면 다음과 같다.
    class Affine:
        def __init__(self, W, b):
            self.W = W
            self.b = b
            
            self.x = None
            self.original_x_shape = None
            # 가중치와 편향 매개변수의 미분
            self.dW = None
            self.db = None
    
        def forward(self, x):
            # 텐서 대응
            self.original_x_shape = x.shape
            x = x.reshape(x.shape[0], -1)
            self.x = x
    
            out = np.dot(self.x, self.W) + self.b
    
            return out
    
        def backward(self, dout):
            dx = np.dot(dout, self.W.T)
            self.dW = np.dot(self.x.T, dout)
            self.db = np.sum(dout, axis=0)
            
            dx = dx.reshape(*self.original_x_shape)  # 입력 데이터 모양 변경(텐서 대응)
            return dx
    
  • Softmax-with-Loss
  • 출력층에는 Softmax 계층과 손실 함수인 교차 엔트로피 오차를 포함해 Softmax-with-Loss라는 이름의 계층을 구현한다.
    이를 사용하는 것은 손실 함수 게시물에서 평균 제곱 오차에서 구한 것과 같이, 정답을 어느정도의 확률로 추정하는지 알기 위함이다.
    순전파와 역전파는 아래와 같다.출처

    언뜻보면 복잡해보이지만, 중간부분은 생략하고 end부분만 살펴보자.
    그러면 역전파가 $(y_1 - t_1,y_2 - t_2,y_3 - t_3)$ 와 같이 간단한 결과로 나옴을 알 수 있다.
    이는 '소프트맥스 함수'의 손실 함수로 '교차 엔트로피 오차'를 사용해 설계한 결과로, 비슷한 방법으로 회귀의 출력층에서는 '항등 함수'의 손실 함수로 '평균 제곱 오차'를 사용하면 똑같이 역전파의 결과가 나온다.
    실제 예를 들어 이해해보자.
    정답 레이블 t가 (0,1,0)일 때 Softmax계층이 (0.3, 0.2, 0.5)를 출력했다면, 확률은 0.2(20%)로 잘 인식을 못했다는 얘기다.
    그리고 이때의 Softmax의 역전파는 (0.3, -0.8, 0.5)라는 값이 된다.
    두번째로 t가 (0,1,0)으로 같고 Softmax계층이 (0.01, 0.99, 0)을 출력했다면, 확률은 0.99(99%)로 잘 인식했다는 얘기다.
    그리고 이때의 Softmax의 역전파는 (0.01, -0.01, 0)라는 값이 된다.
    위에서 파이썬으로 구현한 코드에서 쉽게 와닿듯이, backward부분에서 dout값이 커지면 해당 계층들의 dW와 db값도 크게 변할 것이다.
    따라서 소프트 맥스의 역전파 결과가 위와 같이 설계함을 통해 하류의 층들에 학습을 효과적으로 시킬 수 있다.
  • 기울기 확인 = Gradient Check
  • 오차역전파법은 속도는 빠르지만 구현이 복잡해 실수할 확률이 높다.
    그래서 구현이 쉬운 수치 미분의 결과와 비교해, 두 방식으로 구한 기울기가 일치하는지(거의 같은지) 확인하는 작업이 기울기 확인이다.

댓글

이 블로그의 인기 게시물

Loss Function

SGD = Stochastic Gradient Descent