Lipschitz連続性とスペクトルノルム:ヤコビアンが決めるニューラルネットの安定性

ニューラルネットに、ほんのわずかなノイズを混ぜた画像を入れると、人間の目には同じに見えるのに、まったく違うクラスに分類されてしまうことがあります。これが「敵対的サンプル」です。逆に、入力を少し動かしても出力がほとんど動かないネットは、ノイズに強く、学習も安定します。

この「入力をちょっと動かしたとき、出力はどれだけ暴れるか」という最悪の感度を、たった1つの数で測るのが Lipschitz定数 です。そして微分可能な関数では、この最悪の感度がヤコビアン行列の スペクトルノルム(最大特異値) に一致します。

なぜこれを学ぶのでしょうか。Lipschitz定数とスペクトルノルムは、次のような場面の共通の土台になっているからです。

  • 生成モデルの安定化: WGAN(Wasserstein GAN)では critic を1-Lipschitzに保つことが理論の前提です。Spectral Normalization はこの制約を効率よく実現します。
  • 敵対的頑健性(certified robustness): ネットのLipschitz定数が小さいほど、小さな摂動では出力が動かず、「半径 $r$ 以内の攻撃では誤分類されない」と数学的に保証できます。

この記事は、ヤコビアンを扱った記事「ディープラーニングにヤコビアンが現れる理由」の直接の続編です。あの記事ではヤコビアンには3つの顔(積=逆伝播、行列式=確率の変化、ノルム=感度)があると述べました。本記事は、その3つ目の顔である「ノルム $\|J\|$」を徹底的に深掘りします。

本記事の内容

  • Lipschitz連続性の直感と定義、そして「最悪の傾き」という見方
  • 微分可能関数のLipschitz定数 = ヤコビアンの最大特異値、という核心
  • スペクトルノルムの復習とべき乗法による高速計算
  • 合成・各層への分解、Spectral Normalization、WGAN、敵対的頑健性への応用
  • Pythonでの実装と数値検証

前提知識

この記事を読む前に、以下の記事を読んでおくと理解が一気に深まります。

Lipschitz連続性とは

まず、坂道をイメージしてみましょう。なだらかな坂なら、1メートル横に歩いても標高はせいぜい数十センチしか変わりません。一方、崖のように切り立った斜面では、1メートル横に動いただけで標高が何メートルも変わります。「横の移動」に対して「縦の変化」がどれだけ大きくなりうるか — その上限を決める数が、坂の急さです。

Lipschitz連続性は、これを関数に一般化したものです。入力 $x$ を $y$ まで動かしたとき、出力 $f(x)$ と $f(y)$ の差は、入力の差の何倍までで収まるか。その「何倍」の上限が Lipschitz定数です。

数式で書くと、ある定数 $L \geq 0$ が存在して、すべての $x, y$ について次が成り立つとき、$f$ は $L$-Lipschitz連続 であると言います。

$$ \begin{equation} \| f(x) – f(y) \| \leq L \, \| x – y \| \end{equation} $$

ここで $\|\cdot\|$ はベクトルの大きさ(ノルム)です。左辺は出力の変化の大きさ、右辺は入力の変化の大きさを $L$ 倍したものです。この不等式は「出力の変化は、入力の変化の $L$ 倍を超えない」と言っているわけです。

両辺を $\|x – y\|$ で割ると、意味がさらにはっきりします。

$$ \begin{equation} \frac{\| f(x) – f(y) \|}{\| x – y \|} \leq L \quad (x \neq y) \end{equation} $$

左辺は、2点を結んだときの「平均的な傾き」です。Lipschitz定数 $L$ は、考えうるすべての2点について、この傾きの 上限 にあたります。言い換えると、$L$ は関数全体を通じての「最悪の傾き」なのです。

下の図は、この「最悪の傾き」を絵にしたものです。ある基準点を頂点として、傾き $\pm L$ の2本の直線が「錐(コーン)」を作ります。$f$ が $L$-Lipschitzであるとは、どの基準点から見ても、関数のグラフがこの錐の内側だけを通る、ということです。

Lipschitz連続の定義を錐で挟んで説明する図

この図から2つのことが読み取れます。まず、関数の曲線はどこを切り取っても錐の傾き $L$ より急になっていません。これが $L$-Lipschitzの視覚的な意味です。次に、$L$ は「どこか1点での傾き」ではなく「全域で最も急な箇所の傾き」だという点です。1か所でも錐をはみ出す急な箇所があれば、その関数は $L$-Lipschitzではなくなります。

ここまでで「最悪の傾き」というイメージがつかめました。では、微分可能な関数の場合、この最悪の傾きはどう計算すればよいのでしょうか。実はそこにヤコビアンが登場します。

微分可能関数のLipschitz定数はヤコビアンの最大特異値

1次元の関数 $f: \mathbb{R} \to \mathbb{R}$ を考えると話は単純です。平均値の定理から、2点間の傾きはどこかの点での微分係数に等しくなります。したがって、最悪の傾き、つまりLipschitz定数は導関数の絶対値の最大値です。

$$ \begin{equation} L = \sup_{x} | f'(x) | \end{equation} $$

問題は多次元のときです。入力も出力もベクトルになると、「傾き」は単なる数ではなく、ヤコビアン行列 $J(x)$ になります。$J(x)$ は入力の各方向の微小変化が、出力の各成分をどれだけ動かすかを並べた行列です。

このとき、Lipschitz定数は次のように書けます。

$$ \begin{equation} L = \sup_{x} \| J(x) \|_2 \end{equation} $$

ここで $\|J\|_2$ は行列 $J$ の 作用素ノルム(スペクトルノルム) です。これは「ヤコビアンが入力ベクトルを最大でどれだけ引き伸ばすか」という倍率を表します。なぜこの形になるのか、丁寧にたどってみましょう。

入力を方向 $u$(単位ベクトル)にほんの少し $\epsilon$ だけ動かすと、出力は1次近似で次のように変化します。

$$ \begin{equation} f(x + \epsilon u) – f(x) \approx \epsilon \, J(x) \, u \end{equation} $$

この出力変化の大きさは $\|\epsilon J(x) u\| = \epsilon \|J(x) u\|$ です。入力変化の大きさは $\epsilon \|u\| = \epsilon$ なので、局所的な傾きは次のようになります。

$$ \begin{equation} \frac{\| f(x+\epsilon u) – f(x) \|}{\epsilon} \approx \| J(x) \, u \| \end{equation} $$

ここで「最悪の方向 $u$」を選ぶと、傾きは最大になります。単位ベクトル $u$ を全方向に動かしたときの $\|J u\|$ の最大値、これがまさに行列のスペクトルノルムの定義です。

$$ \begin{equation} \| J \|_2 = \max_{\| u \| = 1} \| J u \| \end{equation} $$

