수학

MATH / 중급 17번

행렬 노름: 프로베니우스·스펙트럼 노름과 립시츠 상수

유도 노름을 정의하고 ‖A‖₂ = σ_max를 특잇값 분해로 증명합니다. 프로베니우스 노름이 특잇값 제곱합인 이유와 두 노름 사이의 부등식, 부분곱셈성, 그리고 선형층의 립시츠 상수가 곧 스펙트럼 노름이라는 것까지 이어 붙여 클리핑·스펙트럼 정규화·립시츠 제약이 왜 같은 언어인지를 봅니다.

PALDYN Team40 MIN READ

세 가지 안정화 기법이 각각 다른 이름으로 불립니다. 순환망에서는 그래디언트 클리핑의 임계값을 정하고, GAN 판별자에서는 스펙트럼 정규화를 켜고, 강건성 논문에서는 립시츠 제약을 겁니다. 라이브러리도 다르고 걸리는 자리도 다릅니다.

그런데 셋이 재는 것은 같은 수 하나입니다. «이 행렬이 벡터를 최대 몇 배까지 늘릴 수 있는가» — 이 질문의 답이 세 기법의 공통 언어입니다.

지난 글에서 프로베니우스 노름과 스펙트럼 노름을 «행렬 사이의 거리를 재는 두 자»로 빌려 쓰고 성질은 미뤄 두었습니다. 이 글이 그 빚을 갚습니다.

유도 노름과 σ_max

유도 노름

벡터의 길이를 재는 노름은 이미 노름과 거리에서 세웠습니다. 행렬에도 그런 자가 필요한데, 행렬은 그 자체가 «벡터를 벡터로 보내는 장치»라 자연스러운 정의가 하나 있습니다 — 가장 많이 늘어나는 정도를 재는 것입니다.

정의. 벡터 노름 ∥⋅∥\|\cdot\| 이 주어졌을 때

∥A∥=max⁡x≠0∥Ax∥∥x∥=max⁡∥x∥=1∥Ax∥\|A\| = \max_{\mathbf{x} \ne \mathbf{0}} \frac{\|A\mathbf{x}\|}{\|\mathbf{x}\|} = \max_{\|\mathbf{x}\|=1}\|A\mathbf{x}\|

를 그 벡터 노름이 유도한 노름이라고 한다.

두 번째 등호는 분수를 «길이 1로 맞춰 놓고 재기»로 바꾼 것입니다. x\mathbf{x} 를 두 배로 늘리면 분자와 분모가 함께 두 배가 되어 비가 그대로이므로, 길이 1인 것만 봐도 됩니다. 곧 유도 노름은 벡터의 자를 하나 골라 두고, 그 자로 잰 입력 길이 대비 출력 길이의 최대 배율을 행렬의 크기로 삼는 것입니다.

이것이 노름이라고 불릴 자격이 있는지부터 확인합니다. 벡터 노름이 갖춰야 했던 세 조건을 행렬에 그대로 요구합니다.

  • 0일 때만 0 — A≠0A \ne 0 이면 0이 아닌 열이 하나 있고, 그 열을 뽑는 표준기저 ej\mathbf{e}_j 를 넣으면 Aej≠0A\mathbf{e}_j \ne \mathbf{0} 이므로 최댓값이 0보다 큽니다.
  • 상수배 — ∥cAx∥=∣c∣ ∥Ax∥\|cA\mathbf{x}\| = |c|\,\|A\mathbf{x}\| 이므로 최댓값도 ∣c∣|c| 배가 됩니다.
  • 삼각부등식 — 길이 1인 아무 x\mathbf{x} 에서 ∥(A+B)x∥≤∥Ax∥+∥Bx∥≤∥A∥+∥B∥\|(A+B)\mathbf{x}\| \le \|A\mathbf{x}\| + \|B\mathbf{x}\| \le \|A\| + \|B\| 이고, 왼쪽의 최댓값도 이 상한을 못 넘습니다.

셋 다 벡터 노름의 성질을 한 번씩 빌려 쓴 것뿐입니다. 덤으로 하나가 더 따라옵니다 — 단위행렬은 아무것도 늘리지 않으므로 어떤 벡터 노름에서 유도했든 ∥I∥=1\|I\| = 1 입니다. 이 사실이 뒤에서 판정 도구가 됩니다.

스펙트럼 노름

L2L^2 노름에서 유도된 것을 스펙트럼 노름이라 하고 ∥A∥2\|A\|_2 로 적습니다. 지난 두 글의 그림 — 어떤 행렬이든 단위원을 타원으로 보낸다 — 이 이미 답을 말하고 있습니다. 길이 1인 벡터가 갈 수 있는 가장 먼 곳은 타원의 긴 반지름이고 그것이 σ1\sigma_1 입니다. 특잇값 분해로 확인합니다.

∥Ax∥=∥UΣV⊤x∥=∥ΣV⊤x∥\|A\mathbf{x}\| = \|U\Sigma V^\top\mathbf{x}\| = \|\Sigma V^\top\mathbf{x}\|

UU 가 직교행렬이라 길이를 바꾸지 않으므로 지웠습니다. y=V⊤x\mathbf{y} = V^\top\mathbf{x} 로 두면 이것도 직교행렬이라 ∥y∥=∥x∥=1\|\mathbf{y}\| = \|\mathbf{x}\| = 1 이고,

∥Σy∥2=σ12y12+σ22y22+⋯≤σ12(y12+y22+⋯ )=σ12\|\Sigma\mathbf{y}\|^2 = \sigma_1^2y_1^2 + \sigma_2^2y_2^2 + \cdots \le \sigma_1^2(y_1^2 + y_2^2 + \cdots) = \sigma_1^2

σ1\sigma_1 이 가장 크므로 각 항의 계수를 σ12\sigma_1^2 으로 키운 것이고, 괄호 안은 ∥y∥2=1\|\mathbf{y}\|^2 = 1 입니다. 그리고 y=(1,0,…,0)\mathbf{y} = (1,0,\dots,0) 일 때, 즉 x=v1\mathbf{x} = \mathbf{v}_1 일 때 등호가 성립합니다.

 ∥A∥2=σ1=σmax⁡ \boxed{\ \|A\|_2 = \sigma_1 = \sigma_{\max}\ }

