본문 바로가기

AI/cs231n

[강의정리] Lecture 4: Backpropagation and Neural Networks

-강의 영상

 

- Introduction

이전 강의인 Lecture 3에서는 Loss function에서의 Loss값의 gradient를 이용해서 가중치를 업데이트하는 optimization 과정을 살펴봤다. Lecture 4에서는 Optimization 과정에서 가중치를 업데이트 하는 방법 중 하나인 Backpropagation과 Neural Network의 간략한 내용을 살펴보는 내용을 소개한다.

 

- Computational graphs

먼저, 해당 강의에서는 Computational graph라는 개념을 소개한다. Computational graph는 Backpropagation 연산을 위해서 복잡한 다변수 입력에 대한 함수 수식을 simple하게 표현해주는 프레임워크이다. 해당 Graph는 연산을 나타내는 노드와 변수값에 대한 stream을 나타내는 edge로 구성되어 있다. 슬라이드에서는 lec3에서 사용했던 linear classfication 연산인 f=Wx와 Hinge loss를 연산하는 수식을 computational graph로 표현한 것이다.

 

 

- Backpropagation Simple Example (scalar)

해당 슬라이드에서는 computational graph를 이용한 backpropagation 과정을 simple한 예제에서 설명한다. 이때 함수는 x와 y를 더한 뒤 z를 곱하는 매우 simple한 함수를 사용하였고, 이러한 함수를 오른쪽 그림과 같이 computational graph로 표현을 했다. 초록색 value는 해당 변수에 대한 값, 빨간색 value는 함수의 최종출력의 해당변수에 대한 gradient 값을 나타낸다. 우리가 목표로 하는 것은 최종 출력의 각 입력에 대한 gradient(df/dx, df/dy, df/dz)이다. 이러한 gradient를 재귀적으로 구하기 위해서 우리는 Chain rule을 사용하는데, 우리가 목표로 하는 gradient 값은 어떻게 구하고, Chain rule은 어떻게 적용되는지 다음 슬라이드에서 detail하게 살펴본다.

 

 

 Backpropagation 연산에 대한 설명을 위해 computational graph 하나의 node에 focusing하여 설명한다. 여기서 local gradient에 대한 개념이 나오는데, local gradient는 한개의 local node의 입력에 대한 출력의 gradient라고 정의한다. 여기에서는 함수 f 노드의 local 입력이 x,y이고, 출력이 z이기 때문에 z의 x,y에 대한 gradient 값이 local gradient가 되는것이다.

 추가적인 개념으로 upstream gradient를 정의한다. upstream gradient는 graph의 최종 출력의 해당 노드의 출력에 대한 gradient이다. 해당 슬라이드에서는 최종 출력이 L이고 local한 노드의 출력이 z이기 때문에 L의 z에 대한 gradient가 upstream gradient가 되는 것이다. 우리가 관심있어하는 값은 해당 노드에서 입력에 대한 최종 출력의 gradient 즉, dL/dx, dL/dy 이다. 해당 값들을 구하기 위해서 우리는 chain rule을 적용할 수 있는데, 슬라이드에서처럼 해당 노드의 local gradient와 upstream gradient를 곱하게 되면 우리가 원하는 입력에 대한 최종 출력의 gradient를 구할 수 있다. 여기서 upstream gradient는 우리가 알고 있는 값이기 때문에, 우리는 해당 노드의 local gradient만 구하면 각 입력에 대한 gradient를 재귀적으로 구할 수 있다.

 

 

- Backpropagation Another Example (scalar)

 이번에는 좀 더 복잡한 함수 f에 대한 Backpropagation을 소개한다. 해당 함수를 unit한 연산의 node로 나타내면 위의 슬라이드와 같은 복잡한 함수도 computational graph로 표현할 수 있다. 우리가 원하는 각 입력에 대한 최종 출력의 gradient를 얻기 위해서, 먼저 그래프의 초록색 value에 해당하는 값들을 구한다. 각 변수에 대한 노드 연산을 수행하는 것이다. 이러한 연산을 foward pass라고 한다. 이렇게 foward pass를 진행하고 나면 모든 edge의 초록색 value를 구할 수 있을 것이다.

 우리가 궁금한 것은 각 edge에 해당하는 변수에 대한 최종 출력의 gradient이다. gradient를 구하기 위해서 가장 마지막 node부터 focusing하여 gradient 값을 구한다. 왜냐하면 가장 마지막 노드의 upstream gradient는 항상 1이기 때문에다.(왜냐하면, df/df =1)