つまり、ある点 $x$ での「最悪の傾き」は $\|J(x)\|_2$ で、それを全空間にわたって最大化したものが関数全体のLipschitz定数 $L = \sup_x \|J(x)\|_2$ になるわけです。これがヤコビアンの「3つ目の顔」、すなわちノルムが感度を決めるという話の正体です。

下の図は、$\|J\|_2$ が「最大の引き伸ばし倍率」であることを、線形写像 $A$(一定のヤコビアンだと思ってください)で可視化したものです。

単位円が線形写像で楕円に変わり、最大特異値が最大引き伸ばし倍率を表す図

左の単位円(すべての方向の単位ベクトルの集まり)は、$A$ を通すと右の楕円になります。楕円の長半径の長さが最大特異値 $\sigma_1 = 2.14$ で、これがスペクトルノルム $\|A\|_2$ です。短半径は最小特異値 $\sigma_2 = 0.84$ です。最も伸びる方向に入力を動かすと、出力は $\sigma_1$ 倍に拡大されます。これが「最悪の傾き」に対応します。

スペクトルノルムが最大特異値であることがわかりました。次に、その最大特異値を効率よく計算する方法を見ていきましょう。

スペクトルノルムは最大特異値 — べき乗法で速く求める

行列のスペクトルノルムは、定義上は最大特異値 $\sigma_1$ です。特異値分解 $A = U \Sigma V^\top$ を計算すれば $\Sigma$ の最大対角成分として得られますが、深層学習のように毎ステップ巨大な行列に対してこれをやると重すぎます。そこで、最大特異値だけを近似的に取り出す べき乗法(power iteration) が使われます。

直感から入りましょう。最大特異値は $A^\top A$ の最大固有値の平方根に等しいことが知られています。固有値分解の記事で見たように、行列を何度も同じベクトルに掛け続けると、そのベクトルは最大固有値に対応する固有ベクトルの方向にどんどん引き寄せられていきます。最大固有値の成分が一番速く増幅されるからです。これを利用します。

アルゴリズムはこうです。$M = A^\top A$ と置き、適当な単位ベクトル $v$ から始めて次を繰り返します。

$$ \begin{equation} v \leftarrow \frac{M v}{\| M v \|} \end{equation} $$

毎回ノルムで割って大きさを1に戻すのは、ベクトルが発散・消失しないようにするためです。十分繰り返すと $v$ は最大固有ベクトルに収束します。そのときの固有値(レイリー商)を取り、平方根をとれば最大特異値です。

$$ \begin{equation} \sigma_1 \approx \sqrt{ v^\top M v } = \sqrt{ v^\top A^\top A \, v } = \| A v \| \end{equation} $$

ここで最後の等号は、$\|Av\|^2 = (Av)^\top (Av) = v^\top A^\top A v$ という展開から出ます。つまり収束した $v$ に対して、単に $\|Av\|$ を計算すれば最大特異値が得られます。

下の図は、ランダムな行列に対してべき乗法を回したときの収束の様子です。

べき乗法の推定値が反復ごとに真の最大特異値に収束していくグラフ

このグラフから、べき乗法はわずか数回の反復で np.linalg.svd が返す真の最大特異値(破線)にほぼ一致することが読み取れます。収束の速さは2番目に大きい特異値との比に依存しますが、多くの実用的な行列では数反復で十分です。だからこそ深層学習では、毎ステップ1反復だけ回すという荒い近似でも、学習が進むにつれて行列がゆっくり変化するため、結果的に十分よい推定が得られます。

スペクトルノルムを速く計算できるようになりました。次は、層を積み重ねたネット全体のLipschitz定数を、各層のノルムからどう見積もるかを考えます。

合成写像のLipschitz定数は各層のノルムの積

ニューラルネットは層の合成です。$f = f_L \circ \cdots \circ f_2 \circ f_1$ のように、関数を次々につないだものと見なせます。では、各層のLipschitz定数がわかっているとき、全体のLipschitz定数はどうなるでしょうか。

答えはシンプルで、合成のLipschitz定数は各層のLipschitz定数の 積で上から押さえられます。2層の場合で導いてみましょう。$g$ が $L_g$-Lipschitz、$f$ が $L_f$-Lipschitzだとします。合成 $f \circ g$ について、

$$ \begin{equation} \| f(g(x)) – f(g(y)) \| \leq L_f \, \| g(x) – g(y) \| \end{equation} $$

まず外側の $f$ のLipschitz性を使い、$f$ の入力差 $\|g(x) – g(y)\|$ で押さえました。次に内側の $g$ のLipschitz性を使うと、

$$ \begin{equation} \| g(x) – g(y) \| \leq L_g \, \| x – y \| \end{equation} $$

なので、これを代入すると、

$$ \begin{equation} \| f(g(x)) – f(g(y)) \| \leq L_f \, L_g \, \| x – y \| \end{equation} $$

となります。つまり $f \circ g$ は $(L_f L_g)$-Lipschitzです。同じ議論を繰り返せば、$L$ 層のネット全体については次が成り立ちます。

$$ \begin{equation} \text{Lip}(f) \leq \prod_{\ell=1}^{L} L_\ell \end{equation} $$

これはとても便利です。各層のLipschitz定数さえ押さえれば、全体の上界が自動で得られるからです。下の図は、3層のネットでこの積を計算する例です。

合成写像のLipschitz定数が各層の積で押さえられることを示す図

この図から、各層が $L_1 = 1.5$、$L_2 = 0.8$、$L_3 = 2.0$ のとき、全体のLipschitz定数は $1.5 \times 0.8 \times 2.0 = 2.4$ 以下に収まることが読み取れます。注意したいのは、これはあくまで上界だという点です。実際のLipschitz定数はこれより小さいこともあります。各層が最悪の方向で同時に伸びるとは限らないからです。それでも、設計の指針としては「各層のノルムを掛けて1に近づける」だけで全体を制御できる、という強力な道具になります。

では、各層のLipschitz定数は具体的にどう求まるのでしょうか。線形層と活性化関数に分けて見てみましょう。

線形層は重み行列のスペクトルノルム、活性化は1-Lipschitz

ニューラルネットの層は、おおまかに「線形変換」と「活性化関数」に分けられます。それぞれのLipschitz定数を押さえれば、前節の積でネット全体が制御できます。

まず線形層 $f(x) = Wx + b$ を考えます。バイアス $b$ は差を取ると消えるので、

$$ \begin{equation} \| f(x) – f(y) \| = \| W(x – y) \| \leq \| W \|_2 \, \| x – y \| \end{equation} $$

最後の不等号はスペクトルノルムの定義そのものです。等号は $x – y$ が最大特異ベクトルの方向のときに達成されるので、線形層のLipschitz定数はちょうど重み行列のスペクトルノルム $\|W\|_2$ になります。これが、各層のノルムを掛け合わせるときに各層から出てくる数の正体です。

