JLOG

[Cs231n 정리] Lecture 4: backpropagation and neural networks / CS231n 4강 정리 본문

Study/cs231n

[Cs231n 정리] Lecture 4: backpropagation and neural networks / CS231n 4강 정리

정정선선 2021. 3. 3. 23:48

아래 블로그의 정리글을 참고해 작성되었습니다.

꿈 많은 사람의 이야기


 

cs231n 강의를 들으면서 공부 기록용으로 작성된 글입니다.


전 시간에 Linear score function, loss function(SVM, softmax)+regularization와 optimization에 대해서 알아보았다.

 

 

Gradient descent(경사하강법)을 계산하는 방법은 Numerical gradient와 Analytic gradient가 있었고 위와 같은 특징들이 존재했다.

 

보통 gradient check를 할 때 numerical gradient를 사용한다.

 

 

지금까지 배웠던 수식을 그림으로 나타내면 위와 같다(Wx → score → loss를 얻는 과정).

이와 같은 그림을 통해 neural network의 값의 계산과 원리를 보다 쉽게 확인할 수 있다.

 

 

초록색 부분은 forward 계산 부분이고, 수식에 맞게 진행되어 -12 값을 얻을 수 있다.

gradient를 이용해 가중치를 update하기 위해

x, y, z가 f에 미치는 영향 즉, 각각의 미분 값들이 필요하다. (af/ax, af/ay, af/az)

 

 

여기서 각각의 미분 값을 구하기 위해 편미분을 이용할 수 있다.

q = x+y 에서 dq/dx = 1, dq/dy = 1을 확인할 수 있고

f = qz에서 df/dq = z, df/dz = q를 확인할 수 있다.

 

즉, 덧셈 연산에서 미분값은 1이고, 곱셈 연산에서는 서로의 값을 가지게 된다는 것이다.

 

뒤에서부터 순차적으로 영향을 미치는 정도에 대해 확인해보자

먼저 af/af은 스스로가 영향을 미치는 경우이므로 1이다.

 

 

z와 q가 f에 영향을 미치는 값을 확인해보면,

z의 경우 f에 3만큼 영향을 미치므로, af/az는 3이 될 것이고

q의 경우 f에 -4만큼 영향을 미치므로, af/aq는 -4이 될 것이다.

 

앞서 말했듯이 곱셈의 경우 자신이 아닌 다른 원소의 값이 미분 값이 된다는 것을 확인할 수 있다.

 

 

이번엔 더 앞 부분으로 가서 y와 x가 f에 얼마나 영향을 끼치는지 확인해보자

먼저 y가 f에 영향을 끼치는 정도(af/ay)는 한번에 구할 수가 없다.

그래서 chain rule이라는 기법을 사용해 y가 f에 미치는 영향을 알 수 있다.

(af/ay = af/aq*aq/ay를 이용(y가 q에 미치는 영향 * q가 f에 미치는 영향)

 

그럼 이제 y가 q에 미치는 영향을 알면 되는데 덧셈의 경우 미분 값이 1이었으므로, aq/ay이 1이고, af/ay는 -4라는 것을 확인할 수 있다.

 

 

af/ax의 값도 위와 마찬가지로 구할 수 있다.

 

 

 

az/ax, az/ay 미리 구할 수 있는 gradient 값을 local gradient라고 한다.

이 local gradient 값과 뒤에서 넘어온 global gradient를 이용해 gradient를 계산할 수 있다.

 

 

앞서 직접 계산한 과정을 나타낸 것이다.

 

 

이 와 같은 과정을 맨 앞의 레이어가 될 때까지 순차적으로 곱하며 진행하게 되며 모든 node에 대한 gradient 값을 찾아나갈 수 있다.

 

 

 

 

Example) sigmoid가 포함된 layer의 gradient 계산

미리 계산하기 편하도록 각 식의 미분을 밑에 계산해 두었다.

 

 

맨 처음의 gradient 값은 나 자신임으로 1인 것을 확인할 수 있다.

 

 

1/x에 관한 미분식은 -1/x^2이고 해당 x 값인 1.37을 식에 넣으면, -0.53의 값이 gradient로 나오는 것을 확인할 수 있다.

 

 

 

상수를 더한 경우 미분식은 1이 되어 local gradient는 1이고 뒤의 global gradient 값과 곱해주면 -0.53가 나오는 것을 확인할 수 있다.

 

 

위와 같은 방법으로 해당 식을 이용해 local gradient 값을 구하고 global gradient 값을 곱해주면 해당 gradient를 구할 수 있다.

위와 같이 쭉 간편하게 구할 수 있다.

 

 

 

앞서 이렇게 차근차근 local gradient를 이용해 구한 방법 말고도, sigmoid gate의 gradient는 sigmoid의 미분식을 구해 한번에 gradient 값을 얻을 수 있다.

 

 

위와 같이 sigmoid 식 자체를 미분 할 수 있는데, 이 값에 바로 sigmoid의 output을 넣어 sigmoid gate의 input node의 gradient를 바로 구할 수 있다.

 

 

Patterns in backward flow

각 gate를 보면 local gradient를 알 수 있다.

add의 경우 local gradient는 1이고,

max의 경우 작은 값의 경우 0, 가장 큰 값의 경우는 2

mul의 경우 서로의 인풋 값을 교환한 것이 gradient이다.

 

 

 

만약 앞에서 복수의 gradient를 가지면 간단히 더해주면 된다.

 

 

 