최댓값이 실제로 도달된다는 점이 중요합니다. 상한이 아니라 정확한 값이고, 그 값을 내는 입력 방향이 v1\mathbf{v}_1 이라는 것까지 알려 줍니다. 이름에 '스펙트럼'이 붙은 것은 이 값이 A⊤AA^\top A 의 스펙트럼 — 고윳값 전체 — 의 최댓값에서 나오기 때문입니다. 식으로 적으면 ∥A∥22=λmax⁡(A⊤A)\|A\|_2^2 = \lambda_{\max}(A^\top A) 입니다.

단위원 위에서 ‖Ax‖가 가장 커지는 방향이 v₁이고 그 값이 σ₁이라는 그림

1-노름과 ∞-노름

벡터의 자를 L1L^1 이나 L∞L^\infty 로 바꾸면 유도 노름이 달라지고, 놀랍게도 둘 다 특잇값 없이 성분만 보고 바로 나옵니다. L1L^1 이 유도한 1-노름은 각 열의 절댓값 합 가운데 가장 큰 것, 곧 최대 열합이고, L∞L^\infty 가 유도한 ∞-노름은 최대 행합입니다.

∥A∥1=max⁡j∑i∣aij∣,∥A∥∞=max⁡i∑j∣aij∣\|A\|_1 = \max_j \sum_i |a_{ij}|, \qquad \|A\|_\infty = \max_i \sum_j |a_{ij}|

1-노름 쪽을 보면 이유가 짧습니다. Ax=x1a1+x2a2+⋯A\mathbf{x} = x_1\mathbf{a}_1 + x_2\mathbf{a}_2 + \cdots 로 열의 조합이니 ∥Ax∥1≤∑j∣xj∣ ∥aj∥1≤(max⁡j∥aj∥1) ∥x∥1\|A\mathbf{x}\|_1 \le \sum_j |x_j|\,\|\mathbf{a}_j\|_1 \le (\max_j\|\mathbf{a}_j\|_1)\,\|\mathbf{x}\|_1 이고, 가장 큰 열 하나만 뽑는 x=ej\mathbf{x} = \mathbf{e}_j 에서 등호가 됩니다. L1L^1 단위공의 꼭짓점이 표준기저이므로 최대가 꼭짓점에서 나는 것입니다. ∞-노름은 반대로 한 행을 붙잡습니다 — L∞L^\infty 단위공의 꼭짓점은 성분이 전부 ±1\pm1 인 벡터이고, 그 부호를 어떤 행의 부호와 맞추면 그 행의 절댓값 합이 그대로 출력 성분 하나가 됩니다.

이 둘로 스펙트럼 노름에 상한을 공짜로 겁니다.

∥A∥2≤∥A∥1 ∥A∥∞\|A\|_2 \le \sqrt{\|A\|_1\,\|A\|_\infty}

증명에는 곱의 노름을 노름의 곱으로 누르는 성질이 한 번 쓰이므로, 그 성질을 세우는 「부분곱셈성」 절에서 마저 봅니다. 값이 어떻게 나오는지는 바로 아래 손계산에서 확인합니다 — 거대한 행렬에서 특잇값 분해를 돌리기 전에 덧셈만으로 스펙트럼 노름의 크기를 가늠할 수 있다는 것이 이 부등식의 쓸모입니다.

프로베니우스 노름과 손계산

프로베니우스 노름

다른 자도 하나 있습니다. 행렬을 길게 편 벡터로 보고 그 길이를 재는 것입니다.

∥A∥F=∑i,jaij2\|A\|_F = \sqrt{\sum_{i,j}a_{ij}^2}

이것을 프로베니우스 노름이라고 합니다. 유도 노름이 아니라 성분을 직접 세는 방식이라 계산이 훨씬 싸고, 그래서 실무에서 «행렬이 얼마나 큰가»를 대충 볼 때 가장 많이 쓰입니다. 가중치 감쇠가 더하는 벌점 λ∑w2\lambda\sum w^2 도 층마다 보면 이 노름의 제곱입니다.

이 값도 특잇값으로 표현됩니다. A⊤AA^\top A 의 (i,i)(i,i) 성분이 ii 번 열의 제곱합이므로 대각합이 곧 모든 성분의 제곱합입니다.

∥A∥F2=tr⁡(A⊤A)\|A\|_F^2 = \operatorname{tr}(A^\top A)

그리고 「고윳값의 합은 대각합」이라는 관계에서 tr⁡(A⊤A)=∑iλi(A⊤A)=∑iσi2\operatorname{tr}(A^\top A) = \sum_i\lambda_i(A^\top A) = \sum_i\sigma_i^2 입니다.

 ∥A∥F=σ12+σ22+⋯+σr2 \boxed{\ \|A\|_F = \sqrt{\sigma_1^2 + \sigma_2^2 + \cdots + \sigma_r^2}\ }

두 노름은 같은 특잇값 목록을 다르게 요약합니다. 스펙트럼 노름은 가장 큰 하나만 보고, 프로베니우스 노름은 전부를 모읍니다. 그래서 부등식이 바로 나옵니다 — 랭크를 rr 이라 하면

σ1≤σ12+⋯+σr2≤r σ12⟹∥A∥2≤∥A∥F≤r ∥A∥2\sigma_1 \le \sqrt{\sigma_1^2+\cdots+\sigma_r^2} \le \sqrt{r\,\sigma_1^2} \qquad \Longrightarrow \qquad \|A\|_2 \le \|A\|_F \le \sqrt{r}\,\|A\|_2

왼쪽은 «전부 모은 것이 하나보다 크다», 오른쪽은 «전부가 최대치여도 rr 배까지»입니다. 왼쪽의 등호는 랭크 1일 때, 오른쪽의 등호는 특잇값이 전부 같을 때 성립합니다.

같은 특잇값 목록을 스펙트럼 노름과 프로베니우스 노름이 다르게 요약하는 그림

손계산