次に活性化関数です。代表的な ReLU、tanh、sigmoid はいずれも 1-Lipschitz です。理由は、これらの導関数の絶対値が1を超えないからです。

  • ReLU: $\text{ReLU}'(x)$ は $0$ または $1$ なので、傾きは最大でも1です。
  • tanh: $\tanh'(x) = 1 – \tanh^2(x)$ で、最大値は $x=0$ での1です。
  • sigmoid: $\sigma'(x) = \sigma(x)(1 – \sigma(x))$ で、最大値は $x=0$ での $1/4$ です。よってsigmoidは $1/4$-Lipschitz、つまり1-Lipschitzでもあります。

要素ごとに作用する活性化関数のLipschitz定数は、各成分の傾きの最大値で押さえられます。どれも1以下なので、活性化はネット全体のLipschitz定数を増やしません。したがって ネット全体のLipschitz定数は、実質的に各線形層のスペクトルノルムの積で決まります

$$ \begin{equation} \text{Lip}(\text{net}) \leq \prod_{\ell} \| W_\ell \|_2 \end{equation} $$

この事実は重要です。ネットを1-Lipschitzにしたければ、各重み行列のスペクトルノルムを1以下に抑えればよい、ということだからです。これを実現するのが次に説明する Spectral Normalization です。

Spectral Normalization — 重みを最大特異値で割る

各重み行列のスペクトルノルムを1にする一番素直な方法は、重みをその最大特異値で割ることです。Miyato らが2018年に提案した Spectral Normalization はまさにこれを行います。

学習中の各重み行列 $W$ に対して、正規化された重みを次のように定義します。

$$ \begin{equation} \bar{W} = \frac{W}{\sigma_1(W)} \end{equation} $$

ここで $\sigma_1(W)$ は $W$ の最大特異値です。すると正規化後の最大特異値は $\sigma_1(\bar{W}) = \sigma_1(W) / \sigma_1(W) = 1$ になり、その層は確実に1-Lipschitzになります。前節の積の議論から、全層に適用すればネット全体が1-Lipschitzになります。

問題は、毎ステップ $\sigma_1(W)$ をフルの特異値分解で求めるのは重いことです。ここでべき乗法が効きます。前のステップの特異ベクトルを使い回し、1ステップにつきべき乗法を たった1反復 だけ回して $\sigma_1$ を近似します。重みは学習でゆっくりしか変わらないので、この荒い近似でも実用上十分な精度が出ます。これが Spectral Normalization が安価で済む理由です。

下の図は、ランダムな重み行列に Spectral Normalization を適用する前と後で、写像がどう変わるかを見たものです。

Spectral Normalization 適用前後で写像の引き伸ばし方が変わる図

左の正規化前では、入力のグリッド(灰色)が出力(オレンジ)で大きく引き伸ばされ、スペクトルノルムは3.43に達しています。右の正規化後では、最大の引き伸ばし方向が1倍に抑えられ、出力が入力からはみ出さなくなっています。スペクトルノルムはちょうど1.00です。重みを最大特異値で割るだけで、最も暴れる方向を確実に抑え込めることが視覚的にわかります。

Spectral Normalization は、特にGANのような不安定な学習で威力を発揮します。なぜGANに効くのか、その背景にあるWGANの理論を次に見ていきましょう。

WGANとの接続 — criticは1-Lipschitzでなければならない

GANの学習が不安定になる大きな原因は、生成分布と真の分布が重ならないとき、両者の「近さ」を測る指標(JSダイバージェンスなど)が飽和してしまい、勾配が消えることでした。WGAN(Wasserstein GAN)は、距離の測り方を Wasserstein距離(地球を動かす距離) に変えてこれを解決します。

Wasserstein距離は計算が難しいのですが、Kantorovich-Rubinstein双対という定理を使うと、次のように書き換えられます。

$$ \begin{equation} W(P, Q) = \sup_{\| D \|_{\text{Lip}} \leq 1} \; \mathbb{E}_{x \sim P}[D(x)] – \mathbb{E}_{x \sim Q}[D(x)] \end{equation} $$

ここがポイントです。右辺の上限(sup)は、すべての1-Lipschitz関数 $D$ にわたって取られています。$D$ が critic(識別役)です。この式が意味を持つには、critic が1-Lipschitzでなければなりません。もし $D$ が好きなだけ急になれてしまうと、右辺はいくらでも大きくなり、Wasserstein距離としての意味を失います。

つまりWGANは、その理論の根幹で critic が1-Lipschitzであること を要求します。下の図は、この制約の意味を示したものです。

WGANのcriticが1-Lipschitzに制約される様子を示す図

青の critic は傾きが1以下に収まっており、許される領域(オレンジの錐)の中にあります。一方、赤い破線の critic は傾きが1を超えており、制約を破っています。制約のない critic は値を無限に引き離せてしまい、Wasserstein距離の推定が破綻します。

この1-Lipschitz制約をどう実現するかには、いくつかの流派があります。

  • Weight clipping: 重みを $[-c, c]$ に毎回クリップする。WGANの原論文の方法ですが、容量が制限されすぎる弱点があります。
  • Gradient penalty(WGAN-GP): 勾配のノルムが1から離れたらペナルティを課す。$\|\nabla D\| = \|J\|$ を1に近づける、まさにLipschitz制約の直接的な実装です。
  • Spectral Normalization: 前節の通り各層のスペクトルノルムを1にする。実装が軽く、安定しています。

このように、WGANの理論的要請(1-Lipschitz)と、スペクトルノルムによる実装が一本の線でつながっています。詳しくはWasserstein GANの記事も参照してください。Lipschitz制約は生成モデルだけでなく、モデルの安全性にも直結します。次は敵対的頑健性を見ましょう。

敵対的頑健性 — 小さいLは攻撃に強い

冒頭で触れた敵対的サンプルの話に戻ります。攻撃者は、入力に人間には見えない小さな摂動 $\delta$ を加えて、出力を大きく狂わせようとします。$f$ が $L$-Lipschitzなら、出力の変化は次で押さえられます。

$$ \begin{equation} \| f(x + \delta) – f(x) \| \leq L \, \| \delta \| \end{equation} $$

この式は安心材料です。Lipschitz定数 $L$ が小さいほど、同じ大きさの摂動 $\delta$ に対して出力の変化が小さくなる、と保証してくれるからです。下の図はこの直感を示しています。

Lipschitz定数の大小と敵対的摂動への強さの関係を示す図

左の $L=3$ の関数では、同じ入力摂動(オレンジの帯)に対して出力が大きく動きます。右の $L=0.6$ の関数では、同じ摂動でも出力の動きが小さく抑えられています。Lipschitz定数を小さく保つことが、そのまま摂動への鈍感さ、つまり頑健性につながることが読み取れます。

さらに、Lipschitz定数があると 証明つきの頑健性(certified robustness) が得られます。分類器の出力で、正解クラスのスコアと2番目に高いクラスのスコアの差を「マージン $M$」とします。出力が $M/2$ 以上動かなければ、順位は入れ替わらず、誤分類は起きません。Lipschitz性から出力の動きは $L\|\delta\|$ 以下なので、$L \|\delta\| < M/2$ である限り安全です。これを解くと保証半径が出ます。

