
딥러닝을 하다 보면 affine layer를 반드시(!) 만나게 된다. Vectorized input/output에 대해 back-propagation을 처음으로 적용하게 되는 대상이기도 하다. 이 글은 딥러닝이나 affine layer의 역할을 설명하려는 것이 아니고, affine layer에서 gradient 구하는 과정을 헷갈려한 나 자신을 돌아보기 위함이 주목적이다.
두 번째 목적은 복잡한 notation을 정리하며, affine layer에서 gradient를 구하는 모든 과정을 분명하게 밝히는 것에 있다.
표기법. 모든 실수 값 (스칼라)는 italic 체로 (), 모든 벡터는 소문자 bold 체로 ( ), 행렬은 대문자 bold 체로 ( ) 로 표기한다.
Affine layer는
미분
증명을 하기에 앞서, 몇 가지 명확하게 짚고 넘어가야 할 부분들이 있다. 우선 벡터나 행렬로의 미분에 대한 정의를 분명하게 하고 넘어가야 할 것이다. 익숙한 것들부터 시작해보자.
미분가능성에 대한 가정은 모두 생략했다.
스칼라로 미분
스칼라 함수
벡터를 스칼라로 미분할 수 있다. 미적분학에서 공간의 매개화된 곡선을 공부할 때 접했던 기억이 있다.
일 때,
행렬도 스칼라로 미분할 수 있다. 미분방정식을 공부할 때 접했던 기억이 있다.
로 정의하면,
단,
스칼라 값으로 미분하는 경우는 굉장히 간단하다. 벡터나 행렬의 각 성분들을 미분하려는 변수로 각각 미분만 하면 되기 때문이다.
벡터로 미분
한 걸음 나아가, 벡터
먼저 스칼라 함수
엄청 비직관적인 정의는 아니다. 벡터의 각 성분들로 스칼라 함수를 미분하여 얻은 벡터를 생각할 수 있을 것이다.
이제 벡터
일 때,
그래도 정의를 자세히 관찰해보면 받아들일 만하다.
그런데 이제 행렬
행렬로 미분
마지막으로 한 걸음 더 나아간다. 행렬
위와 마찬가지로 스칼라 함수
이제는 행렬로 미분했더니 스칼라를 미분해도 행렬이 나오면서 상황이 복잡하다. 그래도 자세히 관찰해 보면 벡터로 미분했을 때 벡터의 각 성분으로 미분하여 벡터를 만들었던 것처럼, 행렬의 경우에도 행렬의 각 성분으로 미분하여 행렬을 만들 수 있을 것이다.
이제 벡터
또, 행렬
억지로 정의를 확장시키는 느낌이 든다면 정상이다.
참고
마찬가지로
행렬을 벡터로 미분하거나, 벡터를 행렬로 미분하거나, 행렬을 행렬로 미분하는 경우에 대해서 위키백과는 'not as widely considered and a notation is not widely agreed upon' 이라고 언급하고 있다. 그래서 이 3가지 경우는 회색 박스에 담지 않았다.
이런 게 있구나 하고 적당히 넘어가는 편이 현명한지도 모르겠다.
연쇄 법칙
두 번째로 짚고 넘어가야 할 부분은 연쇄 법칙 (chain rule)이다. Stewart Calculus 7th Ed.의 명제를 복사해 왔다.
Chain Rule (General Version). Suppose thatis a differentiable funtion of the variables and each is a differentiable function of the variables . Then is a function of and for each .
식만 복잡하지 해석해 보면 일변수에서의 연쇄 법칙과 크게 다를 바 없다. 직관적으로 설명해 보자. 현재 상황은
더불어, 스칼라로 미분하는 경우 뿐만 아니라 벡터나 행렬로 미분하는 경우에도 연쇄 법칙은 동일하게 성립한다.
증명
이제 식
이렇게 잡으면
의 증명
하나 문제가 있다면
그렇다면 행렬의 각 성분별로 따져보면 어떨까?
한편 우리는
임도 알고 있다. Index가 지나치게 많아 헷갈리지만, 조심스럽게
를 얻는다. 여기서
마지막 등호는
이제 이 식을 자세히 관찰하면,
모든
의 증명
여기서도 비슷한 이유로
이제
를 얻고
마지막 등호는
이제 이 식을 자세히 관찰하면,
모든
이제 편안하게 affine layer에서 back-propagation을 할 수 있다. 정의와 표기법, 그리고 핵심이 되는 연쇄법칙만 알고 있으면 어렵지 않게 증명할 수 있는 내용이었는데, 직관적으로 '대충 이렇게 되겠지~' 하고 넘어갔다가, 다시 자세히 증명을 하려다 보니 막상 잘 되지 않았다. 정의와 표기법이 중요하다는 사실을 다시 한 번 깨닫게 된다.
내가 보는 책에서는 이 글에서 증명한 식들을 대충 언급하고 넘어가며, 증명은 커녕 계산해야 하는 행렬들의 size를 바탕으로 식을 유추하면 결론이 나온다는 식으로 얼렁뚱땅 넘어간다. 개인적으로 굉장히 맘에 들지 않는다. 이것이 직접 증명을 시도한 이유 중 하나이기도 하다. 구현을 하거나, 실무에 활용하는 입장에서는 이론적 배경이 중요하지 않을 수 있다. 하지만, 이론적 배경을 잊어버리더라도 최소한 한 번쯤은 읽어보고 이해하고 지나가야, 더욱 근본이 탄탄한 지식을 쌓을 수 있지 않을까.
'Computer Science > Machine Learning' 카테고리의 다른 글
Autodiff with Julia (1) | 2021.03.22 |
---|---|
Autodiff 직접 구현하기 (0) | 2021.03.21 |
Derivative of log determinant (0) | 2020.08.09 |
Using different instances of activation layers in a neural network (0) | 2020.04.18 |
댓글