[CS182] Lecture 5 - Backpropagation

2022. 8. 2. 01:39ML, DL/CS182

 

CS 182: Deep Learning

Head uGSI Brandon Trabucco btrabucco@berkeley.edu Office Hours: Th 10:00am-12:00pm Discussion(s): Fr 1:00pm-2:00pm

cs182sp21.github.io

 

 

머신러닝은 data와 parameter의 연산으로 이뤄진 program이라고 할 수도 있는데,

이를 computation graph를 그려서 visualize할 수 있다.

예로, 간단한 linear regression에서의 MLE loss가

로 나타날 때, 이에 대한 computation graph는

이와 같이 그릴 수 있다.

하나의 '연산'을 어떻게 정의하는가에 따라 이를 단순화할 수 있는데, 여기서는 vector 간의 dot product를 사용해

와 같이 나타낼 수도 있다.

 

조금 더 복잡한 경우를 알아볼까? 다음은 logistic regression에서의, softmax를 probability로 사용한 negative log-likelihood loss 식이다.

이를 computation graph로 그려보면 다음과 같은데, 꽤 복잡해 보인다.

여기서 y의 경우 data label을 one-hot vector로 나타낸 것이다.

조금 더 간결하게 나타내 보면, sofrmax를 하나의 연산으로 취급하여

이렇게 그릴 수도 있다. x는 vector, theta는 matrix이고 log를 마지막에 취했음에 유의하자.

 

더 간결하게 나타내 볼까?

이 연산에서 사용하는 variable들은 dataparameter로 나뉘는데,
parameter는 (항상은 아니지만) locally하게 사용된다. 
또한 y는 마지막에 loss를 구할 때만 작용함을 생각해서 그려 보면,

이렇게도 가능하다.

형태는 다르지만, 모두 input과 parameter를 곱하는 linear layer를 나와 softmax를 통과해 loss를 계산하는 과정을 담은 것이다.

 

Neural network diagram으로도 표현할 수 있는데,

 

 

layer의 경우 사다리꼴을 사용하고,
보통 parameter와 loss 부분은 표시하지 않기도 한다.

 

layer를 arrow-notation으로 표시해 다음과 같이 줄일 수도 있다.

간단하다.

 

Logistic regression은 대상 data가 linear seperable하거나, 그에 준한 경우 데이터를 잘 분류한다.
당연하게도 항상 data가 linear separable하라는 법은 없다. 이럴 경우 어떻게 할까?

data로부터 새로운 feature를 추출한다면, 해당 feature space에서 logistic regression을 적용할 수 있다.
이때 feature의 dimension은 원본과 다를 수 있다.

 

 

이 강의에선 softmax를 이용해 feature를 추출하는데, 자세히는 feature의 dimension별로 sigmoid 함수를 적용하는 방식이다(즉 기존의 softmax는 아니나, sigmoid 자체가 softmax의 특수형이기 때문에 틀린 말은 아니게 된다).
사실 꼭 softmax를 사용할 필요는 없고, nonlinearity function을 사용하면 된다(ReLU 등).

 

 

 

그렇다면 feature를 추출해서 사용하는 model의 graph를 보자.
기존의 linear layer --> softmax --> NLL 과는 다르게,
중간에 feature를 추출해야 하는 한 linear layer와 sigmoid가 들어간다.

 

이 역시 더 간단히 그릴 수 있다.
첫 번째 layer의 이름이 sigmoid layer임을 참고하자.

 

 

그리고, 이런 layer들을 많이 쌓아 만드는 모델이 딥러닝 모델이 된다.
그림엔 3개의 sigmoid layer가 있지만, 원하는 많큼 더 넣을 수도 있다.

 

이렇게 nonlinearity를 부여해 주는 함수들을 Activation function이라고 한다. 앞서도 말했지만, sigmoid 함수만이 아닌 tanh, ReLU 등 다양한 activation function들이 있으니 상황에 따라 적절한 것을 사용하면 된다.
여기서 한 가지 의문을 가질 수 있는데, 어째서 nonlinearity 함수여야만 할까?
조금만 생각해보면 알 수 있는데, linear한 함수라면 그것은 곧 output에 대해 linear transformation을 거치는 것과 같다.
그런데 그 output은 앞에서 linear transformation(linear layer)를 거치지 않았는가? 두 개의 linear transformation의 합성은 역시 linear transformation이므로, 두 개의 layer는 사실 하나의 layer와 같아지게 되어 굳이 layer를 추가한 의미가 없어지기 때문이다.

 


 

이제 model training 과정을 알아보자.

  1. model을 학습시킬 목표 class를 정의한다.
  2. Loss fcn을 정의한다. 주로 MSE, NLL(Cross-entropy loss) 등을 사용한다.
  3. Optimizer를 골라 parameter를 최적화한다(SGD, +momentum, Adam...).
  4. GPU에서 신나게 돌린다.

 

사용하는 Optimizer들은 (거의) 모두 gradient를 사용해 parameter를 최적화한다. 즉 우리는 우리가 사용하는 변수들의 gradient를 알아야 한다. 이는 Chain rule을 통한 Backpropagation algorithm을 사용해 구할 수 있다.

 

 