지난 두 글에서 쓴 A=(304500)A = \begin{pmatrix} 3 & 0 \\ 4 & 5 \\ 0 & 0 \end{pmatrix} 로 네 노름을 전부 구합니다. 특잇값은 45\sqrt{45} 와 5\sqrt5 였습니다.

스펙트럼 노름은 큰 쪽 하나입니다.

∥A∥2=45=35≈6.708\|A\|_2 = \sqrt{45} = 3\sqrt5 \approx 6.708

프로베니우스 노름은 두 방법으로 구해 맞춰 봅니다. 성분을 직접 세면

∥A∥F=32+42+52=9+16+25=50≈7.071\|A\|_F = \sqrt{3^2+4^2+5^2} = \sqrt{9+16+25} = \sqrt{50} \approx 7.071

특잇값으로 구하면 45+5=50\sqrt{45+5} = \sqrt{50} 으로 같습니다. 15번 글에서 검산으로 써 놓고 이유를 미뤄 둔 관계가 이것이었습니다. 랭크가 2이므로 부등식도 확인됩니다.

6.708≤7.071≤2×6.708=9.4876.708 \le 7.071 \le \sqrt2 \times 6.708 = 9.487

1-노름과 ∞-노름은 더하기만 합니다. 열합은 3+4+0=73+4+0 = 7 과 0+5+0=50+5+0 = 5 이므로 ∥A∥1=7\|A\|_1 = 7, 행합은 3, 9, 03,\ 9,\ 0 이므로 ∥A∥∞=9\|A\|_\infty = 9 입니다. 상한은 7×9=63≈7.937\sqrt{7 \times 9} = \sqrt{63} \approx 7.937 이고, 실제 6.7086.708 보다 18% 큽니다. 분해 없이 얻은 것치고는 가깝습니다.

A의 열합 7과 행합 9, 그리고 두 값으로 얻는 스펙트럼 노름의 상한 7.937

비유도 노름

프로베니우스 노름은 어떤 벡터 노름에서도 유도되지 않습니다. 판정은 앞에서 챙겨 둔 한 줄로 끝납니다 — 유도 노름이면 반드시 ∥I∥=1\|I\| = 1 인데,

∥In∥F=1+1+⋯+1=n\|I_n\|_F = \sqrt{1 + 1 + \cdots + 1} = \sqrt{n}

n≥2n \ge 2 이면 1이 아닙니다. 512×512512 \times 512 단위행렬이면 약 22.6입니다. 아무것도 늘리지 않는 행렬을 22.6이라고 재는 자이니, «최대 배율»이라는 해석이 프로베니우스 노름에는 없습니다. 특잇값으로 보면 당연합니다 — 단위행렬의 특잇값은 1이 nn 개이고, 프로베니우스 노름은 그 전부를 모읍니다.

그런데도 다음 절의 부분곱셈성 ∥AB∥F≤∥A∥F∥B∥F\|AB\|_F \le \|A\|_F\|B\|_F 은 만족합니다. ABAB 의 (i,j)(i,j) 성분은 AA 의 ii 행 ai\mathbf{a}_i 와 BB 의 jj 열 bj\mathbf{b}_j 의 내적이므로 코시-슈바르츠 부등식으로 (ai⋅bj)2≤∥ai∥2∥bj∥2(\mathbf{a}_i\cdot\mathbf{b}_j)^2 \le \|\mathbf{a}_i\|^2\|\mathbf{b}_j\|^2 이고, 모든 i,ji, j 에 대해 더하면

∥AB∥F2≤(∑i∥ai∥2)(∑j∥bj∥2)=∥A∥F2 ∥B∥F2\|AB\|_F^2 \le \Big(\sum_i\|\mathbf{a}_i\|^2\Big)\Big(\sum_j\|\mathbf{b}_j\|^2\Big) = \|A\|_F^2\,\|B\|_F^2

두 줄입니다. 그래서 프로베니우스 노름도 층을 쌓은 상한을 잡는 데 쓸 수는 있지만, 스펙트럼 노름보다 언제나 크거나 같으므로 더 헐거운 상한이 됩니다.

핵 노름

같은 특잇값 목록을 요약하는 방법이 하나 더 있습니다. 제곱 없이 그대로 더한 ∥A∥∗=σ1+σ2+⋯+σr\|A\|_* = \sigma_1 + \sigma_2 + \cdots + \sigma_r 을 핵 노름이라고 합니다. 위의 AA 라면 45+5≈6.708+2.236=8.944\sqrt{45}+\sqrt5 \approx 6.708 + 2.236 = 8.944 입니다. 벡터에 비유하면 특잇값 목록의 L∞L^\infty 가 스펙트럼 노름, L2L^2 가 프로베니우스 노름, L1L^1 이 핵 노름입니다.

이 세 번째 요약이 쓸모 있는 이유는 랭크와의 관계입니다. 랭크는 0이 아닌 특잇값의 개수라 특잇값 목록의 «L0L^0»인데, 개수를 직접 줄이는 최적화는 볼록하지 않아 풀기 어렵습니다. 벡터에서 0이 아닌 성분 개수 대신 L1L^1 을 벌점으로 거는 것처럼, 행렬에서는 랭크 대신 핵 노름을 벌점으로 걸면 볼록한 문제가 됩니다. 어려운 문제를 풀 수 있는 볼록 문제로 바꾸는 이 대체를 볼록 완화라고 부르고, 빈칸이 많은 평점 행렬을 저랭크로 채우는 추천 시스템의 행렬 완성이 이 방법을 씁니다. 지난 글의 LoRA가 랭크를 rr 로 못 박아 두는 방식이었다면, 핵 노름은 랭크를 벌점으로 부드럽게 누르는 방식입니다.

부분곱셈성

스펙트럼 노름의 곱

행렬 노름에는 벡터 노름에 없는 성질이 하나 있습니다. 곱의 노름이 노름의 곱을 넘지 않는다는 ∥AB∥≤∥A∥ ∥B∥\|AB\| \le \|A\|\,\|B\| 를 부분곱셈성이라고 합니다.

스펙트럼 노름에서는 정의만으로 두 줄입니다. 어떤 x\mathbf{x} 에 대해서든

