곱셈 노드(Multiplication Node)는 계산 그래프에서 두 값을 곱하는 노드이다.
역전파에서는 출력 쪽에서 전달된 기울기에 대해, 각 입력의 반대쪽 값을 곱해서 기울기를 전달한다.
곱셈 노드
입력이 x, y이고 출력이 z일 때, 곱셈 노드는 다음 연산을 수행한다.
z=x⋅y
순전파에서는 입력 x, y를 받아 두 값을 곱한 z를 출력한다.
(x,y)↦z
순전파
순전파는 다음과 같다.
z=x⋅y
예를 들어 x=2, y=3이면 출력은 다음과 같다.
z=2⋅3=6
즉, 곱셈 노드는 입력 두 개를 받아 하나의 출력 값을 만든다.
역전파
손실 함수를 L이라고 하자.
출력 z 쪽에서 곱셈 노드로 전달되는 기울기는 다음과 같다.
∂z∂L
곱셈 노드의 역전파에서는 이 기울기를 각 입력 방향으로 다시 전달해야 한다.
먼저 x에 대한 기울기는 다음과 같다.
∂x∂L=∂z∂L⋅y
y에 대한 기울기는 다음과 같다.
∂y∂L=∂z∂L⋅x
즉, x 방향으로는 y가 곱해지고, y 방향으로는 x가 곱해진다.
상류 Gradient와 로컬 Gradient
역전파는 기본적으로 다음 형태로 이해할 수 있다.
하류 gradient=상류 gradient×로컬 gradient
여기서 상류 gradient는 뒤쪽 노드에서 현재 노드로 전달된 기울기이다.
곱셈 노드에서는 출력 z 쪽에서 전달된 다음 값이 상류 gradient이다.
∂z∂L
로컬 gradient는 현재 노드의 출력이 각 입력에 대해 얼마나 변하는지를 나타내는 값이다.
곱셈 노드의 출력은 다음과 같다.
z=xy
따라서 각 입력에 대한 로컬 gradient는 다음과 같다.
∂x∂z=y
∂y∂z=x
결국 x 방향으로 전달되는 gradient는 다음과 같이 계산된다.
∂x∂L=상류 gradient∂z∂L×로컬 gradient∂x∂z=∂z∂L⋅y
y 방향도 마찬가지이다.
∂y∂L=상류 gradient∂z∂L×로컬 gradient∂y∂z=∂z∂L⋅x
즉, 역전파는 상류에서 흘러온 gradient에 현재 노드의 로컬 gradient를 곱해 앞쪽 노드로 전달하는 과정이다.
왜 반대쪽 입력이 곱해지는가
곱셈 노드의 출력은 다음과 같다.
z=xy
x에 대해 미분하면 다음과 같다.
∂x∂z=y
y에 대해 미분하면 다음과 같다.
∂y∂z=x
역전파에서는 연쇄 법칙을 사용한다.
따라서 x에 대한 손실의 기울기는 다음과 같다.
∂x∂L=∂z∂L∂x∂z
여기서 ∂x∂z=y이므로 다음과 같이 된다.
∂x∂L=∂z∂L⋅y
마찬가지로 y에 대해서는 다음과 같다.
∂y∂L=∂z∂L∂y∂z=∂z∂L⋅x
결국 곱셈 노드는 역전파 시 출력 쪽 기울기에 반대쪽 입력 값을 곱해 전달한다.
행렬 기반 표현
딥러닝에서는 스칼라 하나끼리 곱하는 경우보다 벡터나 행렬 단위로 계산하는 경우가 많다.
먼저 벡터 입력의 곱셈을 생각해보자.
벡터끼리 곱한다고 할 때는 보통 같은 위치의 원소끼리 곱하는 원소별 곱(element-wise product)을 의미한다.
z=x⊙y
여기서 ⊙는 원소별 곱을 의미한다.
벡터 x, y가 다음과 같다고 하자.
x=x1x2⋮xn,y=y1y2⋮yn
그러면 출력 z는 다음과 같다.
z=z1z2⋮zn=x1y1x2y2⋮xnyn
즉, 각 원소는 다음과 같이 계산된다.
zi=xiyi
스칼라 곱셈 z=xy가 각 위치마다 독립적으로 반복된다고 보면 된다.
원소별 곱의 야코비안
벡터 출력 z를 벡터 입력 x에 대해 미분하면 야코비안 행렬이 나온다.
Jz,x=∂x∂z
이 행렬의 (i,j)번째 원소는 다음 값이다.
∂xj∂zi
그런데 zi=xiyi이므로 zi는 xi에만 의존한다.
xj가 xi와 다른 원소라면 zi에는 영향을 주지 않는다.
따라서 다음이 성립한다.
∂xj∂zi={yi,0,i=ji=j
즉, x에 대한 야코비안은 대각행렬이다.
∂x∂z=y10⋮00y2⋮0⋯⋯⋱⋯00⋮yn=diag(y)
마찬가지로 y에 대한 야코비안은 다음과 같다.
∂yj∂zi={xi,0,i=ji=j
따라서,
∂y∂z=x10⋮00x2⋮0⋯⋯⋱⋯00⋮xn=diag(x)
이다.
원소별 곱의 역전파
손실 함수가 z를 통해 계산된다고 하자.
L=L(z)
출력 쪽에서 내려온 상류 gradient를 다음과 같이 둔다.
∂z∂L=∂z1∂L∂z2∂L⋮∂zn∂L
다변수 연쇄 법칙에 의해 x 방향의 gradient는 다음과 같다.
∂x∂L=(∂x∂z)T∂z∂L
여기에 앞에서 구한 야코비안을 대입하면 다음과 같다.
∂x∂L=diag(y)T∂z∂L
대각행렬은 전치해도 같으므로,
∂x∂L=diag(y)∂z∂L
이다.
원소별로 보면 다음과 같다.
∂xi∂L=∂zi∂Lyi
결국 벡터 형태로는 다음처럼 쓸 수 있다.
∂x∂L=∂z∂L⊙y
y 방향도 같은 방식이다.
∂y∂L=(∂y∂z)T∂z∂L
∂y∂L=diag(x)∂z∂L
따라서 벡터 형태로는 다음과 같다.
∂y∂L=∂z∂L⊙x
즉, 스칼라에서
dx=dz⋅y,dy=dz⋅x
였던 것이 벡터에서는 원소별로 확장된다.
dx=dz⊙y
dy=dz⊙x
곱셈 노드의 핵심은 그대로이다.
상류 gradient에 현재 노드의 로컬 gradient를 곱해 앞쪽으로 전달한다.
다만 벡터에서는 이 계산이 각 원소마다 독립적으로 일어나기 때문에, 결과가 원소별 곱 형태로 나타난다.
행렬 곱셈의 경우
원소별 곱과 달리, 일반적인 행렬 곱셈에서는 한 출력 원소가 여러 입력 원소의 합으로 만들어진다.
그래서 역전파 식도 단순한 원소별 곱이 아니라 전치 행렬을 사용한 형태로 나타난다.
예를 들어 다음과 같은 선형 변환을 생각할 수 있다.
z=Wx
이때 출력 쪽에서 전달되는 기울기를 다음과 같이 두자.
∂z∂L
그러면 입력 벡터 x에 대한 기울기는 다음과 같다.
∂x∂L=W⊤∂z∂L
가중치 행렬 W에 대한 기울기는 다음과 같다.
∂W∂L=∂z∂Lx⊤
행렬 곱셈에서도 핵심은 같다.
역전파에서는 출력의 기울기를 각 입력 방향으로 전달하되, 해당 입력이 출력에 미친 영향을 곱해서 전달한다.
요약
곱셈 노드는 순전파에서 두 입력을 곱한다.
z=x⋅y
역전파에서는 출력 쪽 기울기에 반대쪽 입력 값을 곱해 전달한다.
∂x∂L=∂z∂L⋅y
∂y∂L=∂z∂L⋅x
즉, 곱셈 노드의 역전파는 “서로의 값을 바꿔 곱해서 전달한다”고 이해할 수 있다.
#딥러닝 #딥러닝/기초/역전파