함수는 높이만 말해준다. 어느 쪽으로 내려가야 할지를 어떻게 알까?
함수는 지금 선택이 얼마나 좋은지를 단 한 수로 말해준다. 어떤 선택이 가장 좋은지는 말해주지 않는다. 간단한 함수라면 답을 손으로 적을 수 있지만, 그 외 거의 모든 경우에는 그렇지 못하다. 이 신경망을 보정하는 온도에는 공식이 없고, 이 제약 아래에서 분산을 최소화하는 포트폴리오 비중에도, 이 데이터셋에 맞는 모델 매개변수에도 공식이 없다. 그런데도 세 문제 모두 매일 풀린다 — 같은 다섯 가지 움직임으로. 목적을 정한다, 탐색 공간을 정한다, 근처 선택지를 비교한다, 얼마나 움직일지를 정한다, 언제 멈출지를 정한다.
최적화는 공식을 찾는 일이 아니다. 좋아져야 할 양을 정하고, 가능한 선택지 사이를 움직이다가 더 좋아지지 않는 곳에서 멈추는 일이다. 이 모듈은 그 움직임에 대한 것이다. 알고리즘마다 그 움직임을 다르게 한다 — 골격은 같다.
- 정의
탐색 공간 위의
가 주어졌을 때, 를 가능한 한 작게 (또는 크게) 만드는 점 를 찾는 일. 표준 기계 장치 — 어딘가에서 시작해, 를 개선하는 방향으로 스텝을 밟고, 한 스텝의 거리를 (목적 함수 로) 조절하고, 근처에서 개선이 더는 일어나지 않으면 멈춘다. 이게스텝 크기 이다. 멈춘 곳은수렴 이고, 그곳이 전역 최솟값인지는 의 기하와 시작점에 달렸다.국소 최솟값 - 적용
선택지가 있고, 그 선택이 얼마나 좋은지를 말해주는 수가 있을 때 언제든. ML의 모델 매개변수 적합, 금융의 포트폴리오 비중 선택,
의 온도 스칼라 조정, 물리의보정 점 찾기, 공학의 더 싼 부품 설계. 같은 다섯 단계 루프가 모두를 돌린다. 다른 건 목적, 공간, 움직임 규칙뿐.평형 - 한계
간단한 루프가 무너지는 세 자리. (1) 목적 함수에 국소 최솟값이 여러 개 있어 하강이 나쁜 곳에 떨어진다. (2) 탐색 공간에 제약이 있어 (확률은 합이 1, 비중은 음이 아님, 매개변수가 다양체 위에 있음) 단순한 스텝이 공간을 벗어난다. (3) 목적 함수 평가는 싸지만
계산이 비싸서, 방향 결정이 비용의 대부분이 된다. 각각은 고유한 기법 계열을 가지고 있고, 이 모듈은 그 모두가 확장하는 기본 사례다.그래디언트
목적 — 무엇을 더 좋게 만들 것인가?
모든 최적화 문제는 하나의 수에서 출발한다. 작을수록 좋거나, 클수록 좋거나 — 어느 쪽이든 단 한 수만 그 권한을 가진다. 기계 학습에서는 이 수가 손실 함수 — 데이터셋 위에서 합한 오차다. 금융에서는 포트폴리오
“최소화”와 “최대화”는 같은 문제를 두 번 부르는 이름이다 — 를 최대화하는 일은 를 최소화하는 일과 같다. 이 모듈은 관습적으로 최소화에 대해 말한다. 부호를 뒤집으면 모든 게 최대화로 옮겨간다. 목적 함수가 있어야 문제가 자리에 박힌다. 없으면 “더 좋게 만들자”에 합의된 방향이 없다. 있으면 모든 후보에 수 하나가 붙어 비교가 기계적이 된다.
탐색 공간 — 어떤 선택지가 허용되는가?
목적 함수만으로는 부족하다. 무엇이 변할 수 있는지도 말해야 한다. 허용된 모든 선택지의 집합이 탐색 공간이다. ML에서는 모델 매개변수의 고차원
탐색 공간이 유한하냐 (하이퍼파라미터 100가지 조합 중 하나), 이산적 조합론이냐 (작업을 작업자에 배정), 연속이냐 (의 어디든) 가 어떤 알고리즘이 쓰일지를 결정한다. 이 모듈은 연속 경우에 집중한다 — Lemma의 나머지를 돌리는 움직임 규칙, 미분이 그곳에서 가장 할 말이 많기 때문이다. 이산 최적화 (정수 계획법, 스케줄링, 외판원 문제) 도 존재한다 — 다른 수학을 쓴다.
움직임 — 근처 선택지를 비교
현재 점 가 주어졌을 때, 최적화기는 어느 쪽으로 갈지를 정해야 한다. 가장 단순하고 가장 일반적인 답 — 와 근처 점들에서 를 계산해 작은 값 쪽으로 움직인다. 가 미분 가능하면 “근처”는 한 대상으로 줄어든다 — 미분, 또는 고차원에서는 그래디언트 — 가 1차 근사로 를 가장 빠르게 작게 만드는 방향을 정확히 알려준다. 움직임은 한 연산이 된다: .
위젯이 이걸 구체화한다. 현재 의 주황 접선이 기울기 를 보여주고, 스텝을 누르면 기울기가 양이면 (함수가 증가 → 반대로) 가 왼쪽으로, 음이면 오른쪽으로 움직인다. 움직임의 크기는 — 기울기 자체에 비례한다. 기울기가 가파른 곳에서는 큰 스텝, 완만한 곳에서는 작은 스텝. 최적화기는 최솟값에 다가갈수록 스스로 느려진다.
이것이 유일한 움직임 규칙은 아니다. 뉴턴 방법은 2계 도함수를 써서 한 번에 스텝을 정한다. 좌표 하강법은 한 번에 한 변수씩 움직인다. 확률적 경사하강법은 그래디언트의 잡음 섞인 근사를 쓴다. 모두 같은 질문에 대한 답이다 — 어느 쪽이 더 좋고, 얼마나 갈까?
import numpy as np
# A general "improve until you can't" loop. Given an objective f and its
# derivative f', start somewhere, take steps in the direction f' says is
# downhill, stop when f' is essentially zero (or you run out of budget).
def descend(f, df, x0, alpha=0.1, tol=1e-4, max_iters=500):
x = x0
history = [x]
for _ in range(max_iters):
g = df(x)
if abs(g) < tol:
break
x = x - alpha * g
history.append(x)
return x, history
# Convex bowl: f(x) = (x - 1)², f'(x) = 2(x - 1). Unique min at x = 1.
f = lambda x: (x - 1)**2
df = lambda x: 2 * (x - 1)
x_star, hist = descend(f, df, x0=-2.4, alpha=0.3)
(round(x_star, 4), len(hist), round(f(x_star), 6))
# → (1.0000, 28, 0.0)
# 28 iterations from x = -2.4 to x = 1.0. Each step uses f'(x) — the
# "which way is better" question, answered locally.스텝 크기 — 너무 적게, 너무 많이
스텝 크기 는 두 번째 다이얼이고, 실용적 영향은 방향 못지않다. 위젯을 보자 — 볼록 그릇 프리셋에 작은 , 위치가 최솟값을 향해 천천히 옮긴다. 작은 옳은 스텝이 많다. 를 키운다 — 하강이 빨라지다가 너무 빨라진다. 매 스텝이 목표를 지나치고 자취가 좌우로 진동한다. 더 키우면 위치가 완전히 폭발해, 매 반복마다 전 오차를 증폭하며 화면 밖으로 걸어 나간다.
2계 도함수가 인 이차식 의 안정성 한계는 정확하다 — 면 수렴, 면 발산. 이차식이 아닌 에서는 그 한계가 움직이는 동안 변한다 — 한 점의 국소 곡률과 다른 점의 곡률이 다르다. 실제 알고리즘은 를 보수적으로 고정하거나, 스케줄링하거나 (크게 시작해 시간이 흐를수록 줄임), 매 스텝 적응적으로 계산한다 (선형 탐색, 신뢰 영역). 셋 다 같은 사실에 대한 답이다 — 단일 상수로 모든 기하를 다룰 수는 없다.
ML에서는 에 특별한 이름이 붙는다 — 학습률 — 학습 결과를 가르는 가장 중요한 튜닝 양이라서. 나머지 최적화에서는 그냥 다. 같은 수, 같은 역할 — 커뮤니티마다 다른 민속만 다를 뿐.
# Step size α decides whether descent crawls, lands, or diverges.
# Same convex bowl, three different α.
for alpha in (0.02, 0.3, 1.05):
x_star, hist = descend(f, df, x0=-2.4, alpha=alpha, max_iters=300)
print(f"α = {alpha:5.2f} → iters = {len(hist):4d} final x = {x_star:8.4f}")
# α = 0.02 → iters = 300 final x = -0.0241 (crawls, hit max_iters)
# α = 0.30 → iters = 28 final x = 1.0000 (lands)
# α = 1.05 → iters = 300 final x = -1.5e+87 (overshoots, diverges)
#
# For this quadratic, the curvature is f''(x) = 2, and the stability
# bound is α < 2 / f''(x) = 1. α = 1.05 sits past the edge, so each step
# amplifies the previous error. The right α is geometry-dependent.
# Adaptive trick: shrink α whenever a step *increases* f. Backtracking
# line search is one widely-used version.
def descend_backtrack(f, df, x0, alpha0=1.0, tol=1e-4, max_iters=500):
x = x0
alpha = alpha0
for _ in range(max_iters):
g = df(x)
if abs(g) < tol:
break
# Halve α until the step actually improves f.
while f(x - alpha * g) > f(x):
alpha *= 0.5
x = x - alpha * g
alpha = min(alpha * 1.5, alpha0) # gently grow back
return x
round(descend_backtrack(f, df, x0=-2.4, alpha0=2.0), 4)
# → 1.0 converges even with a deliberately too-big starting α정지 — 국소 최솟값과 수렴
가장 단순한 정지 규칙 — 움직여도 가 크게 변하지 않으면 멈춘다. 구체적으로, 그래디언트 크기 가 작은 허용오차 아래로 떨어지거나, 변화량 이 그러거나, 반복 점 자체가 더는 움직이지 않거나. 이런 규칙이 없으면 루프는 영원히 돈다. 있으면 무엇인가가 최적화기를 멈춘다 — 다만 멈춘 자리가 국소 최솟값이라는 보장만 있다.
이게 이 모듈이 짊어진 가장 중요한 단서다. 볼록 목적 함수 (단일 그릇, 다른 굴곡 없음) 는 정확히 최솟값 하나를 가지고, 어떤 하강도 그곳에 닿는다. 실세계에서는 볼록한 것이 거의 없다. 신경망 손실 곡면은 극단적으로 비볼록이고, 제약이 있는 포트폴리오 문제는 비볼록이 되고, 보정 손실은 볼록이지만 그 고차원 사촌은 아니다. 위젯의 두 골짜기 프리셋이 1차원에서 문제를 보여준다 — 에서 시작하면 하강은 왼쪽 골짜기 — 국소 최솟값 — 에 떨어져 멈추고, 더 깊은 오른쪽 골짜기에는 닿지 못한다.
정직한 입장 — 멈췄다와 풀렸다는 다른 두 일이다. 국소 최솟값은 안에서 보면 전역 최솟값과 똑같아 보인다 (근처에서 더 나은 곳이 없다). 거기서 벗어나려는 전략 — 임의 재시작, 모멘텀, 확률적 잡음, 시뮬레이티드 어닐링 — 은 모두 그래디언트가 사라지는 첫 자리에서 멈추지 않는 어떤 방법을 더한 것이다.
이게 어디에 나타나나 — 같은 다섯 단계, 두 필러
최적화는 “공식은 없지만 절차가 있다”는 Lemma 페이지마다 그 뒤에 있는 수학이다. 세 응용이 이미 이 언어를 쓴다 — 같은 골격 위에 다른 무엇을, 어디서, 어떻게가 얹혀 있다.
ml : 학습 데이터의 손실; ℝⁿ 위의 매개변수;
학습률을 가진 경사하강법.
ml : 음의 로그 가능도; 스칼라 하나 (온도);
1차원 하강.
finance : 포트폴리오 분산; 합이 1인 비중;
이차식 최소화 — 닫힌 형식 또는 반복.경사하강법 — 정전(正典)적 예. 목적 = 학습 데이터에 합한 회귀 손실. 탐색 공간 = 모델 매개변수. 움직임 = 역전파로 계산한 그래디언트. 스텝 크기 = 학습률. 정지 = 손실이 평탄해지거나 학습 예산이 끝남. 모든 디테일이 다섯 단계 중 하나에 도메인 이름을 갖고 들어간다.
모델 보정 — 온도 스케일링은 1차원 탐색 공간 위의 최적화. 목적 = 따로 빼둔 정답 위의 음의 로그 가능도. 탐색 공간 = . 움직임 = NLL의 에 대한 미분. 스텝 크기 = 1차원 스칼라 적합이 몇 초 안에 수렴할 만큼 작게. 이 페이지는 하강으로 문제를 푸는데, 왜 하강이 작동하는지를 정당화하는 자리가 이 모듈이다.
포트폴리오 위험 — 최소 분산 비중 찾기는 두 자산이면 닫힌 형식, 고차원이면 반복으로 푸는 최적화다. 목적 = 포트폴리오 분산. 탐색 공간 = 합이 1인 비중 . 움직임 = 분산의 비중에 대한 미분. 그 페이지 § 5의 유도는 정확히 움직임 단계의 첫 한 줄 — 그래디언트를 0으로 놓고 푼다. 닫힌 형식이 있을 때 최적화는 대수로 무너지고, 없을 때는 같은 기계가 반복한다.
같은 다섯 단계 골격, 다른 뼈. 골격에 이름을 붙이는 일이 그것을 옮길 수 있게 만든다.
# Where this shows up — three real optimization stories share the same loop.
# (1) ML: gradient descent on a regression loss.
# Data y = 3·x; fit w to minimize L(w) = Σ (w·x_i − y_i)².
X = np.array([1.0, 2.0, 3.0, 4.0])
Y = 3.0 * X
def L(w): return float(((w * X - Y) ** 2).sum())
def dL(w): return float((2 * (w * X - Y) * X).sum())
w_star, _ = descend(L, dL, x0=0.0, alpha=0.02)
round(w_star, 4)
# → 3.0 the slope of Y = 3x, recovered by descent
# (2) Calibration: fit one scalar T (temperature) to minimize NLL.
# Logits z, true labels y; we pick T to make softmax(z/T) match observed
# correctness frequencies. One parameter, well-behaved objective.
def softmax(z):
e = np.exp(z - z.max(axis=-1, keepdims=True))
return e / e.sum(axis=-1, keepdims=True)
np.random.seed(0)
z_logits = np.random.randn(200, 5) * 3.0 # overconfident logits
labels = np.random.randint(0, 5, size=200)
def nll(T): return float(-np.log(softmax(z_logits / T)[range(200), labels] + 1e-12).mean())
T_star = 1.0
for _ in range(80):
g = (nll(T_star + 1e-3) - nll(T_star - 1e-3)) / 2e-3 # numerical gradient
T_star -= 0.1 * g
round(T_star, 3), round(nll(T_star), 3)
# → (>1.0, <nll(1.0)) T > 1 softens overconfident predictions
# (3) Portfolio risk: minimize variance over weight w ∈ [0, 1].
# Two assets, σ_A = 0.2, σ_B = 0.1, ρ = 0.0 (independent).
def var_p(w): return float(w**2 * 0.04 + (1 - w)**2 * 0.01)
def dvar_p(w): return float(2 * w * 0.04 - 2 * (1 - w) * 0.01)
w_star, _ = descend(var_p, dvar_p, x0=0.5, alpha=2.0)
round(w_star, 4)
# → 0.2 20% in the volatile asset minimizes variance. The closed-form
# answer w* = σ_B² / (σ_A² + σ_B²) = 0.01 / 0.05 = 0.2. Match.
#
# Three pillars, one loop: objective + derivative + step + stopping.
# The science is in the choices (which f? which start? which α?). The
# *machinery* is identical.최적화는 좋아져야 할 양을 정하고, 가능한 선택지 사이를 움직이다가 더 좋아지지 않는 곳에서 멈추는 일이다. 다섯 움직임 — 목적, 탐색 공간, 움직임 규칙, 스텝 크기, 정지. Lemma의 나머지에서 적합, 튜닝, 최소화, 평형 찾기로 불리는 거의 모든 것이 이 루프의 한 판본이다.
retro-fit된 세 응용 (경사하강법, 모델 보정, 포트폴리오 위험) 중 하나를 골라라. 그 페이지가 무엇을 목적 함수로, 탐색 공간으로, 움직임 규칙으로, 스텝 크기로, 정지 조건으로 쓰는지 적어라.
이라 하자. 를 구하라. 에서 시작해 (a) , (b) , (c) 에 대해 첫 세 반복 을 적어라. 어느 것이 수렴하고, 어느 것이 그대로이고, 어느 것이 발산하는지 말해라.
위젯에서 두 골짜기로 바꾼다. 리셋한 뒤 위치 슬라이더로 에서 시작해, 더는 움직이지 않을 때까지 스텝을 밟는다. 멈춘 자리와 그곳의 값을 기록한다. 이제 에서 같은 일을 한다. 두 정지 자리가 같은가? 이게 하강 규칙에 대해 무엇을 말해주는가?
트레이더가 포트폴리오 비중 위의 기대 수익 를 최대화하려 한다. 이 모듈이 쓰는 형태 (최소화) 로 다시 써라. 목적 함수는 무엇이고, 로 표현한 그 미분은 무엇인가?