$$ \begin{equation} \| \delta \| < \frac{M}{2L} \;\; \Rightarrow \;\; \text{誤分類されない} \end{equation} $$

入力に対するLipschitz定数を $L$ とすると、この半径 $r = M/(2L)$ の内側の摂動では絶対に判定が変わらない、と数学的に証明できます。下の図はこの考え方を示します。

certified robustnessにおける保証半径がマージンをLで割った量になることを示す図

この図から、正解クラスと次点クラスのスコア差(マージン $M$)が大きいほど、そして $L$ が小さいほど、保証半径が大きくなることが読み取れます。$L$ を小さく保つことが、攻撃に対する「証明書」の発行能力に直結するわけです。なお、ここでの係数は使うノルムの取り方によって $\sqrt{2}$ などの定数が変わりますが、「マージンを $L$ で割る」という構造は共通です。

頑健性の話で見たように、Lipschitz定数の制御は学習の安定性とも深く関わります。最後に、勾配の爆発・消失とスペクトルノルムの関係を見ましょう。

勾配の爆発・消失 — ノルムの積が1から離れると起きる

深いネットの学習でしばしば問題になるのが、勾配の爆発と消失です。逆伝播では、勾配が各層のヤコビアンを次々に掛けられながら入力側へ伝わっていきます。ヤコビアンの記事で見た「積としてのヤコビアン」がここに効いてきます。

勾配が通過する各層のスペクトルノルムを $\sigma_\ell$ とすると、$L$ 層を通った後の勾配の大きさは、おおまかに次のスケールで変化します。

$$ \begin{equation} \| \text{勾配} \| \;\sim\; \prod_{\ell=1}^{L} \sigma_\ell \end{equation} $$

ここで各層のノルムが平均的に $\sigma$ だとすると、積は $\sigma^L$ となります。指数関数なので、$\sigma$ が1からほんの少しずれるだけで、深さ $L$ に対して激しく変化します。

  • $\sigma > 1$ なら $\sigma^L$ は層が深くなるほど爆発します。勾配爆発です。
  • $\sigma < 1$ なら $\sigma^L$ は層が深くなるほど0に近づきます。勾配消失です。
  • $\sigma = 1$ のときだけ、勾配の大きさが保たれます。

下の図は、$\sigma = 1.3, 1.0, 0.7$ の3つの場合について、ノルムの積が層の深さでどう変わるかを対数軸で描いたものです。

各層のスペクトルノルムの積が層の深さで爆発または消失する様子を対数軸で示した図

この図から、$\sigma=1.3$ では30層で積が約1000倍に達し(勾配爆発)、$\sigma=0.7$ では約10万分の1に減衰している(勾配消失)ことが読み取れます。$\sigma=1.0$ の線だけが水平に保たれています。これは、各層のスペクトルノルムを1付近に保つこと(直交初期化やSpectral Normalizationなど)が、深いネットを安定して学習させる鍵であることを意味します。Lipschitz制御は単に頑健性のためだけでなく、学習そのものの安定性のためにも重要なのです。

ここまでの理論を、実際のコードで確かめてみましょう。

Pythonでの実装と検証

理論を裏付けるために、3つのことをコードで確認します。第一にべき乗法と np.linalg.svd の一致、第二にSpectral Normalizationで層のスペクトルノルムが1になること、第三に合成ネットのLipschitz上界が各層ノルムの積になることです。

べき乗法と特異値分解の一致

まず、べき乗法で求めたスペクトルノルムが、特異値分解の最大特異値と一致することを確かめます。

import numpy as np

rng = np.random.default_rng(0)

def spectral_norm_power(A, n_iter=500):
    """べき乗法で最大特異値(スペクトルノルム)を求める。"""
    M = A.T @ A
    v = rng.normal(size=A.shape[1])
    v /= np.linalg.norm(v)
    for _ in range(n_iter):
        v = M @ v
        v /= np.linalg.norm(v)
    return np.linalg.norm(A @ v)  # = sqrt(v^T A^T A v)

# さまざまなサイズの行列で比較
for n in [3, 5, 8, 12, 20, 40]:
    A = rng.normal(size=(n, n))
    pw = spectral_norm_power(A)
    sv = np.linalg.svd(A, compute_uv=False)[0]
    print(f"n={n:2d}  べき乗法={pw:.6f}  svd={sv:.6f}  誤差={abs(pw-sv):.2e}")

このコードは、行列サイズを変えながらべき乗法と特異値分解の最大特異値を比較します。実行すると、両者の誤差はおおむね $10^{-13}$ 以下、つまり機械精度レベルで一致します。べき乗法が最大特異値の正しい計算法であることが数値的に確認できました。下の図はこの一致を視覚化したものです。

べき乗法とnp.linalg.svdの最大特異値が完全に一致することを示す図

この図から、行列サイズによらず2つの方法の点が完全に重なっていることが読み取れます。注釈の通り、最大誤差は $2.7 \times 10^{-15}$ で、浮動小数点の限界に達しています。べき乗法は最大特異値だけを取り出す高速かつ正確な手段だと確認できます。

Spectral Normalizationで層を1-Lipschitzにする

次に、重み行列をスペクトルノルムで割ると、本当に層のスペクトルノルムが1になることを確かめます。

import numpy as np
rng = np.random.default_rng(1)

# ランダムな重み行列
W = rng.normal(size=(6, 6)) * 2.0
sigma = np.linalg.svd(W, compute_uv=False)[0]
print(f"正規化前のスペクトルノルム: {sigma:.4f}")

# Spectral Normalization: 最大特異値で割る
W_sn = W / sigma
sigma_sn = np.linalg.svd(W_sn, compute_uv=False)[0]
print(f"正規化後のスペクトルノルム: {sigma_sn:.4f}")

# 1-Lipschitz の確認: 任意の入力差に対し出力差が入力差以下
errs = []
for _ in range(100000):
    x = rng.normal(size=6)
    y = rng.normal(size=6)
    ratio = np.linalg.norm(W_sn @ (x - y)) / np.linalg.norm(x - y)
    errs.append(ratio)
print(f"出力差/入力差 の最大値: {max(errs):.4f} (<= 1 なら1-Lipschitz)")

このコードは、正規化前後のスペクトルノルムを比べ、さらに10万通りのランダムな入力ペアで「出力の変化÷入力の変化」が1を超えないことを確認します。実行すると、正規化後のスペクトルノルムはちょうど1.0000になり、出力差と入力差の比の最大値も1.0000以下に収まります。重みを最大特異値で割るだけで、層が確実に1-Lipschitzになることが実測できました。比の最大値が1にぴったり届くのは、入力差が最大特異ベクトルの方向に揃ったときだけです。

合成ネットのLipschitz上界は各層ノルムの積