∥ABx∥≤∥A∥2 ∥Bx∥≤∥A∥2 ∥B∥2 ∥x∥\|AB\mathbf{x}\| \le \|A\|_2\,\|B\mathbf{x}\| \le \|A\|_2\,\|B\|_2\,\|\mathbf{x}\|

유도 노름의 정의가 «∥Az∥≤∥A∥ ∥z∥\|A\mathbf{z}\| \le \|A\|\,\|\mathbf{z}\| 가 모든 z\mathbf{z} 에 성립한다»는 말과 같으므로, 그것을 두 번 쓴 것뿐입니다. 같은 논리가 어떤 유도 노름에서도 통합니다.

앞에서 미뤄 둔 상한 ∥A∥2≤∥A∥1∥A∥∞\|A\|_2 \le \sqrt{\|A\|_1\|A\|_\infty} 가 이것으로 풀립니다. 먼저 Av=λvA\mathbf{v} = \lambda\mathbf{v} 이면 ∣λ∣ ∥v∥=∥Av∥≤∥A∥ ∥v∥|\lambda|\,\|\mathbf{v}\| = \|A\mathbf{v}\| \le \|A\|\,\|\mathbf{v}\| 이므로 고윳값의 절댓값은 어떤 유도 노름도 넘지 못합니다. 이것을 A⊤AA^\top A 에 1-노름으로 쓰고 부분곱셈성을 붙이면

∥A∥22=λmax⁡(A⊤A)≤∥A⊤A∥1≤∥A⊤∥1 ∥A∥1=∥A∥∞ ∥A∥1\|A\|_2^2 = \lambda_{\max}(A^\top A) \le \|A^\top A\|_1 \le \|A^\top\|_1\,\|A\|_1 = \|A\|_\infty\,\|A\|_1

마지막 등호는 전치하면 열이 행이 되어 최대 열합이 최대 행합으로 바뀐다는 것입니다.

부분곱셈성에서 요점은 등호가 아니라 부등호라는 데 있습니다. AA 가 가장 크게 늘리는 방향과 BB 가 결과를 내놓는 방향이 다르면 곱은 예측보다 작아집니다. 숫자로 봅니다.

W1=(1.5000.8),W2=(1.20.401.1)W_1 = \begin{pmatrix} 1.5 & 0 \\ 0 & 0.8\end{pmatrix}, \qquad W_2 = \begin{pmatrix} 1.2 & 0.4 \\ 0 & 1.1\end{pmatrix}

값
∥W1∥2\|W_1\|_2 1.500
∥W2∥2\|W_2\|_2 1.373
곱의 상한 ∥W1∥2∥W2∥2\|W_1\|_2\|W_2\|_2 2.060
실제 ∥W2W1∥2\|W_2W_1\|_2 1.837

두 층만으로도 상한이 실제보다 12% 큽니다.

층별 상한

이 여유는 층마다 곱해집니다. 64×6464 \times 64 무작위 행렬을 성분 분산이 1/641/64 이 되게 뽑아 스무 개를 차례로 곱해 봅니다. 층 하나의 스펙트럼 노름은 2 안팎이므로 층별 노름의 곱은 층마다 대략 두 배씩 불어납니다. 그런데 곱해진 행렬의 실제 스펙트럼 노름은 3~4 근처에서 좀처럼 움직이지 않습니다.

열 층이면 층별 곱이 817인데 실제는 3.70이라 상한이 실제의 221배이고, 스무 층이면 636,752 대 3.08로 20만 배를 넘습니다. 이유는 앞의 두 층 예와 같습니다 — 한 층이 가장 크게 늘리는 방향 v1\mathbf{v}_1 을 앞 층의 출력이 정확히 겨냥할 까닭이 없고, 무작위 층끼리는 그 방향이 거의 늘 어긋납니다. 층별 곱은 모든 층의 최악이 한 줄로 맞춰지는 경우를 가정한 값이라, 깊을수록 그런 일이 일어날 확률과 멀어집니다.

층을 쌓을수록 층별 노름의 곱이 실제 배율에서 멀어지는 그림

그래서 층별 노름의 곱은 강건성을 «증명»할 때는 쓸 수 있어도 실제 모델이 얼마나 민감한지를 «추정»하는 데는 쓸모가 없습니다. 그래도 상한이라는 점은 변하지 않아서, 층마다 노름을 1 이하로 묶으면 전체도 1 이하가 보장됩니다. 뒤에서 볼 스펙트럼 정규화가 기대는 것이 이 방향입니다.

스펙트럼 반지름

13번 글의 스펙트럼 반지름 ρ(A)\rho(A), 곧 고윳값 절댓값의 최댓값과 헷갈리기 쉬우니 구별해 둡니다. 바로 위에서 보았듯 ρ(A)≤∥A∥2\rho(A) \le \|A\|_2 는 항상 성립하고 대칭 행렬에서는 등호가 되지만, 일반적으로는 다릅니다 — 전단 (1101)\begin{pmatrix}1&1\\0&1\end{pmatrix} 이 ρ=1\rho = 1 인데 ∥A∥2=1.618\|A\|_2 = 1.618 이었던 것이 그 예입니다.

부분곱셈성은 ∥Ak∥2≤∥A∥2k\|A^k\|_2 \le \|A\|_2^k 를 주지만, 같은 행렬을 거듭 곱할 때 실제로 커지는 속도는 ρ\rho 가 정합니다. 전단을 스무 번 곱하면 ∥A20∥2≈20.05\|A^{20}\|_2 \approx 20.05 인데 상한 1.618201.618^{20} 은 약 15,127입니다. 전단의 거듭제곱은 (1k01)\begin{pmatrix}1&k\\0&1\end{pmatrix} 이라 kk 에 비례해 느리게 자랄 뿐이고, ρ=1\rho = 1 이 말하는 대로 지수적으로 터지지는 않습니다. ρ\rho 는 반복 곱셈의 장기 운명을, ∥A∥2\|A\|_2 는 한 번 통과할 때의 최대 증폭을 말합니다.

ρ(A)와 ‖A‖₂가 각각 어떤 질문에 답하는지 대비한 표

립시츠 상수

립시츠 조건