Composition function의 gradient를 계산하기 위한 방법인데, 전체 function의 gradient를 각 function의 gradient의 곱으로 나타내는 것이다. Input과 output 모두 vector인 경우, gradient는 Jacobian matrix 형태로 계산됨에 유의하자.
Vector에 대한 연산이다 보니, 통째로 이해하려 하기보단 각 element별 식을 구한 후 전체 vector에 대해 정리하는 것이 보다 더 이해하기 쉬웠다. 물론 그래도 머리가 아팠던 건 여전하지만...

 

아무튼, neural network 역시 많은 function들의 composition이므로, chain rule을 통해 각 variable에 대한 gradient를 계산할 수 있다.

 

 

그런데 이를 그냥 적용하기에는 한 가지 문제가 있다. 위 이미지의 좌하단 식을 보면,
가장 우측의 dL/dz_2는 vector이나 나머지 3개의 항은 jacobian matrix이다.
Matrix multiplication에는 시간이 많이 걸린다. 예로, 두 n * n matrix를 곱한다면 time complexity는 O(n^3)이다.
만약 n이 커진다면, 굉장히 시간이 오래 걸리는 것이다.

 

 

 

그래서 한 가지 트릭을 사용하는데, 바로 "뒤에서부터" 계산하는 것이다. matrix - vector multiplication의 경우 
O(n^2)의 time complexity를 가지므로, 앞서의 방법보다 훨씬 효율적이 된다.

 

 

 

이를 model에 적용하면 다음과 같다.

  1. 먼저 loss에 대한 마지막 output의 gradient를 계산한 뒤 delta라고 하고, 
  2. 각 layer의 함수 f에 대해 해당 layer의 input과 parameter에 대한 gradient를 계산한 뒤
    delta와 곱해줘서(Chain rule!) loss에 관한 gradient를 구하고, 값들을 갱신해준다.
  3. 이를 모든 layer에 대해 반복한다.

이제 실제 모델을 개발하는 부분에 관해 살펴보자.

 

 

보통 layer을 얼마나 할 것인지, layer의 size는 어느 정도로 할지, activation function은 무엇으로 고를지 등을 결정해야 한다. 여기서 activation function의 경우 앞서 말했던 것처럼 많은 선택지가 있는데 가장 많이 쓰이는 것 중 하나가
바로 ReLU(Rectified Linear Unit)이다.
함수가 단순하다 보니 계산도 빠르고, gradient 형태도 간단하다는 장점이 있다.

 

 

앞서의 layer들은 그저 input과 weight를 multiplicate했지만, input이 zero-vector인 경우 이후의 모든 layer에서의 output이 zero-vector가 나오는 참사가 벌어진다.
이를 방지하기 위해 bias term을 각 linear layer에 추가해준다.

 

결국 이 형태의 layer들에 대해 forward pass 후 backpropagation을 통해 gradient를 계산해서 optimization에 사용하는 것이 모델 학습이다.
몇 가지 backpropagation의 예를 들어보겠다.

 

 

앞서 서술한 대로, 현재 function에서 input과 parameter를 구해 delta와 곱해주면 된다.
간단히, z = Wa + b라고 하자. W 대한 gradient를 한 번 계산해 보겠다.

 

dz_i / dW_jk를 구하기 위해 먼저 z_i의 식을 살펴보자.
z_i 내부에는 W_ik만 존재한다. 즉, dz_i / dW_jk는 i j 다르다면 0, 같다면 a_k가 된다.
그러면 dz/dW cube 형태를 지닌 tensor 되겠지만, i j 다른 모든 element에선 0 되는 tensor이다.
이것과 델타를 곱할 경우, W 크기를 가지는 평면들과 델타의 원소들을 곱한 것들을 합쳐 주는 되고,
그 평면에서는 단 한 줄의 vector만 zero-vector가 아니기에, 대충 시각화를 해 보면

 

네, 저는 악필에 그림도 못 그립니다.


이런 식으로 나는 이해했다. 나는...
어쨌든, 이
형태는 결국 delta aT outer product 같게 된다.

 

z의 bias에 대한 gradient는, 단순히 더하는 term이므로 jacobian은 다음과 같은 identity matrix이다.

 

z의 input vector에 대한 gradient는 W의 transpose matrix가 된다.

 

즉, 정리하면 한 linear layer에 대한 variable의 gradient들은 

 

다음과 같다.

 

 

정리하면, model에 대해 forward pass를 거친 후, backpropagation algorithm을 이용해 모든 layer의 variable들의 loss에 대한 gradient를 구하며 optimize해나가는 것이 model을 훈련하는 과정이다.

'ML, DL > CS182' 카테고리의 다른 글

[CS182] Lecture 4 - Optimization  (0) 2022.08.07
[CS182] Lecture 3 - ML Basics 2  (0) 2022.08.05
[CS182] Lecture 2 - ML Basics 1.  (0) 2022.08.04
[CS182] Lecture 1 - Introduction  (0) 2022.08.04
[CS182] Lecture 6 - Convolutional Networks  (0) 2022.08.02