最後に、複数の線形層と活性化を重ねたネットで、全体のLipschitz定数が各層のスペクトルノルムの積で上から押さえられることを確認します。

import numpy as np
rng = np.random.default_rng(2)

# 3層のネット: 線形 -> ReLU -> 線形 -> ReLU -> 線形
Ws = [rng.normal(size=(8, 8)) for _ in range(3)]
sigmas = [np.linalg.svd(W, compute_uv=False)[0] for W in Ws]
bound = np.prod(sigmas)  # 各層ノルムの積 = Lipschitz上界
print("各層のスペクトルノルム:", [f"{s:.3f}" for s in sigmas])
print(f"Lipschitz上界(積): {bound:.4f}")

def net(x):
    h = x
    for i, W in enumerate(Ws):
        h = W @ h
        if i < len(Ws) - 1:
            h = np.maximum(h, 0.0)  # ReLU(1-Lipschitz)
    return h

# 実際の最悪傾きをサンプリングで推定
worst = 0.0
for _ in range(200000):
    x = rng.normal(size=8)
    y = x + 1e-3 * rng.normal(size=8)
    ratio = np.linalg.norm(net(x) - net(y)) / np.linalg.norm(x - y)
    worst = max(worst, ratio)
print(f"サンプリングした最悪傾き: {worst:.4f}")
print(f"上界を超えていないか: {worst <= bound + 1e-9}")

このコードは、3つの線形層とReLUからなるネットについて、各層スペクトルノルムの積(理論上の上界)と、実際にサンプリングして測った最悪の傾きを比べます。実行すると、サンプリングで得た最悪傾きは必ず上界以下に収まります。実測値が上界より小さくなるのは、各層が同時に最悪の方向で伸びることはまれだからです。ReLUが入ると、活性化が一部の成分を0にするため、実効的な傾きはさらに下がります。これにより「各層のノルムの積が全体のLipschitz定数を上から押さえる」という理論が、コードでも確認できました。

3つの検証はいずれも理論と一致しました。べき乗法は正確、Spectral Normalizationは確実に1-Lipschitzを作り、合成の上界は積で与えられます。これでLipschitz制御の全体像が、理論とコードの両面から腹落ちしたはずです。

補遺:飛ばした証明をすべて埋める

この補遺は読み飛ばしても大丈夫です。 ここから先は、本文で「知られています」「定義そのものです」と流した主張を一行ずつ証明する部分です。前半までで「∥J∥が安定性を決める」というイメージは押さえられているので、結論を使えれば十分という方は次の節へ進んでください。証明を自分の手で追いたい方、論文の付録を読めるようになりたい方のための部分です。

本文では直感を優先して、いくつかの主張を「〜であることが知られています」「定義そのものです」と流しました。ここではそれらを、初見の読者でも論理の穴なく追えるように、1行ずつ証明します。数学そのものは標準的(Boyd & Vandenberghe『Convex Optimization』、Horn & Johnson『Matrix Analysis』、Miyato ら 2018 の Spectral Normalization 論文に準拠)ですが、この分野が初めての方を想定して、使う記号は初出で一言ずつ補います。

証明全体を通じて、ベクトルのノルム $\|\cdot\|$ はユークリッドノルム($\|x\| = \sqrt{\sum_i x_i^2}$)、行列のノルム $\|\cdot\|_2$ はそれに付随する作用素ノルム(後で定義します)を指します。$\sup$(supremum, 上限)は「集合の最小上界」、つまり最大値が存在しないときも含めて『それ以上は超えない一番きつい上の壁』を表す記号です。最大値が存在すればそれと一致します。$\lambda$ は固有値、$\sigma$ は特異値を表します。

補遺1:$L = \sup_x \|J(x)\|_2$ の証明

主張は2つに分かれます。$f: \mathbb{R}^n \to \mathbb{R}^m$ が連続微分可能($C^1$)でヤコビアン $J(x)$ を持つとき、

  1. (上から) $\displaystyle S := \sup_x \|J(x)\|_2$ が有限なら、$f$ は $S$-Lipschitz、つまり $\|f(y)-f(x)\| \le S\,\|y-x\|$ がすべての $x,y$ で成り立つ。
  2. (下から) Lipschitz定数 $L$ は $S$ を下回れない、すなわち $L \ge S$。

この2つを合わせると、最小のLipschitz定数(それを $L$ と書く)はちょうど $S = \sup_x \|J(x)\|_2$ になります。

ステップ1-1:線積分による表現。 $x$ と $y$ を結ぶ線分を $\gamma(t) = x + t(y-x)$($t \in [0,1]$)とパラメータ表示します。合成関数 $t \mapsto f(\gamma(t))$ を微分すると、連鎖律により

$$ \begin{equation} \frac{d}{dt} f(\gamma(t)) = J(\gamma(t)) \, \gamma'(t) = J\big(x + t(y-x)\big)\,(y-x) \end{equation} $$

です。ここで $\gamma'(t) = y-x$(線分なので速度は一定)を代入しました。微積分学の基本定理を各成分に適用して $t=0$ から $t=1$ まで積分すると、$f(\gamma(1)) – f(\gamma(0)) = f(y) – f(x)$ なので、

$$ \begin{equation} f(y) – f(x) = \int_0^1 J\big(x + t(y-x)\big)\,(y-x)\, dt \end{equation} $$

が得られます。これは「2点間の差は、途中のヤコビアンを線分に沿って積分したもの」という、平均値の定理のベクトル版です。

ステップ1-2:ノルムで上から押さえる。 両辺のノルムを取り、積分のノルムは被積分関数のノルムの積分以下である(三角不等式の積分版 $\|\int g\,dt\| \le \int \|g\|\,dt$)ことを使うと、

$$ \begin{equation} \| f(y) – f(x) \| = \left\| \int_0^1 J(\gamma(t))\,(y-x)\, dt \right\| \le \int_0^1 \big\| J(\gamma(t))\,(y-x) \big\|\, dt \end{equation} $$

となります。次に被積分関数を作用素ノルムで押さえます。作用素ノルムの定義(補遺2でも使う $\|A z\| \le \|A\|_2 \|z\|$)から、各 $t$ について

$$ \begin{equation} \big\| J(\gamma(t))\,(y-x) \big\| \le \| J(\gamma(t)) \|_2 \, \| y-x \| \le S\,\|y-x\| \end{equation} $$

です。最後の不等号は $\|J(\gamma(t))\|_2 \le \sup_x \|J(x)\|_2 = S$(上限の定義)によります。これを積分に戻すと、被積分関数が定数 $S\|y-x\|$ で押さえられ、$\int_0^1 dt = 1$ なので、

$$ \begin{equation} \| f(y) – f(x) \| \le \int_0^1 S\,\|y-x\|\, dt = S\,\|y-x\| \end{equation} $$

が出ます。これでステップ1($f$ は $S$-Lipschitz)が示せました。同時に、本文で「1次近似」として書いた感度の議論が、近似でなく厳密な不等式として正当化されたことになります。