이제 첫머리로 돌아옵니다. 함수 ff 가 입력의 차이를 최대 LL 배까지만 벌린다는 조건을 립시츠 조건이라 하고, 그런 LL 중 가장 작은 것을 립시츠 상수라고 합니다.

∥f(x)−f(y)∥≤L ∥x−y∥\|f(\mathbf{x}) - f(\mathbf{y})\| \le L\,\|\mathbf{x}-\mathbf{y}\|

선형층 f(x)=Wxf(\mathbf{x}) = W\mathbf{x} 에 넣어 보면 계산이 한 줄에 끝납니다.

∥Wx−Wy∥=∥W(x−y)∥≤∥W∥2 ∥x−y∥\|W\mathbf{x} - W\mathbf{y}\| = \|W(\mathbf{x}-\mathbf{y})\| \le \|W\|_2\,\|\mathbf{x}-\mathbf{y}\|

그리고 x−y\mathbf{x}-\mathbf{y} 가 v1\mathbf{v}_1 방향일 때 등호가 성립하므로 이보다 작은 LL 은 없습니다.

 선형층의 립시츠 상수=∥W∥2=σmax⁡ \boxed{\ \text{선형층의 립시츠 상수} = \|W\|_2 = \sigma_{\max}\ }

«가장 크게 늘리는 배율»과 «차이를 벌리는 최대 비율»이 같은 수였습니다. 하나는 벡터 하나를 넣어 재고 다른 하나는 두 입력의 차이를 재는데, 선형이라 그 둘이 같은 것을 묻습니다.

층을 쌓으면 부분곱셈성이 그대로 립시츠 상수에 적용됩니다. ReLU·시그모이드·탄젠트 같은 흔한 활성함수는 기울기의 절댓값이 1을 넘지 않아 립시츠 상수가 1 이하이므로, 전체 상수는 선형층의 스펙트럼 노름들의 곱으로 묶입니다.

Lnet≤∥W1∥2 ∥W2∥2⋯∥Wn∥2L_{\text{net}} \le \|W_1\|_2\,\|W_2\|_2\cdots\|W_n\|_2

여기서 세 기법이 한 줄에 놓입니다.

기법 실제로 하는 일 노름으로 말하면
그래디언트 클리핑 기울기 벡터의 크기가 임계값을 넘으면 줄인다 벡터의 L2L^2 노름에 상한을 건다
스펙트럼 정규화 가중치를 W/∥W∥2W/\|W\|_2 로 바꿔 쓴다 층의 립시츠 상수를 1로 고정한다
립시츠 제약 전체 함수가 입력 변화를 못 키우게 한다 층별 스펙트럼 노름의 곱을 묶는다

클리핑·스펙트럼 정규화·립시츠 제약이 각각 어느 자리에 상한을 거는지

그래디언트 클리핑

그래디언트 클리핑은 기울기 벡터 g\mathbf{g} 의 길이가 임계값 cc 를 넘을 때만 길이를 cc 로 줄이는 조작입니다.

g←g⋅min⁡ ⁣(1, c∥g∥)\mathbf{g} \leftarrow \mathbf{g}\cdot\min\!\left(1,\ \frac{c}{\|\mathbf{g}\|}\right)

∥g∥≤c\|\mathbf{g}\| \le c 이면 곱하는 수가 1이라 그대로 두고, 넘으면 c/∥g∥c/\|\mathbf{g}\| 를 곱해 길이가 정확히 cc 가 됩니다. 곱하는 수가 언제나 양수이므로 방향은 바뀌지 않고 크기만 잘립니다. g=(3,4)\mathbf{g} = (3, 4) 에 c=1c = 1 이면 ∥g∥=5\|\mathbf{g}\| = 5 라 (0.6,0.8)(0.6, 0.8) 이 되고, 이것은 원래 벡터와 같은 방향의 길이 1짜리입니다.

성분마다 [−1,1][-1, 1] 로 자르는 방식과 비교하면 차이가 드러납니다. 같은 (3,4)(3, 4) 가 (1,1)(1, 1) 이 되어 방향이 틀어집니다 — 손실을 가장 빨리 줄이는 방향이라는 기울기의 뜻이 사라지는 셈입니다. 노름으로 자르는 쪽이 표준이 된 이유가 이것입니다. 순환망에서 기울기가 터지는 까닭도 같은 언어로 읽힙니다 — 시간 단계마다 같은 가중치 행렬을 거꾸로 곱해 나가므로, 그 행렬이 늘리는 방향이 있으면 기울기 길이가 단계 수만큼 거듭제곱으로 불어날 수 있습니다.

스펙트럼 정규화

스펙트럼 정규화는 가중치를 쓰기 직전에 W/∥W∥2W/\|W\|_2 로 나누는 조작입니다. ∥W/∥W∥2∥2=∥W∥2/∥W∥2=1\|W/\|W\|_2\|_2 = \|W\|_2/\|W\|_2 = 1 이므로 가장 큰 특잇값이 정확히 1이 되고 나머지는 전부 1 이하로 눌립니다. 방향의 비율은 그대로 두고 전체 배율만 1에 맞추는 것입니다. GAN 판별자에 이것을 거는 이유는 판별자의 출력이 입력의 작은 변화에 급하게 튀지 않아야 생성자에게 쓸 만한 기울기가 전달되기 때문입니다.

대가도 같은 식에서 읽힙니다. 모든 특잇값이 1 이하이면 그 층은 어떤 방향으로도 입력을 늘리지 못합니다. 층을 몇 개 쌓든 전체 립시츠 상수가 1 이하이므로, 어딘가에서 기울기가 5인 함수가 필요해도 그것을 표현할 수 없습니다. 게다가 나눗셈은 모든 특잇값을 같은 비율로 줄이므로 원래 작던 특잇값은 더 작아져, 층을 거칠수록 신호가 점점 약해질 수 있습니다. 판별자처럼 민감도를 누르는 것이 목적인 자리에서는 이것이 원하는 성질이지만, 분류기에 그대로 걸면 표현력이 줄어듭니다.

편향과 정규화 층