Vectorized gradient

각 gradient 값들은 하나가 아니라 다변수일 확률이 높다. 그럴 때는 자코비안 행렬 방식으로 되게 된다.

자코비안 행렬 : 다변수 함수일 때의 미분 값

 

 

 

 

앞서 말한 자코비안 행렬의 크기를 알아보자

input과 output이 모두 4096 크기이므로 자코비안 행렬의 크기는 4096x4096이 될 것이다.

 

 

 

이때 만약 100개의 mini batch를 사용한다고 하면 409,600 x 409,600 값이 될 것이다.

이렇게 거대한 크기의 행렬을 실제로는 계산하지 않고, elementwise(요소별)로 보기 때문에 입력의 각 요소가 해당 출력의 요소에만 영향을 주기 때문에, 자코비안 행렬은 대각행렬의 형태로 나타나게 된다.

 

실제로는 자코비안 행렬을 구하지 않고 L에 대한 x의 영향을 사용한다고 한다..?

(메모 : 자코비안 행렬이 잘 이해가 되지 않는다

+자코비안행렬 : https://angeloyeo.github.io/2020/07/24/Jacobian.html)

 

 

 

score를 구한 후 L2를 계산하는 함수이다.

각 값에 맞는 벡터 연산을 진행하면 L2의 값이 0.116이 나오는 것을 확인할 수 있다.

 

 

 

gradient를 구해보면, 처음 gradient는 1이고,

f(q) = llqll^2 이므로 미분 식은 2q가 나오는 것을 확인할 수 있다.

그래서 다음의 gradient는 [0.22 0.26] * 2인 [0.44 0.52]가 된다.

 

 

 

dqk/dWij의 식을 보면 1k=i xj로 나타나져 있다. 이 것의 의미는 각 행의 연산 시 다른 행은 관여하면 안되기 때문이다.

 

dqk/dWij과 chain rule을 이용해 df/dWij를 구할 수 있다. 2qixj가 된다.

(2 위에 붙은 k는 윗줄 sigma의 부분인 것 같다.)

 

 

 

위 식을 벡터화 된 형식으로 작성하기 위하여 xt하여 곱해준다.

이 때, 중요한 것은 gradient와 변수의 shape이 동일한지 항상 확인해주어야 한다.

 

 

마찬가지로 x의 gradient를 구하기 위해 위와 같은 과정을 한번 더 거친다.

위와 같이 W를 t해서 사용하는 것을 확인할 수 있다.

 

(메모 : 왜 gradient 식이 2Wtq, 2qxt와 같이 상대의 변수의 위치가 달라질까?

그 이유는 단순히 shape을 맞추기 위해서인가?)

 

 

 

 

 

위의 슬라이드들은 앞서 배운 forward, backward를 코드로 나타낸 것이다. 이 때 눈 여겨 봐야하는 것은 x,y,z가 scalar이기 때문에 backward를 구할 때 전치를 시켜주지 않고 간단히 곱해준 것을 확인할 수 있다.

 

 

 

첫 번째 과제에 대한 내용이고, 추후에 과제 풀이에 대해서 작성하겠다.

 

 

 

 

 

Neural Networks

지금까지는 Linear score function(선형) 사용했지만,

max함수를 이용해 함수를 비선형으로 만듬으로서 2개의 layer를 쌓을 수 있다.

이 때 max(0, W1x)는 Relu라는 activation function이다.

 

 

전에 사용했던 함수보다 더 복잡한 구조(식)를 가짐으로서 더 자세하게 분류할 수 있을 것이다.

 

 

2-layer말고도 3-layer, n-layer...로 더 깊게 쌓을 수 있다.

 

 

2-layer를 코드로 구현한 모습이다.

아래와 같이 차근차근 식을 쓰며 확인해 보았다.

 

 

 

과제 2번에 대한 슬라이드이다. 2-layer net에 대하여 code를 작성하는 것이다.

 

 

 

 

실제 뉴런은 자극(input)이 cell body로 들어오면 axon을 걸쳐 다른 뉴런으로 들어가게 된다.

우리가 배운 구조인 input이 w와의 연산을 걸쳐 output이 되는 것과 유사한 것을 확인할 수 있다.

 

또한 실제 뉴런은 역치 이상의 자극이 들어오면 신경 전달 물질을 전달한다.

이와 같이 기준치 이상의 입력을 넘겨주는 역할을 하는 것은 activation function이고 sigmoid와 같은 것이 될 것이다.

 

 

코드로 작성하면 위와 같이 될 것이다.

+참고 : firing rate : axon으로 넘겨주게 되는 비율(역치 이상의 input의 비율)이라고 생각할 수 있다.

 

 

하지만 위와 같은 요소 때문에 실제 nueral의 동작과 code의 동작은 완전히 같다고 보기에는 어렵다.

 

 

 

지금까지 sigmoid를 사용했지만 다양한 activation function이 존재하고 추후에 하나하나 공부할 것이다.

 

 

 

fully connected network(fc)

위 사진과 같이 하나의 연결도 빠지지 않고 완전히 연결 되어 있는 네트워크를 fully connected(fc)라고 한다.

 

feed-forward network는 순방향 신경망으로서 노드 간의 연결이 순환을 형성하지 않는 인공 신경망이다.

위의 슬라이드는 feed-forward network의 forward 부분을 code로 나타낸 것이다.

 

 

 

 

Comments