upstream gradient는 알고 있기 때문에, 마지막 node의 local gradient를 계산하면 마지막 노드의 입력에 대한 최종 출력의 gradient를 구할 수 있다. 그리고 이 값은 이전 node의 upstream gradient가 된다. 즉, upstream gradient는 이전 노드의 gradient를 계산하는 단계에서 구한 값이므로, 우리는 재귀적으로 해당 연산을 수행하기 위해 local gradient를 구하는데에만 집중하면 된다.

 슬라이드의 아래와 같이 각 node에 해당하는 도함수들을 모두 알고 있으면, 우리는 upstream gradient는 재귀적으로 구한 알고 있는 값이기 때문에 각 노드에 해당하는 도함수를 구하고 이를 통해 local gradient를 계산할 수 있다.

 

 

해당 슬라이드는 unit한 연산 단위인 node들을 하나로 그룹화 할 수 있는 성질을 나타낸다. 슬라이드에 파란색으로 표시된 Sigmoid gate 영역을 잘 살펴보면, sigmoid function의 연산과 동일한 것을 알 수 있다. 이러한 경우 해당 node들을 그룹화 하여 하나의 node로 묶을 수 있으며, Backpropagation을 수행하는데 있어서 우리는 해당 node의 local gradient값 만 알면 되기 때문에, sigmoid function의 도함수 값만 알면 그림처럼 하나로 그룹화 시켜도 정상적인 Backpropagation을 수행할 수 있는 것이다.

 

 

- Patterns in backward flow

위와 같은 computational graph가 주어지고, forward pass와 backward pass를 모두 완료한 상황에서 각 gradient 값을 관찰해봤다. addition gate는 upstream gradient를 입력 각각의 branch에 동일 한값으로 전파시키는 distributor 성질을 가지는 것을 알 수 있고, multiplication gate는 upstream gradient를 입력 각각의 branch에 반대 입력값을 곱하는 switcher 성질을 가지는 것을 알 수 있었다.

또한, max gate는 upstream gradient 값을 하나의 branch에만 전달하고 나머지는 0의 값을 취하는 router 성질을 가지는 것을 알 수 있었다. 해당 node 연산들은 unit한 연산이기 때문에 이러한 특징을 잘 파악해두면 backpropagation에 잘 적용해볼 수 있다.

 

- Backpropagation Example (vectorized)

이번에는 변수가 scalar가 아닌 vector값에 대한 backpropagation에 대해 설명한다. upstream gradient는 이미 구해져 있는 값이기 때문에 vector에 대한 local gradient 값만 구한다면, 우리는 목표하는 gradient값을 구할 수 있다. 따라서 우리는 vector에 대한 local gradient 값을 구하는것이 목적이다. 이러한 local gradient 값을 구하기 위해 Jacobian matrix라는 개념을 이용한다.

 

 

- Jacobian matrix

Jacobian matrix는 슬라이드에 나와있는 것처럼 n차원의 입력벡터 x, m차원의 출력벡터 f(x)를 가지는 벡터 함수 f에서 왼쪽 아래와 같은 m*n 행렬로 정의한다. 각 행은 n차원의 입력에 대한 m차원의 출력 gradient를 나타낸다.

 

만약, 이렇게 3차원의 x 입력과 4차원의 y 출력을 갖는 f가 있을때, 우리가 원하는 y의 x에 대한 gradient는 그림과 같은 Jacobian matrix로 표현이 된다. 해당 matrix는 4*3의 크기를 갖는 행렬이다.

 

 