ステップ1-3:逆向き($L \ge S$)を方向微分で。 今度は、Lipschitz定数 $L$ がどんなに頑張っても $S$ より小さくはできないことを示します。任意の点 $x_0$ と任意の単位ベクトル $u$($\|u\|=1$)を固定し、$y = x_0 + h u$($h>0$)とおきます。$f$ が $L$-Lipschitzなら

$$ \begin{equation} \frac{\| f(x_0 + hu) – f(x_0) \|}{h} = \frac{\| f(x_0+hu) – f(x_0) \|}{\| hu \|} \le L \end{equation} $$

が成り立ちます($\|hu\| = h$ を使いました)。ここで $h \to 0^+$ の極限を取ると、左辺は方向微分のノルムに収束します。微分可能性から $f(x_0+hu) – f(x_0) = h\,J(x_0)u + o(h)$ なので、

$$ \begin{equation} \lim_{h \to 0^+} \frac{\| f(x_0+hu) – f(x_0) \|}{h} = \| J(x_0)\, u \| \end{equation} $$

となり、したがって $\|J(x_0)u\| \le L$ がすべての単位ベクトル $u$ で成り立ちます。$u$ について上限を取ると、補遺2で示す通り左辺の上限は $\|J(x_0)\|_2$ なので $\|J(x_0)\|_2 \le L$。さらに $x_0$ は任意だったので、$x_0$ についても上限を取って

$$ \begin{equation} S = \sup_{x_0} \| J(x_0) \|_2 \le L \end{equation} $$

を得ます。ステップ1-2の $L \le S$($S$-Lipschitzなので最小のLが $S$ 以下)と合わせて $L = S = \sup_x \|J(x)\|_2$ が確定しました。これが本文の核心の等式の完全な証明です。なお1次元 $f:\mathbb{R}\to\mathbb{R}$ では $J(x)=f'(x)$、$\|J(x)\|_2 = |f'(x)|$ なので $L = \sup_x |f'(x)|$ となり、本文の1次元の式と整合します。

補遺2:スペクトルノルム $\|A\|_2 = \sigma_{\max}(A)$ の証明

行列 $A \in \mathbb{R}^{m \times n}$ の作用素ノルム(スペクトルノルム)を、本文の定義に従い

$$ \begin{equation} \| A \|_2 := \sup_{\|v\|=1} \| A v \| = \sup_{v \neq 0} \frac{\|Av\|}{\|v\|} \end{equation} $$

とします(2つの表式は $v$ をその長さで割れば等価です)。これが最大特異値 $\sigma_{\max}(A) = \sqrt{\lambda_{\max}(A^\top A)}$ に等しいことを示します。$\lambda_{\max}$ は最大固有値です。

ステップ2-1:$A^\top A$ の性質。 対称行列 $M := A^\top A$ を考えます。$M$ は対称($M^\top = (A^\top A)^\top = A^\top A = M$)なので、スペクトル定理(実対称行列は直交行列で対角化できる)により、正規直交な固有ベクトル $v_1,\dots,v_n$ と実固有値 $\lambda_1 \ge \lambda_2 \ge \cdots \ge \lambda_n$ を持ちます。さらに任意の $v$ について $v^\top M v = v^\top A^\top A v = \|Av\|^2 \ge 0$ なので $M$ は半正定値、つまりすべての $\lambda_i \ge 0$ です。よって $\sqrt{\lambda_i}$ は実数として定義でき、これを特異値 $\sigma_i := \sqrt{\lambda_i}$ と呼びます。

ステップ2-2:$\|Av\|^2$ を固有基底で展開。 任意の単位ベクトル $v$ を正規直交基底 $\{v_i\}$ で $v = \sum_i c_i v_i$ と展開します。正規直交性から $\|v\|^2 = \sum_i c_i^2 = 1$ です。すると

$$ \begin{equation} \|Av\|^2 = v^\top M v = \Big(\sum_i c_i v_i\Big)^\top M \Big(\sum_j c_j v_j\Big) = \sum_{i,j} c_i c_j \, v_i^\top (M v_j) \end{equation} $$

ここで $M v_j = \lambda_j v_j$(固有ベクトルの定義)と $v_i^\top v_j = \delta_{ij}$(正規直交、$\delta_{ij}$ はクロネッカーのデルタで $i=j$ なら1、それ以外0)を代入すると、二重和のうち $i=j$ の項だけが残り、

$$ \begin{equation} \|Av\|^2 = \sum_i \lambda_i\, c_i^2 \end{equation} $$

という、固有値を重み $c_i^2$ で平均した形になります。

ステップ2-3:上限の評価。 $\lambda_1$ が最大なので $\sum_i \lambda_i c_i^2 \le \lambda_1 \sum_i c_i^2 = \lambda_1$。等号は $c_1 = 1$(残りは0、つまり $v = v_1$)のときに達成されます。したがって

$$ \begin{equation} \sup_{\|v\|=1} \|Av\|^2 = \lambda_1, \qquad \|A\|_2 = \sqrt{\lambda_1} = \sigma_{\max}(A) \end{equation} $$

です。最大値は最大固有ベクトル $v_1$ の方向で実現されます。これで本文の「スペクトルノルム = 最大特異値」が証明できました。ついでに、特異値分解 $A = U\Sigma V^\top$ で見ても、$V$ の第1列が $v_1$、$\Sigma$ の最大対角成分が $\sigma_1$ にあたり、同じ結論になります。なお補遺1で用いた $\|Az\| \le \|A\|_2\|z\|$ は、この定義から $z \ne 0$ のとき $\|Az\|/\|z\| \le \sup_{w\ne0}\|Aw\|/\|w\| = \|A\|_2$ として直ちに従います。

補遺3:べき乗法の収束証明

べき乗法は $M = A^\top A$ に対し、単位ベクトル $v_0$ から $v_{k+1} = M v_k / \|M v_k\|$ を繰り返します。これが最大固有ベクトル $v_1$ に収束し、レイリー商 $v_k^\top M v_k$ が $\lambda_1 = \sigma_{\max}^2$ に収束することを、固有値の分離 $\lambda_1 > \lambda_2 \ge \cdots \ge \lambda_n \ge 0$ のもとで示します。

ステップ3-1:正規化を後回しにできる。 各反復で割っている $\|M v_k\|$ は正のスカラーなので、$k$ 回後の $v_k$ は方向としては $M^k v_0$ と同じです(向きは正規化で変わりません)。よって方向の収束は $M^k v_0$ の向きを調べれば十分です。

ステップ3-2:固有基底での展開と増幅。 初期ベクトルを固有基底で $v_0 = \sum_i c_i v_i$ と展開します。$M^k v_i = \lambda_i^k v_i$(固有値は累乗で効く)なので、

