English ver.

Interactive Calculus

Date: |Estimated Reading Time: 33 min|Author: Seungheon Doh

참고: angeloyeo.github.io의 그래디언트·발산·다중적분 편, 그리고 Najeeb Khan, Vector Calculus. 이 글은 Interactive Linear AlgebraInteractive Probability에 이어지며, 다음 글 Interactive Differential Equations의 준비편입니다.

선형대수는 데이터를 표현하는 언어였고, 확률은 불확실성을 다루는 언어였습니다. 그런데 두 글 모두 한 가지를 당연한 듯 사용했습니다 — "손실을 최소화한다"는 말입니다. 파라미터를 어느 방향으로 얼마나 움직여야 손실이 줄어드는지, 그 질문에 답하는 언어가 미적분입니다.

미적분의 핵심 발상은 하나입니다. 충분히 가까이서 보면 모든 매끄러운 것은 직선이다. 곡선도, 곡면도, 수억 개의 파라미터를 가진 신경망도 한 점 근처에서는 선형 함수로 근사됩니다. 미분은 그 국소적인 직선의 기울기이고, 적분은 그렇게 쪼갠 조각들을 다시 합치는 연산입니다. 신경망의 학습이 결국 "지금 위치에서의 선형 근사를 보고 한 걸음 내딛는 일"의 반복인 이유가 여기 있습니다.

그래서 이 글의 두 번째 축은 선형대수와의 재회입니다. 다변수 함수에서 미분은 더 이상 하나의 수가 아니라 벡터(그래디언트)가 되고, 벡터함수의 미분은 행렬(야코비안)이 되며, 이차 근사의 계수는 대칭행렬(헤시안)이 됩니다. 앞 글에서 배운 고유값과 고유벡터가 손실 지형의 곡률을 읽는 도구로 그대로 돌아옵니다.

이 글은 함수와 극한에서 시작해 미분·연쇄법칙·테일러 전개·적분을 거쳐, 편미분·그래디언트·야코비안·헤시안·벡터장·발산·라플라시안으로 이어집니다. 뒤쪽 절반은 다음 글에서 다룰 미분방정식 — 그리고 최종적으로는 확산 모델 — 을 읽기 위한 어휘이기도 합니다.

함수 Functions

머신러닝 모델은 결국 함수다. 입력을 받아 출력을 내놓는 규칙이며, 학습이란 그 규칙을 지배하는 파라미터를 고르는 일이다. 함수를 어떻게 바라보느냐가 이후 모든 논의의 출발점이 된다.

정의. 함수 \(f:X\to Y\)는 정의역 \(X\)의 각 원소에 공역 \(Y\)의 원소를 정확히 하나씩 대응시키는 규칙이다. "하나씩"이라는 조건이 핵심이다 — 같은 입력에 두 값이 대응하면 함수가 아니다.

모델은 함수다, 두 가지 의미로. 신경망 \(f_\theta(x)\)는 입력 \(x\)에 대한 함수인 동시에 파라미터 \(\theta\)에 대한 함수이기도 하다. 추론할 때는 \(\theta\)를 고정하고 \(x\)를 변수로 보고, 학습할 때는 \(x\)를 고정하고 \(\theta\)를 변수로 본다. 같은 식을 어느 쪽 변수로 보느냐에 따라 전혀 다른 일을 한다는 이 구조는 확률 글의 "확률 vs 가능도"와 정확히 같은 종류의 시점 전환이다.

합성이 전부다. 딥러닝의 "딥"은 합성의 깊이를 뜻한다. \(f = f_L\circ\cdots\circ f_2\circ f_1\)처럼 단순한 함수를 겹겹이 쌓아 복잡한 함수를 만든다. 각 층이 선형변환과 비선형 활성함수의 조합인데, 비선형이 하나라도 빠지면 아무리 깊게 쌓아도 전체가 하나의 선형변환으로 붕괴한다.

매끄러움이 필요한 이유. 경사하강법은 함수가 미분 가능해야 작동한다. 그래서 딥러닝에서 쓰는 함수는 거의 모두 연속이고 (거의 어디서나) 미분 가능하다. ReLU처럼 한 점에서 꺾이는 함수도 쓰이지만, 그 한 점을 제외하면 매끄럽기 때문에 실무에서 문제가 되지 않는다.

\[\begin{aligned} f &: X \to Y \\ (g\circ f)(x) &= g(f(x)) \\ f_\theta &: \mathbb{R}^{d} \to \mathbb{R}^{k} \quad \text{(모델)} \end{aligned}\]

함수를 골라 파라미터를 움직여보세요. 같은 식이라도 어떤 변수를 움직이느냐에 따라 그래프가 다르게 반응합니다. 합성 모드를 켜면 f(x)와 g(f(x))가 함께 그려져, 함수를 겹칠 때 모양이 어떻게 변형되는지 볼 수 있습니다.

극한 Limits

미분과 적분은 모두 "무한히 잘게 쪼갠다"는 조작 위에 세워진다. 그 조작을 엄밀하게 만드는 장치가 극한이며, 0으로 나누는 일을 하지 않고도 순간의 기울기를 말할 수 있게 해준다.

정의. \(\lim_{x\to a}f(x)=L\)이라는 것은, \(x\)를 \(a\)에 충분히 가깝게(단, \(x\ne a\)) 가져가면 \(f(x)\)를 \(L\)에 원하는 만큼 가깝게 만들 수 있다는 뜻이다. \(x=a\)에서 함수가 어떤 값을 갖는지, 심지어 정의되어 있는지조차 극한과는 무관하다.

왜 이 우회가 필요한가. 기울기는 \(\frac{\Delta y}{\Delta x}\)인데, "한 점에서의" 기울기를 구하려면 \(\Delta x=0\)이어야 하고 그러면 \(0/0\)이 된다. 극한은 이 막다른 길을 피한다 — \(\Delta x\)를 0으로 보내되 결코 0으로 두지는 않는다. 오른쪽에서 \(h\)를 줄여보면 할선의 기울기가 어떤 값으로 다가가는 것이 보이는데, 그 값이 접선의 기울기다.