- Vectorized operations

 그림과 같이 4096차원의 입력과 4096차원의 출력이 주어지면, 해당 Jacobian matrix의 크기는 4096*4096의 크기가 되는것을 알 수 있다. 이렇게 행렬의 크기가 커지는것은 vectorized operation의 issue중 하나이다.

 이렇게 구한 Jacobian matrix는 우리가 계산하기를 원하는 local gradient에 해당하고, upstream gradient 값은 이미 구해져 있는 값이기 때문에 Jacobian matrix와 upstream gradient의 곱셈 연산을 통해 해당 node의 입력에 대한 최종 출력의 gradient를 구할 수 있게 되는 것이다.

 

 

- Vectorized example

해당 슬라이드에서는 Linear classification의 L2 norm 연산에 대한 computational graph에서 backpropagation 연산 과정을 보여준다. 해당 슬라이드에서는 재귀적인 연산과정 중에 나머지는 생략하고, multiplication 노드에서 x에 대한 gradient를 구하는 과정에 집중해서 보여준다. x와 W의 mul gate의 출력을 q라고 했을때, 우리는 upstream gradient를 알고 있기 때문에 local gradient에 해당하는 q의 x에 대한 gradient만 구하면 된다. x를 입력, q를 출력으로 하는 Jacobian matrix를 빨간 글씨로 필기한 것 처럼 구하면, Wk,i 라는 local gradient를 구할 수 있다. 최종적으로 전체 출력의 x에 대한 gradient를 구하기 위해서는 앞에서 구한 local gradient와 upstream gradient를 곱하면 된다.

 

- 2 layers Neural networks

 우리는 lecture3에서 Linear classification을 수행하는 neural network를 살펴봤다. lec3에서의 neural Network는 f=Wx의 Linear score function을 가지는 함수였다. 이 때 x는 3072*1차원의 크기를 가지는 이미지 픽셀 값이고 s는 10개의 카테고리를 가지는 10*1 크기의 score 행렬이었다. 그림으로 나타내면 아래와 같다. 위의 아래에 10개의 카테고리별 template가 있다. 이는 이미지 픽셀이 해당 score에 어떤 영향을 끼쳤는데 시각화 하기 위해서 W 가중치 행렬의 각행을 시각화 한 것이다. 각 행은 각 위치의 카테고리 score에 영향을 주므로 W가중치 벡터의 각 행은 특정 카테고리의 score를 분류하는 가중치를 이미지로 보여준다.

 

 

 이때, layer가 1개인 lec3의 neural network를 사용하게 되면 각 카테고리가 가지고 있는 특징을 하나의 template에 모두 담아야한다는 issue가 있다. 예를들어, 2번째 카테고리 car의 template를 보면 붉은 색깔을 띄고있고 해당 template를 통해서 신경망은 현재 빨간색의 특징을 이용해서 자동차를 찾고있는 것을 알 수 있다. 즉, car의 빨간색 자동차라는 특징을 담고 있는 것이다. 하지만 우리는 빨간색 자동차 뿐 만 아니라 노란색, 초록색, 파란색 자동차도 정확히 분류하기를 원한다. 그래서 카테고리의 여러 특징들을 담기 위해서 우리는 hidden layer를 하나 더 추가하여 template를 늘려주는 방법을 생각했다.

 

 

위의 그림과 같이 2 layers Neural network를 사용하게 되면 우리가 원하는 특징을 hidden layer의 차원수만큼 늘려줄 수 있다. 예를 들어 위의 그림과 같이 hidden layer의 차원의 수가 20*1이면 최종 카테고리가 10이기 때문에 카테고리당 2개의 특징을 담는 template를 만들 수 있다는 것을 직관적으로 알 수 있다. 즉 hidden layer의 차원수를 늘려줌으로써 우리는 카테고리의 여러 특징을 담을 수 있음을 나타낸다.

 

 

W2와 h를 곱하여 최종 score 벡터를 구할 수 있다. 이 때 h는 각 template의 특징별 score이고 이를 W2 가중치에 곱하여 최종 카테고리별 score를 얻기 때문에 각 template 특징들이 최종 score에 미치는 가중치는 W2의 각 행의 가중치 값이라고 할 수 있다. 즉 W2의 가중치를 학습시킴으로써 각 특징이 최종 카테고리별 socre에 얼마나 영향을 미치는지 학습하는 것이다.

 

출처 : Stanford University School of Engineering, http://cs231n.stanford.edu/