$$ \begin{equation} M^k v_0 = \sum_{i=1}^{n} c_i \lambda_i^k v_i = c_1 \lambda_1^k \left( v_1 + \sum_{i=2}^{n} \frac{c_i}{c_1} \left( \frac{\lambda_i}{\lambda_1} \right)^k v_i \right) \end{equation} $$

と変形できます。ここでは支配項 $c_1\lambda_1^k v_1$ をくくり出しました(初期ベクトルが $v_1$ 成分を持つ、すなわち $c_1 \ne 0$ を仮定します。ランダムな $v_0$ では確率1で成立)。

ステップ3-3:収束率。 $i \ge 2$ では $\lambda_i/\lambda_1 < 1$(分離の仮定)なので、$(\lambda_i/\lambda_1)^k \to 0$ です。括弧内の誤差項のノルムは、最大の比 $\lambda_2/\lambda_1$ で支配され、

$$ \begin{equation} \left\| \sum_{i=2}^{n} \frac{c_i}{c_1} \left( \frac{\lambda_i}{\lambda_1} \right)^k v_i \right\| \le \left( \frac{\lambda_2}{\lambda_1} \right)^k \sum_{i=2}^{n} \frac{|c_i|}{|c_1|} = O\!\left( \left( \frac{\lambda_2}{\lambda_1} \right)^k \right) \end{equation} $$

と評価できます。途中の不等号は各 $i\ge2$ で $(\lambda_i/\lambda_1)^k \le (\lambda_2/\lambda_1)^k$ を使い、$\{v_i\}$ の正規直交性でノルムを成分和に直しました。よって正規化した $v_k = M^k v_0/\|M^k v_0\|$ は、誤差が幾何級数的(比 $\lambda_2/\lambda_1$)に減衰しながら $\pm v_1$ に収束します。これが本文で「収束の速さは2番目に大きい特異値との比に依存」と述べた部分の定量的な根拠です。$\lambda_i = \sigma_i^2$ なので比は特異値の比の2乗 $(\sigma_2/\sigma_1)^2$ となり、$M=A^\top A$ を使うことで収束がさらに加速されています。

ステップ3-4:レイリー商の収束。 正規化された $v_k$($\|v_k\|=1$)を最大固有ベクトル方向とそれに直交する誤差に分解し $v_k = a_k v_1 + e_k$ と書きます。ここで $e_k \perp v_1$、$a_k^2 + \|e_k\|^2 = 1$、そしてステップ3-3より $\|e_k\| = O((\lambda_2/\lambda_1)^k) \to 0$、$a_k \to 1$ です。レイリー商 $R(v_k) = v_k^\top M v_k$ を展開すると、交差項 $v_1^\top M e_k = \lambda_1 v_1^\top e_k = 0$(直交により消える)ので、

$$ \begin{equation} R(v_k) = a_k^2\, v_1^\top M v_1 + e_k^\top M e_k = a_k^2 \lambda_1 + e_k^\top M e_k \end{equation} $$

となります。$e_k$ は $\{v_2,\dots,v_n\}$ の張る空間に属するので $0 \le e_k^\top M e_k \le \lambda_2 \|e_k\|^2$、また $a_k^2 = 1-\|e_k\|^2$ です。これらを代入すると $R(v_k) = \lambda_1 + (e_k^\top M e_k – \lambda_1\|e_k\|^2)$ で、誤差項は $\|e_k\|^2 = O((\lambda_2/\lambda_1)^{2k})$ のオーダーなので、

$$ \begin{equation} R(v_k) = \lambda_1 + O\!\left( \left( \frac{\lambda_2}{\lambda_1} \right)^{2k} \right) \;\longrightarrow\; \lambda_1 = \sigma_{\max}^2 \end{equation} $$

と、固有値の方向誤差の2乗の速さで $\lambda_1$ に収束します。最後に $\sigma_{\max} = \sqrt{\lambda_1} = \sqrt{R(v_k)} = \|A v_k\|$(補遺2の $\|Av\|^2 = v^\top M v$ より)を取れば、本文のべき乗法の式と一致します。本文の検証コード「べき乗法と特異値分解の一致」で誤差が $10^{-13}$ 以下に達するのは、この幾何級数収束を $n\_iter=500$ 回繰り返した結果であり、ここでの証明の数値的裏付けになっています。

補遺4:合成と各層のLipschitz定数

ステップ4-1:合成の不等式(再掲を厳密化)。 $g$ が $L_g$-Lipschitz、$f$ が $L_f$-Lipschitzのとき、任意の $x,y$ について

$$ \begin{equation} \| f(g(x)) – f(g(y)) \| \le L_f \|g(x)-g(y)\| \le L_f L_g \|x-y\| \end{equation} $$

の2段で $f\circ g$ が $(L_f L_g)$-Lipschitzと分かります。1段目は $f$ のLipschitz性に入力 $g(x), g(y)$ を代入、2段目は $g$ のLipschitz性です。帰納法で $L$ 個の合成 $f_L\circ\cdots\circ f_1$ に拡張すれば $\mathrm{Lip}(f) \le \prod_{\ell} L_\ell$ を得ます。

ステップ4-2:線形層のLipschitz定数はちょうど $\|W\|_2$。 $f(x)=Wx+b$ では $f(x)-f(y) = W(x-y)$(バイアスは相殺)なので、補遺2の作用素ノルム不等式から $\|f(x)-f(y)\| = \|W(x-y)\| \le \|W\|_2\|x-y\|$、よって $L_f \le \|W\|_2$。逆に $x-y$ を最大特異ベクトル $v_1$ 方向に取ると等号 $\|Wv_1\| = \|W\|_2\|v_1\|$ が成立するので、最小のLipschitz定数はちょうど $\|W\|_2$ です。

ステップ4-3:ReLU・tanh・sigmoidが1-Lipschitz。 要素ごとに作用する活性化 $\phi$ では、入力ベクトル $a,b$ に対し $\|\phi(a)-\phi(b)\|^2 = \sum_i (\phi(a_i)-\phi(b_i))^2$ です。各成分について1次元の平均値の定理を使うと、ある $\xi_i$ が $a_i, b_i$ の間に存在して

$$ \begin{equation} |\phi(a_i) – \phi(b_i)| = |\phi'(\xi_i)|\,|a_i – b_i| \le \Big(\sup_t |\phi'(t)|\Big)\, |a_i – b_i| \end{equation} $$

が成り立ちます。あとは各活性化の導関数の上限を確認します。

  • ReLU: $\phi'(t) \in \{0,1\}$($t=0$ では劣微分が $[0,1]$)なので $\sup|\phi’| = 1$。
  • tanh: $\phi'(t) = 1 – \tanh^2 t \in (0,1]$ で、最大は $t=0$ の $1$。よって $\sup|\phi’| = 1$。
  • sigmoid: $\phi'(t) = \sigma(t)(1-\sigma(t))$。$\sigma \in (0,1)$ で $s(1-s)$ は $s=1/2$ で最大値 $1/4$。よって $\sup|\phi’| = 1/4 \le 1$。