연속성. \(\lim_{x\to a}f(x)=f(a)\)일 때 함수가 \(a\)에서 연속이라 한다. 즉 극한값과 함숫값이 일치한다는 뜻이다. 연속이 아니면 미분도 불가능하지만, 연속이라고 해서 반드시 미분 가능한 것은 아니다 — \(|x|\)는 원점에서 연속이지만 좌우에서 다가가는 기울기가 \(-1\)과 \(+1\)로 달라 미분이 안 된다.

머신러닝에서. 극한은 학습의 수렴을 이야기할 때 등장한다. "학습률을 0으로 보내면 SGD가 경사흐름(gradient flow)이라는 미분방정식에 수렴한다"는 서술이 그 예이며, 다음 글의 출발점이기도 하다. 수치적으로도 중요하다 — 자동미분이 아니라 유한차분으로 기울기를 근사할 때, \(h\)를 너무 크게 잡으면 근사 오차가 크고 너무 작게 잡으면 부동소수점 반올림 오차가 지배한다.

\[\begin{aligned} \lim_{x\to a} f(x) &= L \\ f'(a) &= \lim_{h\to 0}\frac{f(a+h)-f(a)}{h} \\ \text{연속} &\iff \lim_{x\to a}f(x) = f(a) \end{aligned}\]

h 슬라이더를 크게 잡았다가 줄여보세요. 두 점을 잇는 할선(주황)이 접선(초록)에 점점 겹쳐집니다. 리드아웃의 할선 기울기가 참 도함수 값으로 수렴하는 과정, 그리고 h가 극단적으로 작아지면 오히려 수치 오차가 커지는 현상도 확인할 수 있습니다.

미분 Derivatives

도함수는 한 점에서의 순간 변화율이자, 그 점 근처에서 함수를 가장 잘 흉내 내는 직선의 기울기다. 경사하강법이 매 걸음 참조하는 정보가 정확히 이것이다.

정의. \(f'(a)=\lim_{h\to 0}\frac{f(a+h)-f(a)}{h}\). 이 극한이 존재하면 \(f\)가 \(a\)에서 미분 가능하다고 한다. \(\frac{df}{dx}\), \(\dot{f}\), \(Df\) 등 표기는 여럿이지만 뜻은 같다.

기하적으로: 접선. \(f'(a)\)는 점 \((a,f(a))\)에서 그래프에 접하는 직선의 기울기다. 그 접선 \(y=f(a)+f'(a)(x-a)\)는 \(a\) 근처에서 \(f\)를 가장 잘 근사하는 일차함수이며, 이것이 다음다음 절 테일러 전개의 1차 항이다.

부호와 크기가 말하는 것. \(f'>0\)이면 증가, \(f'<0\)이면 감소, \(f'=0\)이면 정체(임계점)다. 절댓값이 클수록 가파르다. 최소화 문제에서 우리는 \(f'\)의 반대 방향으로 움직인다 — 그것이 \(\theta \leftarrow \theta - \eta f'(\theta)\), 즉 경사하강법이다. 오른쪽 아래 도함수 그래프에서 원 함수의 봉우리와 골짜기가 정확히 \(f'=0\)인 지점과 맞물리는 것을 볼 수 있다.

임계점이 최소점은 아니다. \(f'=0\)은 최소·최대·안장점 어디에서나 성립한다. 어느 쪽인지 가르려면 2차 정보가 필요하며, 그것이 헤시안 절의 주제다. 고차원 손실 지형에서는 국소 최소점보다 안장점이 훨씬 흔하다는 것이 알려져 있고, 이 사실이 최적화 알고리즘 설계에 직접 영향을 준다.

자동미분. PyTorch가 하는 일은 유한차분이 아니다. 기본 연산마다 도함수 규칙을 알고 있고, 계산 그래프를 따라 연쇄법칙을 기계적으로 적용한다. 그래서 오차가 수치 근사 수준이 아니라 기계 정밀도 수준이며, 수억 개 파라미터에 대해서도 한 번의 역방향 순회로 모든 편미분을 얻는다.

\[\begin{aligned} f'(a) &= \lim_{h\to 0}\frac{f(a+h)-f(a)}{h} \\ y &= f(a) + f'(a)(x-a) \quad \text{(접선)} \\ \theta &\leftarrow \theta - \eta\, f'(\theta) \quad \text{(경사하강)} \end{aligned}\]

점 a를 드래그해보세요. 위 그래프에 접선이 그려지고, 아래 도함수 그래프에 해당 지점의 값이 표시됩니다. 원 함수가 평평해지는 곳에서 도함수가 0을 지나는 대응 관계를 확인해보세요. "경사하강 한 걸음" 버튼으로 실제로 최소점을 향해 내려가는 과정을 볼 수 있습니다.

도함수 f′(x) — 원 함수가 평평한 곳에서 0을 지난다

연쇄법칙 Chain Rule

합성함수의 미분은 각 단계 미분의 곱이다. 이 한 줄의 규칙이 수백 층 신경망의 모든 파라미터에 대한 기울기를 계산 가능하게 만든다 — 역전파는 연쇄법칙의 구현일 뿐이다.

정의. \(y=g(f(x))\)일 때 \(\frac{dy}{dx}=g'(f(x))\cdot f'(x)\)다. 라이프니츠 표기로 쓰면 \(u=f(x)\)에 대해 \(\frac{dy}{dx}=\frac{dy}{du}\cdot\frac{du}{dx}\)로, 마치 분수가 약분되는 것처럼 보이는 형태가 된다.

직관: 변화율의 증폭. \(x\)가 1만큼 움직이면 \(u\)는 \(f'(x)\)만큼 움직이고, \(u\)가 그만큼 움직이면 \(y\)는 다시 \(g'(u)\)배로 움직인다. 기어비를 연달아 물린 것과 같아서, 전체 비율은 각 단계 비율의 이다.

역전파가 정확히 이것이다. \(L = \ell(f_L(\cdots f_1(x)))\)에서 \(\theta_k\)에 대한 기울기는 \(k\)층부터 출력까지의 도함수를 모두 곱한 값이다. 순방향으로 각 층의 국소 도함수를 저장해두고, 역방향으로 한 번 훑으며 곱해 나가면 모든 층의 기울기가 한 번의 순회로 얻어진다. 층마다 따로 계산하면 \(O(L^2)\)일 일이 \(O(L)\)이 되는 것이다.

기울기 소실과 폭발. 곱이라는 사실에는 대가가 있다. 각 단계의 도함수가 평균적으로 0.5라면 20층 뒤에는 \(0.5^{20}\approx 10^{-6}\)으로 사라지고, 1.5라면 \(1.5^{20}\approx 3300\)으로 폭발한다. 시그모이드의 최대 기울기가 0.25라는 사실이 초기 심층망 학습을 가로막았고, ReLU(양수 영역 기울기 1)·잔차연결(항등 경로로 기울기 1을 보존)·정규화가 모두 이 곱을 1 근처로 유지하려는 장치다.

다변수로의 확장. 입력과 출력이 벡터면 각 단계의 도함수는 수가 아니라 야코비안 행렬이 되고, 연쇄법칙은 행렬곱이 된다: \(J_{g\circ f}=J_g\,J_f\). 역전파가 실제로 하는 일은 이 행렬들을 곱하는 것이되, 행렬을 만들지 않고 벡터-야코비안 곱(VJP)만 계산해 메모리를 아끼는 것이다.

\[\begin{aligned} \frac{dy}{dx} &= \frac{dy}{du}\cdot\frac{du}{dx} = g'(f(x))\,f'(x) \\ \frac{\partial L}{\partial \theta_k} &= \frac{\partial L}{\partial h_L}\prod_{i=k+1}^{L}\frac{\partial h_i}{\partial h_{i-1}}\cdot\frac{\partial h_k}{\partial \theta_k} \\ J_{g\circ f} &= J_g\, J_f \end{aligned}\]

각 층의 기울기 배율을 슬라이더로 조절하며 층 수를 늘려보세요. 배율이 1보다 작으면 누적 기울기가 급격히 0으로 사라지고, 1보다 크면 폭발합니다. 1 근처에서만 깊은 망이 학습 가능한 범위에 머문다는 것 — 이것이 ResNet과 정규화 기법들이 존재하는 이유입니다.

합성 g(f(x))의 접선 기울기 = 각 단계 기울기의 곱

테일러 전개 Taylor Expansion

한 점에서의 도함수들만 알면 그 근처의 함수 전체를 다항식으로 재구성할 수 있다. 최적화 알고리즘은 예외 없이 이 근사 위에서 설계된다 — 경사하강은 1차 근사를, 뉴턴법은 2차 근사를 신뢰하는 방법이다.

정의. \(a\) 근처에서 \(f(x)\approx \sum_{n=0}^{N}\frac{f^{(n)}(a)}{n!}(x-a)^n\). \(N=1\)이면 접선이고, \(N=2\)면 접하는 포물선이며, \(N\)을 키울수록(수렴 반경 안에서는) 원 함수에 가까워진다.

왜 \(n!\)로 나누는가. \((x-a)^n\)을 \(n\)번 미분하면 \(n!\)이 튀어나온다. 그것을 미리 나눠두어야 \(x=a\)에서 \(n\)차 계수가 정확히 \(f^{(n)}(a)\)와 맞아떨어진다. 즉 테일러 다항식은 \(a\)에서 \(N\)차 도함수까지 원 함수와 완전히 일치하도록 설계된 다항식이다.

경사하강 = 1차 근사를 믿는 것. \(f(\theta+\Delta)\approx f(\theta)+f'(\theta)\Delta\)에서 손실을 줄이려면 \(\Delta\)를 \(f'\)의 반대 부호로 두면 된다. 그런데 1차 근사는 \(\theta\) 근처에서만 유효하므로 한 번에 크게 움직일 수 없다 — 학습률이 존재하는 이유가 정확히 이것이다. 학습률은 "이 선형 근사를 어디까지 믿을 것인가"를 정하는 값이다.

뉴턴법 = 2차 근사를 믿는 것. \(f(\theta+\Delta)\approx f+f'\Delta+\tfrac{1}{2}f''\Delta^2\)를 \(\Delta\)에 대해 최소화하면 \(\Delta=-f'/f''\)가 나온다. 학습률을 고를 필요 없이 곡률이 보폭을 정해준다 — 평평한 곳(작은 \(f''\))에서는 크게, 가파른 곳에서는 작게. 다변수에서는 \(f''\)가 헤시안 행렬이 되고, 그 역행렬을 구하는 비용 때문에 딥러닝에서는 근사 기법(L-BFGS, Adam의 대각 근사 등)을 쓴다.

어디서나 통하지는 않는다. 테일러 전개는 국소적 근사다. \(a\)에서 멀어지면 급격히 어긋나고, 함수에 따라서는 수렴 반경 자체가 유한하다. 오른쪽에서 전개점을 옮겨보면 근사가 잘 맞는 구간이 그 점을 따라 이동하는 것을 볼 수 있다.

\[\begin{aligned} f(x) &\approx \sum_{n=0}^{N}\frac{f^{(n)}(a)}{n!}(x-a)^n \\ \Delta_{\text{GD}} &= -\eta\, f'(\theta) &&\text{(1차)} \\ \Delta_{\text{Newton}} &= -\frac{f'(\theta)}{f''(\theta)} &&\text{(2차)} \end{aligned}\]

차수 N을 0부터 올려보세요. 상수 → 접선 → 포물선 → … 순으로 근사가 원 함수를 감싸 갑니다. 전개점 a를 드래그하면 잘 맞는 구간이 함께 따라옵니다. 리드아웃의 오차를 보면 a에서 멀어질수록 얼마나 빨리 무너지는지 알 수 있습니다.

적분 Integrals

미분이 쪼개는 연산이라면 적분은 합치는 연산이다. 확률의 기대값과 정규화 상수, 그리고 다음 글의 확률밀도 흐름이 모두 적분의 언어로 쓰인다.

정의 (정적분). \(\int_a^b f(x)\,dx\)는 구간을 잘게 쪼개 만든 직사각형 넓이의 합의 극한, 즉 리만 합의 극한이다. 기하적으로는 \(x\)축과 곡선 사이의 부호 있는 넓이다 — 곡선이 축 아래에 있으면 음수로 센다.

미적분학의 기본정리. 미분과 적분은 서로의 역연산이다. \(F(x)=\int_a^x f(t)\,dt\)로 정의하면 \(F'(x)=f(x)\)이고, 따라서 \(\int_a^b f = F(b)-F(a)\)가 된다. 넓이를 구하는 문제와 기울기를 구하는 문제가 같은 문제였다는 이 발견이 미적분학의 심장이다. 오른쪽 아래 누적 곡선이 위 곡선의 부호에 따라 오르내리는 것이 이 정리를 그대로 보여준다.

왜 넓이와 기울기가 서로의 역연산인가. 이 정리는 증명을 따라가기 전에 그림 하나로 납득할 수 있다. \(F(x)=\int_a^x f\)를 "지금까지 쌓인 넓이"라고 읽자. \(x\)를 아주 조금 \(dx\)만큼 늘리면 넓이는 얼마나 늘어나는가? 새로 추가되는 조각은 폭이 \(dx\), 높이가 \(f(x)\)인 가느다란 직사각형이므로 \(dF\approx f(x)\,dx\)이고, 양변을 \(dx\)로 나누면 \(F'(x)=f(x)\)다. 즉 누적된 양이 자라는 속도는 지금 이 순간 쌓이고 있는 높이 그 자체다. 저수지에 물이 차오르는 속도가 곧 지금 수도꼭지에서 나오는 유량인 것과 같다 — 그래서 "쌓기"와 "속도 재기"가 서로를 되돌린다.

그래서 \(F(b)-F(a)\)인 것도 당연하다. 구간을 잘게 쪼개 각 조각에서 늘어난 넓이 \(dF\)를 전부 더하면 중간 항들이 망원경처럼 상쇄되고 처음과 끝만 남는다. 저수지 비유로는 "구간 내내 흘러든 총량 = 마지막 수위 − 처음 수위"다. 적분을 계산할 때 원시함수를 찾아 양 끝에서 빼는 익숙한 절차는, 넓이를 직접 세는 대신 누적량의 시작과 끝만 확인하는 지름길인 셈이다.

머신러닝에서: 대부분 계산할 수 없다. 기대값 \(\mathbb{E}[f(X)]=\int f(x)p(x)\,dx\), 주변화 \(p(x)=\int p(x,z)\,dz\), 베이즈 정리의 증거항이 모두 적분이다. 그런데 고차원에서 이 적분들은 거의 언제나 닫힌 형태로 풀리지 않는다. 그래서 실무의 표준 대응이 두 가지다 — 몬테카를로(표본평균으로 근사)와 변분추론(계산 가능한 하한으로 교체, 즉 ELBO).

수치적분. 저차원에서는 직접 계산할 수 있다. 사다리꼴 규칙은 구간마다 직선으로, 심슨 규칙은 포물선으로 근사하는데, 후자가 훨씬 빠르게 수렴한다(오차가 \(O(h^4)\) 대 \(O(h^2)\)). 하지만 차원이 오르면 격자점 수가 지수적으로 늘어 쓸 수 없게 되고 — 이것이 몬테카를로가 고차원에서 이기는 이유다.

\[\begin{aligned} \int_a^b f(x)\,dx &= \lim_{n\to\infty}\sum_{i=1}^{n} f(x_i)\,\Delta x \\ \frac{d}{dx}\int_a^x f(t)\,dt &= f(x) \quad \text{(기본정리)} \\ \mathbb{E}_p[f(X)] &= \int f(x)p(x)\,dx \approx \frac{1}{N}\sum_i f(x^{(i)}) \end{aligned}\]

적분 구간의 양 끝을 슬라이더로 옮기고, 분할 수 n을 조절해보세요. 직사각형의 합이 참값에 수렴하는 과정과, 곡선이 축 아래로 내려간 구간이 넓이를 깎아내는 것을 볼 수 있습니다. 아래 누적 곡선의 기울기가 위 곡선의 값과 일치한다는 점이 기본정리입니다.

누적 F(x) = ∫f — 이 곡선의 기울기가 위 곡선의 값이다

다중적분 — 넓이에서 부피로

정의. 이변수 함수의 이중적분 \(\iint_A f(x,y)\,dA\)는 영역 \(A\)를 작은 직사각형으로 쪼개 각각에 \(f(x,y)\,\Delta x\,\Delta y\)라는 기둥의 부피를 얹고 모두 더한 극한이다. 일변수에서 "직사각형을 모아 넓이"였던 것이, 여기서는 "직육면체를 모아 부피"가 된다.

계산은 결국 일변수 적분의 반복이다. 푸비니 정리에 따라 이중적분은 안쪽부터 차례로 적분하는 반복적분으로 계산된다. \(y\)를 먼저 적분하면 각 \(x\)마다 세로 단면의 넓이 \(A(x)=\int f(x,y)\,dy\)가 나오고, 그 단면 넓이를 \(x\)에 대해 다시 적분하면 부피가 된다 — 빵을 얇게 썰어 각 조각의 넓이를 구한 뒤 두께를 곱해 더하는 것과 같다. 오른쪽에서 적분 순서를 바꿔봐도 최종 값이 같다는 점을 확인할 수 있다.

영역이 직사각형이 아닐 때. 안쪽 적분의 상하한이 바깥 변수의 함수가 된다. 예를 들어 \(x\in[0,1]\)이고 각 \(x\)마다 \(y\)가 0부터 \(2-2x\)까지라면 \(\int_0^1\!\!\int_0^{2-2x} f\,dy\,dx\)로 쓴다. 이때 적분 순서를 바꾸려면 상하한을 다시 유도해야 하며, 한쪽 순서로는 풀리지 않던 적분이 다른 순서에서는 쉽게 풀리는 일이 흔하다.

머신러닝에서. 결합분포의 전체 적분이 1이라는 조건, 주변화 \(p(x)=\int p(x,y)\,dy\), 그리고 기대값이 모두 다중적분이다. 주변화가 "한 축 방향으로 눌러 납작하게 만드는 연산"이라는 확률 글의 서술이, 여기서는 안쪽 적분 한 번이라는 구체적인 계산으로 정체를 드러낸다. 차원이 오르면 이 격자 계산이 지수적으로 비싸져 몬테카를로로 갈아타야 한다는 점도 앞서 본 그대로다.

\[\begin{aligned} \iint_A f(x,y)\,dA &= \int_a^b\!\!\left[\int_{y_1(x)}^{y_2(x)} f(x,y)\,dy\right]dx \\ &= \int_c^d\!\!\left[\int_{x_1(y)}^{x_2(y)} f(x,y)\,dx\right]dy \\ p(x) &= \int p(x,y)\,dy \quad \text{(주변화 = 안쪽 적분)} \end{aligned}\]

슬라이스 위치를 움직이면 그 자리의 단면이 아래 그래프에 그려지고, 그 단면의 넓이가 표시됩니다. 이 넓이들을 모아 더한 것이 전체 부피입니다. 적분 순서를 바꿔도 같은 값이 나온다는 점을 확인해보세요.

그 자리의 단면 f(x, ·) — 이 넓이를 모아 더하면 부피

편미분 Partial Derivatives

변수가 여럿일 때는 "어느 방향으로의 변화율인가"를 먼저 정해야 한다. 나머지를 붙잡아 두고 하나만 흔드는 것이 편미분이며, 신경망의 각 파라미터가 받는 기울기가 정확히 이 값이다.

정의. \(\frac{\partial f}{\partial x}(a,b)=\lim_{h\to 0}\frac{f(a+h,b)-f(a,b)}{h}\). 다른 변수를 상수 취급하고 한 변수에 대해서만 미분한다. 기호가 \(d\)가 아니라 \(\partial\)인 것은 "다른 변수가 있지만 지금은 고정했다"는 표시다.

기하적으로: 단면의 기울기. 2변수 함수의 그래프는 곡면이다. \(y=b\)로 자르면 곡면이 하나의 곡선으로 잘리는데, 그 곡선의 기울기가 \(\partial f/\partial x\)다. \(x=a\)로 자르면 다른 곡선이 나오고 그 기울기가 \(\partial f/\partial y\)다. 같은 점에서도 어느 방향으로 자르느냐에 따라 기울기가 다르다는 것이 다변수 미분의 출발점이다.

방향도함수로의 일반화. 좌표축 방향만 특별할 이유는 없다. 임의의 단위벡터 \(u\) 방향의 변화율은 \(D_u f = \nabla f\cdot u\)이며, 편미분은 \(u\)가 \(e_1, e_2\)일 때의 특수한 경우다. 이 식이 다음 절 그래디언트의 의미를 결정한다.

머신러닝에서. 손실 \(L(\theta_1,\ldots,\theta_d)\)에서 각 파라미터가 받는 기울기가 \(\partial L/\partial \theta_i\)다. 수억 개 파라미터라면 수억 개의 편미분이 필요한데, 하나씩 유한차분으로 구하면 순전파를 수억 번 해야 한다. 역전파가 이것을 단 한 번의 역방향 순회로 해결한다는 점이 딥러닝을 계산 가능하게 만든 결정적 사실이다.

\[\begin{aligned} \frac{\partial f}{\partial x}(a,b) &= \lim_{h\to 0}\frac{f(a+h,b)-f(a,b)}{h} \\ D_u f &= \nabla f \cdot u, \quad \|u\|=1 \\ \frac{\partial L}{\partial \theta_i} &\;\; i=1,\ldots,d \end{aligned}\]

등고선 위의 점을 드래그해보세요. 위 그림에 두 축 방향의 단면 기울기가 화살표로 표시되고, 아래 두 그래프에 각 방향으로 자른 단면 곡선과 그 접선이 그려집니다. 같은 점인데도 x 방향과 y 방향의 기울기가 전혀 다를 수 있다는 점을 확인해보세요.

그래디언트 Gradient

편미분들을 하나의 벡터로 모으면 특별한 성질을 갖는 대상이 된다. 그것은 함수가 가장 가파르게 증가하는 방향을 가리키며, 등고선과 항상 직교한다.

정의. \(\nabla f = \left(\frac{\partial f}{\partial x_1},\ldots,\frac{\partial f}{\partial x_d}\right)\). 스칼라 함수의 모든 편미분을 성분으로 갖는 벡터이며, 입력과 같은 차원에 산다.

왜 최급상승 방향인가. 방향도함수 \(D_u f=\nabla f\cdot u\)를 \(\|u\|=1\)인 \(u\)에 대해 최대로 만드는 문제다. 내적은 \(\nabla f\cdot u=\|\nabla f\|\cos\theta\)이므로 \(\theta=0\), 즉 \(u\)가 \(\nabla f\)와 같은 방향일 때 최대가 된다. 그러니 가장 빠르게 줄이려면 \(-\nabla f\) 방향으로 가야 하고, 이것이 경사하강법이다. 선형대수의 내적 한 줄이 최적화의 기본 방향을 정해준다.

등고선과 직교한다. 등고선을 따라 움직이면 함숫값이 변하지 않으므로 그 방향의 방향도함수가 0이고, 곧 \(\nabla f\cdot u=0\)이다. 즉 그래디언트는 등고선에 언제나 수직이다. 오른쪽에서 점을 옮겨보면 화살표가 항상 등고선을 가로지르는 방향을 향한다.

그래디언트는 "방향"이지 "목적지"가 아니다. \(-\nabla f\)는 현재 위치에서 가장 가파른 방향일 뿐, 최소점을 향한 방향이 아니다. 길쭉한 골짜기 지형에서는 그래디언트가 골짜기 벽을 향해 지그재그로 튕기며 바닥을 따라 내려가지 못한다. 모멘텀, Adam, 그리고 2차 방법들이 모두 이 결함을 보정하려는 시도다 — 오른쪽에서 지형을 길쭉하게 만들면 그 지그재그를 직접 볼 수 있다.

표기 주의. \(\nabla f\)는 스칼라 함수에만 정의된다. 출력이 벡터인 함수의 미분은 그래디언트가 아니라 다음 절의 야코비안 행렬이다. 신경망의 손실은 스칼라라서 \(\nabla_\theta L\)이 잘 정의되고, 그래서 학습이 벡터 하나를 따라가는 문제가 된다.

\[\begin{aligned} \nabla f &= \left(\tfrac{\partial f}{\partial x_1},\ldots,\tfrac{\partial f}{\partial x_d}\right) \\ D_u f &= \nabla f\cdot u = \|\nabla f\|\cos\theta \\ \theta &\leftarrow \theta - \eta\,\nabla_\theta L \end{aligned}\]

시작점을 드래그하고 "하강 실행"을 눌러보세요. 궤적이 등고선을 가로지르며 최소점으로 내려갑니다. 이방성 슬라이더로 골짜기를 길쭉하게 만들면 궤적이 지그재그로 튕기기 시작하는데, 이것이 순수 경사하강법의 근본적인 약점입니다.

야코비안 Jacobian

입력도 출력도 벡터인 함수의 미분은 행렬이다. 그 행렬은 한 점 근처에서 함수를 대신하는 선형변환이며, 행렬식은 그 변환이 부피를 얼마나 늘리거나 줄이는지를 말해준다.

정의. \(F:\mathbb{R}^n\to\mathbb{R}^m\)의 야코비안은 \((i,j)\) 성분이 \(\partial F_i/\partial x_j\)인 \(m\times n\) 행렬이다. \(m=1\)이면 그래디언트의 전치가 되고, \(n=m=1\)이면 그냥 도함수다 — 야코비안은 미분 개념의 가장 일반적인 형태다.

국소적으로는 모든 것이 선형변환이다. 한 점 \(a\) 근처에서 \(F(a+\Delta)\approx F(a)+J_F(a)\,\Delta\)다. 즉 비선형 함수도 아주 가까이서 보면 행렬 하나로 작동한다. 이것이 이 글 서두의 "충분히 가까이서 보면 모든 것은 직선"을 다차원으로 옮긴 문장이며, 선형변환 글에서 본 격자의 변형이 여기서 그대로 재현된다.

연쇄법칙 = 행렬곱. \(J_{g\circ f}(x)=J_g(f(x))\,J_f(x)\). 역전파는 이 행렬곱의 연쇄인데, 실제 구현은 행렬을 만들지 않는다. 손실이 스칼라이므로 왼쪽부터 벡터-야코비안 곱 \(v^\top J\)를 연달아 취하면 되고, 이 방식(reverse-mode)이 파라미터가 많고 출력이 하나인 딥러닝에 압도적으로 유리하다.

행렬식: 부피 배율. \(|\det J|\)는 그 점 근처에서 미소 부피가 몇 배로 변하는지를 말한다. 선형대수 글의 행렬식이 넓이 배율이었던 것과 정확히 같은 의미이며, 다만 점마다 달라진다는 점이 다르다. \(\det J=0\)인 점에서는 국소적으로 차원이 무너져 함수가 역함수를 갖지 못한다.

머신러닝에서: 정규화 흐름. 확률변수를 \(z\mapsto x=F(z)\)로 변환하면 밀도는 \(p_x(x)=p_z(z)\,|\det J_F(z)|^{-1}\)로 바뀐다. 부피가 늘어난 만큼 밀도가 묽어진다는 뜻이다. Normalizing Flow는 \(\det J\)를 값싸게 계산할 수 있도록 \(F\)를 설계(삼각 야코비안, 결합층 등)해 정확한 로그가능도를 얻는 모델군이다. 다음 글의 확률밀도 흐름도 결국 이 관계의 연속시간 버전이다.

\[\begin{aligned} (J_F)_{ij} &= \frac{\partial F_i}{\partial x_j}, \qquad J_F \in \mathbb{R}^{m\times n} \\ F(a+\Delta) &\approx F(a) + J_F(a)\,\Delta \\ J_{g\circ f} &= J_g\,J_f \\ p_x(x) &= p_z(z)\,\bigl|\det J_F(z)\bigr|^{-1} \end{aligned}\]

왼쪽 격자 위의 점을 드래그하면 오른쪽에 그 점이 어디로 옮겨지는지, 그리고 그 주변의 작은 정사각형이 어떤 평행사변형으로 변형되는지가 그려집니다. 그 평행사변형의 넓이 비율이 곧 |det J|입니다. 변환을 바꿔가며 늘어나는 곳과 접히는 곳(det J = 0)을 찾아보세요.

헤시안 Hessian

그래디언트가 기울기라면 헤시안은 곡률이다. 이 대칭행렬의 고유값들이 임계점의 종류를 판정하고, 최적화가 얼마나 어려울지를 미리 알려준다.

정의. \((H_f)_{ij}=\frac{\partial^2 f}{\partial x_i\partial x_j}\). 2차 편미분을 모은 \(d\times d\) 행렬이며, \(f\)가 충분히 매끄러우면 혼합편미분의 순서가 무관하므로(슈바르츠 정리) 대칭행렬이다. 대칭이라는 사실 덕분에 고유값이 모두 실수이고 고유벡터를 직교하게 잡을 수 있다.

2차 근사의 계수. \(f(a+\Delta)\approx f(a)+\nabla f\cdot\Delta+\tfrac{1}{2}\Delta^\top H\Delta\). 테일러 전개의 다변수판이며, 마지막 이차형식이 그 점 근처의 그릇 모양을 결정한다. 등고선이 타원으로 보이는 것도 이 항 때문이고, 그 타원의 축이 \(H\)의 고유벡터다 — 확률 글의 공분산 타원과 같은 기하가 여기서 다시 나타난다.

임계점 판정. \(\nabla f=0\)인 점에서 헤시안의 고유값 부호가 답을 준다. 모두 양수면 국소 최소(모든 방향으로 위로 휘어짐), 모두 음수면 국소 최대, 부호가 섞이면 안장점이다. 고차원에서 모든 고유값이 같은 부호일 확률은 급격히 낮아지므로, 딥러닝 손실 지형의 임계점은 대부분 안장점이라는 결론이 나온다.

왜 고유값의 부호가 답을 주는가. 임계점에서는 \(\nabla f=0\)이므로 2차 근사에 1차 항이 사라지고 \(f(a+\Delta)-f(a)\approx\tfrac12\Delta^\top H\Delta\)만 남는다. 그러니 질문은 "이 이차형식이 모든 방향에서 양수인가"로 줄어든다. 그런데 \(H\)는 대칭이라 직교하는 고유벡터 축으로 좌표를 갈아탈 수 있고, 그 축에서 보면 교차항이 전부 사라져 \(\tfrac12(\lambda_1 c_1^2+\lambda_2 c_2^2+\cdots)\)라는 단순한 합이 된다. \(c_i^2\)는 언제나 0 이상이므로 각 항의 부호는 오직 \(\lambda_i\)가 정한다. 결국 헤시안은 "고유벡터 방향마다 이 지형이 위로 휘는지 아래로 휘는지"를 \(\lambda_i\)라는 숫자 하나씩으로 적어둔 것이고, 판정 규칙은 그것을 읽는 방법일 뿐이다.

안장점이라는 이름. 부호가 섞였다는 것은 어떤 축에서는 골짜기이고 다른 축에서는 봉우리라는 뜻이다. 말안장이 앞뒤로는 올라가고 좌우로는 내려가는 것과 같은 모양이라 안장점이라 부른다. 이 지점은 \(\nabla f=0\)이라 경사하강법이 보기에 "평평한 곳"이지만 최소점이 아니며, 탈출하려면 \(\lambda<0\)인 방향을 찾아야 한다 — 순수 경사하강이 안장점 근처에서 오래 머무는 이유이고, 잡음이 섞인 SGD가 오히려 그 방향으로 밀려나 빠져나오는 데 도움이 되는 이유이기도 하다.

조건수 = 최적화의 난이도. 최대 고유값과 최소 고유값의 비 \(\kappa=\lambda_{\max}/\lambda_{\min}\)를 조건수라 한다. \(\kappa\)가 크면 등고선이 길쭉한 골짜기가 되고, 경사하강법은 앞 절에서 본 지그재그에 빠진다. 안정적으로 쓸 수 있는 학습률은 \(\lambda_{\max}\)가 제한하는데 수렴 속도는 \(\lambda_{\min}\)이 결정하기 때문이다. 정규화 기법들이 학습을 빠르게 만드는 이유 중 하나가 이 조건수를 낮추는 것이다.

머신러닝에서. \(d\)가 수억이면 \(H\)는 \(d^2\)개 원소라 만들 수조차 없다. 그래서 실무는 우회한다 — 헤시안-벡터 곱만 계산하거나(전체 행렬 없이 가능), Adam처럼 대각 성분만 근사하거나, L-BFGS처럼 최근 기울기들로 저계수 근사를 만든다. 한편 헤시안의 고유값 분포는 손실 지형의 평탄함(sharpness)을 재는 도구로 일반화 성능 연구에서 활발히 쓰인다.

\[\begin{aligned} (H_f)_{ij} &= \frac{\partial^2 f}{\partial x_i \partial x_j} = (H_f)_{ji} \\ f(a+\Delta) &\approx f(a) + \nabla f^\top \Delta + \tfrac{1}{2}\Delta^\top H \Delta \\ \kappa &= \lambda_{\max}/\lambda_{\min} \end{aligned}\]

프리셋으로 그릇·안장·골짜기를 오가며 점을 드래그해보세요. 두 고유벡터 축(빨강·보라)과 고유값이 표시되고, 부호 조합에 따라 임계점 종류가 판정됩니다. 골짜기 프리셋에서 조건수가 얼마나 커지는지, 그리고 그때 등고선이 얼마나 길쭉해지는지 확인해보세요.

벡터장 Vector Fields

공간의 각 점에 벡터를 하나씩 배정한 것이 벡터장이다. 다음 글의 미분방정식은 사실상 벡터장을 하나 주고 "이 화살표를 따라가라"고 말하는 것에 지나지 않는다.

정의. 벡터장은 함수 \(F:\mathbb{R}^n\to\mathbb{R}^n\)이며, 입력과 출력의 차원이 같다는 점이 핵심이다. 각 점 \(x\)에 그 점에 붙어 있는 화살표 \(F(x)\)를 대응시킨다고 읽는다. 유체의 속도장, 중력장, 그리고 앞 절의 \(-\nabla L\)이 모두 벡터장이다.

그래디언트장은 특별한 벡터장이다. 어떤 스칼라 함수의 그래디언트로 표현되는 벡터장을 보존장이라 한다. 이런 장에는 "퍼텐셜"이 존재해 화살표가 언제나 오르막을 가리키고, 닫힌 경로를 돌면 알짜 변화가 0이라 순환하지 않는다. 반면 회전하는 벡터장은 어떤 스칼라의 그래디언트로도 쓸 수 없다. 손실의 경사하강이 빙빙 돌지 않고 결국 어딘가로 내려가는 것은 \(-\nabla L\)이 보존장이기 때문이다 — 반대로 GAN의 두 플레이어가 만드는 벡터장은 보존장이 아니라서 순환이 생기고, 학습이 진동한다.

흐름선. 각 점에서 화살표 방향으로 계속 따라가며 그린 곡선이 흐름선(streamline)이고, 이것이 미분방정식 \(\dot{x}=F(x)\)의 해다. 즉 벡터장을 그리는 것과 미분방정식을 세우는 것은 같은 일이다. 오른쪽에서 아무 곳이나 클릭하면 그 점에서 출발한 흐름선이 그려진다.

머신러닝에서. 학습 동역학 자체가 벡터장 위의 흐름이다. 학습률을 0으로 보낸 극한에서 경사하강은 \(\dot\theta=-\nabla L(\theta)\)라는 미분방정식(경사흐름)이 된다. Neural ODE는 신경망 자체를 벡터장으로 두어 \(\dot{h}=f_\theta(h,t)\)를 풀고, 확산 모델의 역과정과 Probability Flow ODE도 학습된 벡터장을 따라 노이즈를 데이터로 옮기는 흐름이다.

\[\begin{aligned} F &: \mathbb{R}^n \to \mathbb{R}^n \\ \dot{x} &= F(x) \quad \text{(흐름선이 곧 해)} \\ \dot\theta &= -\nabla L(\theta) \quad \text{(경사흐름)} \end{aligned}\]

프리셋으로 여러 벡터장을 비교해보세요. 그림 아무 곳이나 클릭하면 그 점에서 출발한 흐름선이 그려집니다. 그래디언트장에서는 흐름선이 등고선을 가로지르며 반드시 어딘가로 수렴하지만, 회전장에서는 영원히 맴돕니다 — 이 차이가 다음 절 발산·회전의 주제입니다.

발산 Divergence

벡터장의 각 점에서 흐름이 솟아나는지 빨려 들어가는지를 재는 스칼라다. 밀도가 시간에 따라 어떻게 변하는지를 지배하는 양이며, 연속방정식과 확산 모델의 핵심 항이다.

정의. \(\nabla\cdot F=\frac{\partial F_1}{\partial x_1}+\cdots+\frac{\partial F_n}{\partial x_n}\). 야코비안의 대각합(trace)과 같은 값이며, 벡터장을 넣으면 스칼라장이 나온다.

기하적으로: 샘과 싱크. 한 점 주위에 아주 작은 상자를 놓고, 들어오는 양과 나가는 양의 차이를 상자 부피로 나눈 극한이 발산이다. \(\nabla\cdot F>0\)이면 그 점에서 흐름이 솟아나고(샘), \(<0\)이면 빨려 들어가며(싱크), \(=0\)이면 들어온 만큼 나간다. 오른쪽에서 빨간 영역이 샘, 파란 영역이 싱크다.

부피 변화율이다. 벡터장을 따라 흘러가는 작은 물방울을 생각하면, 그 부피의 상대 변화율이 정확히 발산이다: \(\frac{d}{dt}\log V = \nabla\cdot F\). 앞 절 야코비안의 \(|\det J|\)가 이산적인 부피 배율이었다면, 발산은 그것의 연속시간 버전이다 — 실제로 \(\frac{d}{dt}\log\det J = \nabla\cdot F\)가 성립한다.

연속방정식. 물질이 생기거나 사라지지 않는다면 밀도 \(\rho\)는 \(\frac{\partial\rho}{\partial t}+\nabla\cdot(\rho F)=0\)을 만족한다. "밀도가 줄어드는 속도 = 흘러나가는 양"이라는 보존 법칙이며, 다음 글에서 이 식이 확률밀도가 어떻게 흘러가는지를 기술하는 데 그대로 쓰인다. 결국 Fokker-Planck 방정식과 Probability Flow ODE가 이 한 줄의 변주다.

머신러닝에서. Continuous Normalizing Flow에서 로그밀도의 변화가 \(\frac{d\log p}{dt}=-\nabla\cdot f_\theta\)로 주어진다 — 행렬식을 계산할 필요 없이 대각합만 있으면 되고, 그 대각합조차 Hutchinson 추정기로 값싸게 근사할 수 있다는 점이 이 모델군을 실용적으로 만들었다.

\[\begin{aligned} \nabla\cdot F &= \sum_i \frac{\partial F_i}{\partial x_i} = \operatorname{tr}(J_F) \\ \frac{d}{dt}\log V &= \nabla\cdot F \\ \frac{\partial \rho}{\partial t} + \nabla\cdot(\rho F) &= 0 \quad \text{(연속방정식)} \end{aligned}\]

배경색이 발산입니다 — 빨강은 솟아나는 곳, 파랑은 빨려 들어가는 곳. 점을 드래그하면 그 점 주위의 작은 원이 흐름을 따라 어떻게 커지거나 작아지는지 함께 표시됩니다. 회전장에서는 화살표가 격렬히 도는데도 발산이 어디서나 0이라는 점 — 회전과 발산은 서로 다른 것을 잽니다.

라플라시안 Laplacian

그래디언트의 발산, 즉 2차 미분들의 합이다. 어떤 점의 값이 주변 평균보다 얼마나 낮은지를 재며, 이 양이 확산·열전도·평활화를 지배한다.

정의. \(\Delta f=\nabla\cdot(\nabla f)=\sum_i \frac{\partial^2 f}{\partial x_i^2}\). 그래디언트(벡터장)를 만든 뒤 그 발산(스칼라)을 취한 것이며, 헤시안의 대각합과 같다: \(\Delta f=\operatorname{tr}(H_f)\). \(\nabla^2 f\)로도 쓴다.

핵심 직관: 주변 평균과의 차이. 라플라시안은 "이 점의 값이 주변 평균보다 얼마나 작은가"에 비례한다. 정확히는 반지름 \(r\)인 작은 구 위의 평균값이 \(\bar{f}\approx f(x)+\frac{r^2}{2n}\Delta f(x)\)로 주어진다. 그래서 \(\Delta f>0\)이면 그 점은 주변보다 움푹한 골짜기이고, \(\Delta f<0\)이면 주변보다 솟은 봉우리다. 이 한 문장이 라플라시안이 등장하는 모든 방정식을 설명한다.

그래서 확산이 나온다. 열방정식 \(\frac{\partial u}{\partial t}=\alpha\Delta u\)는 "주변보다 차가운 곳은 데워지고 뜨거운 곳은 식는다"를 그대로 옮긴 식이다. 시간이 지나면 봉우리는 깎이고 골짜기는 메워져 전체가 평평해진다. 다음 글의 열방정식·확산방정식, 그리고 확산 모델의 순방향 과정이 모두 이 평활화다.

조화함수. \(\Delta f=0\)인 함수를 조화함수라 하며, 모든 점에서 값이 주변 평균과 정확히 같다. 이런 함수는 내부에 극값을 가질 수 없고(최대원리), 경계값이 내부를 완전히 결정한다.

머신러닝에서. 이미지 처리의 라플라시안 필터는 가장자리를 검출하는데, 값이 주변 평균에서 크게 벗어난 지점이 곧 경계이기 때문이다. 그래프 라플라시안 \(L=D-A\)는 이 연산자를 그래프 위로 옮긴 것으로, 스펙트럼 클러스터링과 GNN의 이론적 토대가 된다 — 그 고유벡터가 그래프 위의 "주파수"에 해당한다. 확산 모델의 순방향 SDE에 대응하는 Fokker-Planck 방정식에도 이 항이 등장하며, 그것이 데이터 분포를 가우시안으로 뭉개는 역할을 한다.

\[\begin{aligned} \Delta f &= \nabla\cdot(\nabla f) = \sum_i \frac{\partial^2 f}{\partial x_i^2} = \operatorname{tr}(H_f) \\ \bar{f}_{\text{구}} &\approx f(x) + \tfrac{r^2}{2n}\Delta f(x) \\ \frac{\partial u}{\partial t} &= \alpha\,\Delta u \quad \text{(열방정식)} \end{aligned}\]

배경색이 라플라시안입니다 — 파랑은 주변보다 낮은 골짜기(앞으로 채워질 곳), 빨강은 주변보다 높은 봉우리(앞으로 깎일 곳). "확산 재생"을 누르면 등고선이 실제로 평평해지는 과정을 볼 수 있습니다. 봉우리가 먼저 무너지고 골짜기가 메워지는 순서가 라플라시안의 부호와 정확히 맞물립니다.

단면으로 본 확산 — 봉우리는 깎이고 골짜기는 메워진다

← Back to all posts