층별 곱 ∥W1∥2⋯∥Wn∥2\|W_1\|_2\cdots\|W_n\|_2 가 전체를 묶으려면 모든 부품이 그 식 안에 들어와야 합니다. 들어오지 않는 것이 몇 있습니다.

  • 편향 — Wx+bW\mathbf{x}+\mathbf{b} 의 두 입력 차이를 구하면 b\mathbf{b} 가 지워지므로 립시츠 상수에는 영향이 없습니다. 대신 출력의 크기는 편향이 얼마든지 옮기므로, 스펙트럼 노름은 민감도를 묶을 뿐 출력 값을 묶지 않습니다.
  • 정규화 층 — 추론 때의 배치 정규화는 채널마다 γ/var+ϵ\gamma/\sqrt{\mathrm{var}+\epsilon} 를 곱하는 고정된 변환이라 그 배율이 1을 넘을 수 있고, 곱에 따로 넣어야 합니다. 층 정규화는 입력의 표준편차로 나누므로 입력이 거의 상수이면 배율이 작은 ϵ\epsilon 에만 막혀 매우 커지고, 곱에 넣을 만한 작은 상수가 없습니다.
  • 잔차 연결 — x+F(x)\mathbf{x} + F(\mathbf{x}) 의 립시츠 상수는 1+LF1 + L_F 까지 갑니다. FF 를 1로 묶어도 블록 하나가 2배까지 늘릴 수 있습니다.

점곱 어텐션도 전역적으로 립시츠가 아니라는 결과가 알려져 있습니다. 그래서 트랜스포머 전체의 립시츠 상수를 층별 곱으로 묶으려는 시도는 이 부품들을 먼저 바꿔 끼우는 데서 시작합니다.

거듭제곱법과 조건수

거듭제곱법

스펙트럼 정규화는 매 학습 스텝마다 ∥W∥2\|W\|_2 를 알아야 합니다. 그런데 4096×40964096\times4096 행렬의 특잇값 분해를 스텝마다 돌리는 것은 불가능합니다.

여기서 13번 글의 거듭제곱법이 돌아옵니다. σ12\sigma_1^2 은 W⊤WW^\top W 의 최대 고윳값이므로 곱셈만으로 얻을 수 있습니다. A⊤AA^\top A 로 실제로 돌려 봅니다.

kk σmax⁡\sigma_{\max} 추정
1 2.624
2 6.084
3 6.6990
4 6.70809
5 6.708203

무작위 벡터에서 출발했는데도 참값 45=6.708204\sqrt{45} = 6.708204 에 다섯 스텝 만에 소수점 다섯 자리까지 붙었습니다. 수렴 속도가 ∣λ2/λ1∣=5/45=1/9|\lambda_2/\lambda_1| = 5/45 = 1/9 이라 빠릅니다 — 원래 행렬의 갭이 σ2/σ1=1/3\sigma_2/\sigma_1 = 1/3 인데, 제곱해서 보므로 갭도 제곱되어 유리해집니다.

실무의 스펙트럼 정규화는 여기서 한 걸음 더 갑니다. 매 스텝 수렴할 때까지 돌리는 대신 벡터를 파라미터 옆에 들고 있으면서 스텝마다 한 번씩만 갱신합니다. 가중치가 한 스텝에 조금밖에 안 변하니 지난 스텝의 추정이 이미 거의 맞고, 반복 한 번이면 따라잡힙니다. 행렬-벡터 곱 두 번으로 스펙트럼 노름을 유지하는 셈이고, 이것이 큰 모델에서 이 기법을 쓸 수 있게 만든 지점입니다.

조건수

가장 큰 특잇값만으로는 모자랄 때가 있습니다. 가장 큰 것과 가장 작은 것의 비 κ(A)=σ1/σmin⁡\kappa(A) = \sigma_1/\sigma_{\min} 을 조건수라고 하며, 연립방정식 Ax=bA\mathbf{x} = \mathbf{b} 를 풀 때 b\mathbf{b} 의 상대 오차가 해에서 최대 몇 배로 불어나는지를 말합니다. 조건수는 노름 둘의 곱으로도 적힙니다. 정사각 가역행렬 A=UΣV⊤A = U\Sigma V^\top 의 역행렬은 A−1=VΣ−1U⊤A^{-1} = V\Sigma^{-1}U^\top 이라 특잇값이 1/σi1/\sigma_i 이고, 그중 가장 큰 것은 1/σmin⁡1/\sigma_{\min} 입니다.

∥A−1∥2=1σmin⁡⟹κ(A)=∥A∥2 ∥A−1∥2\|A^{-1}\|_2 = \frac{1}{\sigma_{\min}} \qquad \Longrightarrow \qquad \kappa(A) = \|A\|_2\,\|A^{-1}\|_2

W=(3113)W = \begin{pmatrix}3&1\\1&3\end{pmatrix} 로 확인합니다. 대칭이라 특잇값이 고윳값 4와 2이고 ∥W∥2=4\|W\|_2 = 4 입니다. 역행렬은 W−1=18(3−1−13)W^{-1} = \frac18\begin{pmatrix}3&-1\\-1&3\end{pmatrix} 이고 그 고윳값은 12\tfrac12 과 14\tfrac14 이므로 ∥W−1∥2=12\|W^{-1}\|_2 = \tfrac12 입니다. 곱하면 4×12=24 \times \tfrac12 = 2 로 σ1/σmin⁡=4/2\sigma_1/\sigma_{\min} = 4/2 와 같습니다. 정사각형이 아닌 AA 도 유사역행렬로 같은 값을 정의하며, 위의 3×23\times 2 행렬은 45/5=3\sqrt{45}/\sqrt5 = 3 입니다.

역거듭제곱법

거듭제곱법은 가장 큰 것만 줍니다. 가장 작은 특잇값이 필요하면 뒤집어서 찾습니다. (A⊤A)−1(A^\top A)^{-1} 의 고윳값은 1/σi21/\sigma_i^2 이라 가장 큰 것이 1/σmin⁡21/\sigma_{\min}^2 이므로, 이 행렬에 거듭제곱법을 쓰면 σmin⁡\sigma_{\min} 쪽 방향으로 벡터가 붙습니다. 이것을 역거듭제곱법이라고 합니다. 실제로는 역행렬을 만들지 않고 스텝마다 A⊤A y=xA^\top A\,\mathbf{y} = \mathbf{x} 를 풀어 y\mathbf{y} 를 얻습니다. 곱셈 대신 연립방정식 풀이가 들어가므로 한 스텝이 더 비싸지만, 조건수를 재려면 이 값이 필요합니다.