いずれも $\sup|\phi’| \le 1$ なので、各成分で $|\phi(a_i)-\phi(b_i)| \le |a_i-b_i|$、これを二乗和に戻すと $\|\phi(a)-\phi(b)\|^2 \le \sum_i (a_i-b_i)^2 = \|a-b\|^2$、すなわち $\phi$ は1-Lipschitzです(sigmoidは $1/4$-Lipschitzでさらに強い)。ステップ4-1〜4-3を合わせると、線形層と1-Lipschitz活性化の交互合成であるネット全体は $\mathrm{Lip}(\mathrm{net}) \le \prod_\ell \|W_\ell\|_2$ で押さえられます。本文の検証コード「合成ネットのLipschitz上界は各層ノルムの積」で、サンプリングした最悪傾きが必ずこの積以下に収まったのは、まさにこの不等式の数値確認です。

補遺5:Spectral Normalizationが1-Lipschitzを保証する

主張は単純です。$\sigma_1(W) = \|W\|_2 > 0$ として $\bar W := W/\sigma_1(W)$ と定義すると、$\sigma_1(\bar W) = 1$ になる、というものです。作用素ノルムは正のスカラー倍に対して絶対同次性 $\|cW\|_2 = |c|\,\|W\|_2$ を満たします。これは定義から

$$ \begin{equation} \| cW \|_2 = \sup_{\|v\|=1} \|cW v\| = \sup_{\|v\|=1} |c|\,\|Wv\| = |c| \sup_{\|v\|=1}\|Wv\| = |c|\,\|W\|_2 \end{equation} $$

と1行で従います(スカラー $|c|$ は上限の外に出せる)。$c = 1/\sigma_1(W) > 0$ を代入すると

$$ \begin{equation} \sigma_1(\bar W) = \| \bar W \|_2 = \left\| \frac{W}{\sigma_1(W)} \right\|_2 = \frac{1}{\sigma_1(W)}\,\|W\|_2 = \frac{\sigma_1(W)}{\sigma_1(W)} = 1 \end{equation} $$

となり、$\bar W$ のスペクトルノルムはちょうど1です。補遺4-2より、重み $\bar W$ の線形層はちょうど1-Lipschitzであり、全層に適用すれば積が $\prod_\ell 1 = 1$ なのでネット全体が1-Lipschitzになります。これが Spectral Normalization の保証の証明です。本文の検証コードで正規化後のスペクトルノルムが「ちょうど1.0000」、出力差/入力差の最大値が1.0000以下になったのは、この等式の実測確認にあたります。

補遺6:証明半径 $r = M/(2L)$ の導出

最後に certified robustness の保証半径を導きます。分類器の出力(ロジット)ベクトルを $f(x) \in \mathbb{R}^K$、正解クラスを $c$、それ以外で最大スコアのクラスを $c’$ とします。マージン

$$ \begin{equation} M := f_c(x) – \max_{j \ne c} f_j(x) = f_c(x) – f_{c’}(x) > 0 \end{equation} $$

と定義します(正しく分類されている前提で $M>0$)。摂動 $\delta$ を加えても順位が入れ替わらない条件は、摂動後も正解クラスが最大、すなわちすべての $j \ne c$ で $f_c(x+\delta) > f_j(x+\delta)$ です。各成分の動きを Lipschitz性で押さえます。

ステップ6-1:各ロジットの動きの上界。 $f$ が(出力をユークリッドノルムで測って)$L$-Lipschitzなら、各成分 $j$ について

$$ \begin{equation} | f_j(x+\delta) – f_j(x) | \le \| f(x+\delta) – f(x) \| \le L\,\|\delta\| \end{equation} $$

が成り立ちます(1成分の絶対値はベクトル全体のノルム以下)。

ステップ6-2:マージンが保たれる条件。 正解クラス $c$ のスコアは最悪でも $L\|\delta\|$ 下がり、対抗クラス $j$ のスコアは最悪でも $L\|\delta\|$ 上がります。よって摂動後のスコア差は最悪でも

$$ \begin{equation} f_c(x+\delta) – f_j(x+\delta) \ge \big(f_c(x) – f_j(x)\big) – 2L\|\delta\| \ge M – 2L\|\delta\| \end{equation} $$

です(係数2は「正解が下がる」と「対抗が上がる」の両方を足したため)。この右辺が正であれば順位は保たれます。

ステップ6-3:半径を解く。 $M – 2L\|\delta\| > 0$ を $\|\delta\|$ について解くと、

$$ \begin{equation} \| \delta \| < \frac{M}{2L} \;\; \Longrightarrow \;\; \text{すべての } j\ne c \text{ で } f_c(x+\delta) > f_j(x+\delta) \;\; \Longrightarrow \;\; \text{誤分類されない} \end{equation} $$

が得られます。よって保証半径は $r = M/(2L)$ です。本文で触れたように、出力差をどのノルムで測るか(例えばロジット差を $\ell_\infty$ や $\ell_2$ のどれで見るか)で係数 $2$ が $\sqrt 2$ などに変わりますが、「半径はマージンを $L$ で割ったオーダー」という構造は不変です。$L$ を小さく保つほど(=各層のスペクトルノルムの積を抑えるほど)半径が大きくなり、より広い摂動に対して「絶対に誤分類しない」証明書を発行できる、という本文の主張が定量的に確定しました。

これで本文で流した6つの主張がすべて、線積分・スペクトル定理・固有値の分離・絶対同次性・平均値の定理という標準的な道具だけで埋まりました。論文を自己完結で読むための論理の穴は、もう残っていません。

まとめ

本記事では、Lipschitz連続性とスペクトルノルムを、ヤコビアンの「ノルム」という顔から掘り下げました。

  • Lipschitz定数 $L$ は「最悪の傾き」。出力の変化を入力の変化の $L$ 倍以下に抑える保証を与えます。
  • 微分可能関数では $L = \sup_x \|J(x)\|_2$。ヤコビアンの最大特異値が局所的な最悪の引き伸ばし倍率です。
  • スペクトルノルムは最大特異値であり、べき乗法で数反復、深層学習では1反復の近似で高速に求まります。
  • 合成のLipschitz定数は各層の積で押さえられ、線形層は重みのスペクトルノルム、ReLU/tanh/sigmoidは1-Lipschitz。よってネット全体のLipschitz定数は各重みのスペクトルノルムの積で決まります。
  • Spectral Normalizationは重みを最大特異値で割り1-Lipschitzを作ります。これはWGANの1-Lipschitz制約敵対的頑健性(保証半径 $\sim M/L$)勾配爆発・消失の制御という3つの大問題の共通の土台です。

Lipschitz定数とスペクトルノルムは、線形代数(特異値)・最適化(学習の安定性)・生成モデル(WGAN)・安全性(頑健性)を一本の糸でつなぐ概念です。次のステップとして、以下の記事も参考にしてください。