갭과 수렴

거듭제곱법이 빨랐던 것은 σ1\sigma_1 과 σ2\sigma_2 가 멀었기 때문입니다. 스텝마다 v2\mathbf{v}_2 쪽 성분이 (σ2/σ1)2(\sigma_2/\sigma_1)^2 배씩 줄어드므로, 두 값이 붙어 있으면 이 비가 1에 가까워 좀처럼 줄지 않습니다. 특잇값을 1, 0.98, 0.5, 0.31,\ 0.98,\ 0.5,\ 0.3 으로 맞춘 4×44\times4 행렬로 돌리면 다섯 스텝 뒤 추정값은 0.998인데 벡터와 v1\mathbf{v}_1 의 코사인은 0.950에 불과하고, 스무 스텝이어도 0.984입니다. 백 스텝을 돌아야 추정값이 0.999999가 됩니다.

추정값은 한쪽으로만 틀립니다. 길이 1인 벡터에 대한 x⊤W⊤Wx\mathbf{x}^\top W^\top W\mathbf{x} 가 언제나 σ12\sigma_1^2 이하이기 때문입니다. 그래서 거듭제곱법의 추정은 항상 실제보다 작고, 스펙트럼 정규화로 나눈 가중치의 노름은 1보다 조금 클 수 있습니다. 갭이 작은 행렬에서 벡터까지 필요하면 시작 벡터를 여러 개 잡아 함께 돌리고 스텝마다 서로 직교하게 맞춥니다. 이렇게 하면 위쪽 둘을 한 덩어리로 잡으므로 느린 비 σ2/σ1\sigma_2/\sigma_1 대신 셋째와의 비 σ3/σ2\sigma_3/\sigma_2 가 속도를 정하고, 덩어리 안의 둘은 마지막에 2×22\times2 짜리 작은 문제로 정확히 가릅니다.

코드로 확인하기

네 노름

import numpy as np

A = np.array([[3., 0], [4, 5], [0, 0]])

for p in [1, 2, np.inf, 'fro', 'nuc']:
    print(p, np.linalg.norm(A, p))
# 1 7.0
# 2 6.70820393249937
# inf 9.0
# fro 7.0710678118654755
# nuc 8.94427190999916

print(np.sqrt(np.linalg.norm(A, 1) * np.linalg.norm(A, np.inf)))  # 7.937253933193772

1-노름과 ∞-노름이 손으로 구한 7과 9이고, 스펙트럼 노름은 그 둘로 만든 상한 7.937 아래에 있습니다. 핵 노름 8.944는 두 특잇값의 합입니다. 단위행렬로는 프로베니우스 노름이 유도 노름이 아님을 눈으로 봅니다.

for n in [2, 4, 512]:
    I = np.eye(n)
    print(n, np.linalg.norm(I, 2), np.linalg.norm(I, 'fro'))
# 2 1.0 1.4142135623730951
# 4 1.0 2.0
# 512 1.0 22.627416997969522

부분곱셈성과 립시츠

W1 = np.array([[1.5, 0], [0, 0.8]])
W2 = np.array([[1.2, 0.4], [0, 1.1]])
print(np.linalg.norm(W2 @ W1, 2),                    # 1.8365502591024236
      np.linalg.norm(W1, 2) * np.linalg.norm(W2, 2)) # 2.060125551410637
print(np.linalg.norm(W2 @ W1, 'fro'),                      # 2.0289898964755837
      np.linalg.norm(W1, 'fro') * np.linalg.norm(W2, 'fro'))  # 2.8497192844208357

rng = np.random.default_rng(0)
P, bound = np.eye(64), 1.0
for k in range(1, 21):
    W = rng.standard_normal((64, 64)) / np.sqrt(64)
    P, bound = W @ P, bound * np.linalg.norm(W, 2)
    if k in (1, 5, 10, 20):
        print(k, f'{bound:10.2f} {np.linalg.norm(P, 2):7.3f} {bound / np.linalg.norm(P, 2):8.1f}')
# 1       2.01   2.005      1.0
# 5      27.55   3.021      9.1
# 10     817.06   3.697    221.0
# 20  636751.77   3.082 206614.1

프로베니우스 노름의 곱 2.850은 스펙트럼 노름의 곱 2.060보다 더 헐겁습니다. 립시츠 상수가 정말 σ1\sigma_1 인지는 무작위로 두들겨 보면 됩니다.

rng = np.random.default_rng(1)
best = max(np.linalg.norm(A @ x) / np.linalg.norm(x)
           for x in rng.standard_normal((200_000, 2)))
print(best, np.linalg.norm(A, 2))
# 6.708203932113659 6.70820393249937   — 20만 번 찔러도 못 넘는다

추정과 조건수

def sigma_max(M, steps=5, seed=0):
    G = M.T @ M
    x = np.random.default_rng(seed).standard_normal(M.shape[1])
    for _ in range(steps):
        x = G @ x
        x = x / np.linalg.norm(x)
    return np.sqrt(x @ G @ x)          # 레일리 몫의 제곱근

def sigma_min(M, steps=20, seed=0):
    G = M.T @ M
    x = np.random.default_rng(seed).standard_normal(M.shape[1])
    for _ in range(steps):
        x = np.linalg.solve(G, x)      # 역행렬 대신 연립방정식
        x = x / np.linalg.norm(x)
    return np.sqrt(x @ G @ x)

print(sigma_max(A), np.linalg.norm(A, 2))   # 6.708202533650214 6.70820393249937
print(sigma_min(A), np.linalg.cond(A))      # 2.2360679774997894 3.000000000000001

W = np.array([[3., 1], [1, 3]])
print(np.linalg.norm(W, 2) * np.linalg.norm(np.linalg.inv(W), 2),  # 2.000000000000001
      np.linalg.cond(W))                                           # 2.0000000000000004
print(np.linalg.norm(W / np.linalg.norm(W, 2), 2))                  # 0.9999999999999997

sigma_max 의 마지막 줄 x⊤Gx\mathbf{x}^\top G\mathbf{x} 는 길이 1인 x\mathbf{x} 에 대한 이차형식이라, 14번 글의 «고유기저에서 ∑λiyi2\sum\lambda_iy_i^2» 그대로입니다. x\mathbf{x} 가 최대 고유벡터에 붙었으면 그 값이 λ1\lambda_1 이 되고, 덜 붙었으면 조금 모자랍니다 — 다섯 스텝의 추정 6.7082025가 참값 6.7082039보다 작은 것이 그 모습입니다. 마지막 줄은 스펙트럼 정규화가 나눗셈 한 번이라는 것을 보여 줍니다 — 부동소수점 오차를 빼면 정확히 1입니다.

정리

  • 유도 노름은 «가장 많이 늘어나는 배율» max⁡∥x∥=1∥Ax∥\max_{\|\mathbf{x}\|=1}\|A\mathbf{x}\| 입니다. 노름의 세 조건을 만족하고, 어떤 벡터 노름에서 유도했든 ∥I∥=1\|I\| = 1 입니다.
  • ∥A∥2=σmax⁡\|A\|_2 = \sigma_{\max} 이고 특잇값 분해로 두 줄에 증명됩니다. 1-노름은 최대 열합, ∞-노름은 최대 행합이라 더하기만으로 나오고, ∥A∥2≤∥A∥1∥A∥∞\|A\|_2 \le \sqrt{\|A\|_1\|A\|_\infty} 라는 상한을 줍니다.
  • ∥A∥F=∑σi2\|A\|_F = \sqrt{\sum\sigma_i^2} 이고 ∥A∥2≤∥A∥F≤r∥A∥2\|A\|_2 \le \|A\|_F \le \sqrt{r}\|A\|_2 입니다. ∥In∥F=n\|I_n\|_F = \sqrt n 이라 유도 노름이 아니지만 부분곱셈성은 만족합니다. 핵 노름 ∑σi\sum\sigma_i 는 랭크의 볼록 완화입니다.
  • 부분곱셈성 ∥AB∥≤∥A∥∥B∥\|AB\| \le \|A\|\|B\| 는 정의를 두 번 쓴 것입니다. 부등호라 층이 깊을수록 상한이 헐거워지고, 무작위 스무 층에서는 20만 배가 넘게 벌어졌습니다.
  • 선형층의 립시츠 상수가 곧 ∥W∥2\|W\|_2 입니다. 클리핑은 기울기 벡터의 노름을, 스펙트럼 정규화는 층의 립시츠 상수를, 립시츠 제약은 그 곱을 묶습니다. 편향·정규화 층·잔차 연결은 그 곱 밖에 있습니다.
  • σmax⁡\sigma_{\max} 는 거듭제곱법으로, σmin⁡\sigma_{\min} 은 역거듭제곱법으로 구하고, 둘의 비가 조건수 κ=∥A∥2∥A−1∥2\kappa = \|A\|_2\|A^{-1}\|_2 입니다. 갭이 작으면 수렴이 느려져 여러 벡터를 함께 돌립니다.

첫머리의 세 기법으로 돌아가면, 순환망의 클리핑 임계값과 GAN 판별자의 스펙트럼 정규화와 강건성 논문의 립시츠 제약은 모두 «이 부품이 입력을 최대 몇 배까지 늘리는가»에 상한을 거는 일이었습니다. 다른 점은 그 상한을 어디에 거느냐뿐입니다.

Av=λvA\mathbf{v} = \lambda\mathbf{v} 라는 한 줄에서 시작한 다섯 편이 여기서 닫힙니다. 고윳값에서 반복 곱셈의 운명이 나왔고, 대칭이라는 조건에서 직교 대각화와 부호 판정이 나왔고, 조건을 떼어 낸 자리에서 특잇값 분해와 랭크가 나왔고, 그것을 자르는 최적성에서 LoRA의 근거가 나왔으며, 마지막으로 그 특잇값들을 하나의 수로 요약하는 자들이 안정화 기법 셋을 한 언어로 묶었습니다. 선형대수 편이 답한 것은 «행렬이 벡터에 무엇을 하는가»였습니다. 다음 단원은 질문을 바꿉니다 — 모델이 내놓는 것이 왜 하나의 답이 아니라 확률분포인가입니다.


읽어주셔서 감사합니다. 😊

LATEST

수학의 최신 글

수학2026.09.07

양자화 오차: 격자 사상, 오차 분산, 이상치 채널

실수를 2^b개 격자에 사상할 때 오차의 분산이 왜 Δ²/12인지 유도하고, 그것이 비트당 6.02dB라는 SNR로 번역되는 과정을 실측과 대조했습니다. 이상치 하나가 나머지 값의 유효 비트를 어떻게 먹는지, 그리고 int4에서 성능이 무너지는 지점을 오차 예산으로 미리 계산하는 법까지.

중급18 MIN
수학2026.09.07

수치적으로 안정한 계산 패턴 모음

최댓값 빼기, 로그 공간, log1p·expm1, 분산의 두 공식, 정규화의 ε, fp32 누산, 역행렬 대신 solve — 프레임워크가 몰래 해 주는 일곱 가지를 하나씩 꺼내 각각 어떤 고장을 막는지 직접 재 봤습니다. 수식을 그대로 옮긴 코드가 왜 라이브러리보다 나쁜지에 대한 목록입니다.

중급22 MIN
수학2026.09.07

부동소수점은 어디서 새는가: 반올림, 상쇄, 더하는 순서

0.1 + 0.2가 0.3이 아닌 이유부터 시작해 머신 엡실론을 유도하고, 같은 16비트인데 fp16과 bf16이 서로 다른 지점에서 터지는 이유, 비슷한 수를 뺄 때 유효자리가 사라지는 파괴적 상쇄, 그리고 1,000만 개를 순서만 바꿔 더했을 때 오차가 백만 배 갈리는 실험까지 직접 재 봤습니다.

중급23 MIN