フロベニウスノルムとは?定義・性質・機械学習での使いどころ

640×427ピクセルの写真を、情報をほとんど落とさずに10分の1のデータ量に圧縮したい。ニューラルネットの重みが暴れないように「重みの大きさ」にペナルティをかけたい。推薦システムで、ユーザー×アイテムの巨大な評価行列の穴を埋めたい。学習が収束したかどうかを、パラメータ行列の変化量で判定したい。

この4つは、見た目はまったく別の問題です。ところが、どれも解こうとすると「2つの行列がどれくらい離れているか」を数値で測る道具が要ります。ベクトルなら $\|\bm{x} – \bm{y}\|$ で距離を測れますが、行列に対して同じことをするにはどうすればよいのでしょうか。

いちばん素直な答えがフロベニウスノルムです。行列の成分を全部並べて、ただの長いベクトルだと思って長さを測る。それだけの、驚くほど単純な定義です。にもかかわらずこのノルムは、特異値分解と深く結びつき、直交変換で値が変わらないという美しい性質を持ち、そして「打ち切りSVDが最良の低ランク近似である」という Eckart-Young-Mirsky の定理を支えています。機械学習で当たり前のように使っている重み減衰(weight decay)も、正体はフロベニウスノルムの二乗にかける罰則です。

この記事では、素朴な定義から出発して、トレース表現・特異値表現・不変性・不等式群を1本ずつ導出し、最後に画像圧縮とニューラルネットの正則化という2つの実験でその働きを目で確かめます。

本記事の内容

  • フロベニウスノルムの直感的な意味と厳密な定義
  • トレース $\mathrm{tr}(\bm{A}^{\mathsf{H}}\bm{A})$ による表現とフロベニウス内積
  • 特異値との関係 $\|\bm{A}\|_F = \sqrt{\sum_i \sigma_i^2}$ の導出
  • 直交(ユニタリ)不変性、劣乗法性、スペクトルノルムとの挟み込みの証明
  • Eckart-Young-Mirsky 定理と低ランク近似の誤差公式
  • Pythonによる3種のノルム比較・画像の低ランク近似・重み減衰の実験

前提知識

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

フロベニウスノルムとは — 行列を「長いベクトル」だと思う

行列を1行ずつ読み上げて長さmnのベクトルに並べ替え、ユークリッド長さを測るとフロベニウスノルムになることを示した概念図

この図がフロベニウスノルムの全体像です。左の $2\times3$ 行列を「行ごとに読み上げて一列に並べる」と長さ6のベクトルになり、あとはそのユークリッド長さを測るだけで $\sqrt{55}\approx 7.416$ が得られます。右側に添えたとおり、行列の大きさには「引き伸ばし倍率の最大値(スペクトルノルム)」という別の測り方もありますが、フロベニウスノルムはそれとは違って成分の詰まり具合を見ています。この乱暴なまでの単純さが、以降で見る三拍子(微分しやすさ・回転不変性・特異値との一致)を生みます。

$m \times n$ の行列には $mn$ 個の数字が詰まっています。この $mn$ 個の数字を、行ごとに端から端まで読み上げて一列に並べると、長さ $mn$ のベクトルができあがります。表計算ソフトのシートを1行ずつコピーして、1本の細長い列に貼り直すイメージです。

こうしてしまえば、あとはベクトルのユークリッド長さ(L2ノルム)を測るだけです。$\sqrt{\text{全成分の二乗和}}$。これがフロベニウスノルムの正体です。行列を行列として扱わず、いったん「構造を忘れて」ただの数の並びとして長さを測る、という思い切りのよさがこのノルムの特徴です。

たとえば

$$ \bm{A} = \begin{pmatrix} 3 & 0 \\ 4 & 5 \end{pmatrix} $$

なら、成分は $3, 0, 4, 5$ の4つですから、

$$ \|\bm{A}\|_F = \sqrt{3^2 + 0^2 + 4^2 + 5^2} = \sqrt{50} = 5\sqrt{2} \approx 7.071 $$

です。中学生でも計算できます。

「そんな乱暴な測り方でいいのか」と思うかもしれません。行列は本来、ベクトルを別のベクトルへ写す写像です。写像の大きさを測るなら「入力ベクトルをどれだけ引き伸ばすか」の最大値(=スペクトルノルム)のほうが自然に見えます。ところが後で見るように、この「乱暴な」定義こそが、微分しやすく・回転で変わらず・特異値の二乗和と一致するという三拍子そろった性質を生みます。乱暴さが素直さになっているわけです。

ではまず、定義をきちんと書き下すところから始めましょう。

フロベニウスノルムの定義

前節で述べた「全成分の二乗和の平方根」を、記号で正確に表します。行列 $\bm{A} \in \mathbb{C}^{m \times n}$ の $(i,j)$ 成分を $a_{ij}$ と書くと、フロベニウスノルムは次で定義されます。

$$ \begin{equation} \|\bm{A}\|_F := \sqrt{\sum_{i=1}^{m} \sum_{j=1}^{n} |a_{ij}|^2} \end{equation} $$

実行列なら絶対値記号は外して $|a_{ij}|^2 = a_{ij}^2$ としてかまいません。複素行列でも絶対値の二乗(=実部と虚部それぞれの二乗和)を取れば、値は必ず非負の実数になります。

この定義は、次のように行ベクトル/列ベクトルの長さの寄せ集めとして読むこともできます。$\bm{A}$ の第 $i$ 行を $\bm{a}_{i\cdot}$、第 $j$ 列を $\bm{a}_{\cdot j}$ と書くと、

$$ \|\bm{A}\|_F^2 = \sum_{i=1}^{m} \|\bm{a}_{i\cdot}\|_2^2 = \sum_{j=1}^{n} \|\bm{a}_{\cdot j}\|_2^2 $$

となります。二乗和を「行ごとにまとめてから足す」か「列ごとにまとめてから足す」かの違いにすぎず、どちらも全成分の二乗和に等しいからです。データ行列(1行が1サンプル)を扱うとき、$\|\bm{X}\|_F^2$ が「全サンプルのノルムの二乗の合計」になるという読み方は実務でよく使います。

2×2行列3,0,4,5の各成分を二乗して足すと50になること、および行ごとの二乗和9と41、列ごとの二乗和25と25がどちらも合計50になることを示した図

左と中央のパネルが定義そのものです。成分 $3,0,4,5$ を二乗して足すと $9+0+16+25=50$、平方根を取って $\|\bm{A}\|_F=\sqrt{50}\approx 7.071$ になります。右のパネルが「行ごとの寄せ集め」と「列ごとの寄せ集め」の比較で、行ごとに足すと $9$ と $41$、列ごとに足すと $25$ と $25$ と内訳はまったく違うのに、合計はどちらも赤い破線の $50$ に一致します。まとめる順番を変えても総和は変わらない、という当たり前の事実が、上の2つの表現式の中身です。

ノルムと呼ぶからには、次の3条件(ノルムの公理)を満たさなければなりません。

  1. 非負性・定値性: $\|\bm{A}\|_F \geq 0$ であり、$\|\bm{A}\|_F = 0 \iff \bm{A} = \bm{O}$
  2. 斉次性: 任意のスカラー $c$ に対し $\|c\bm{A}\|_F = |c| \, \|\bm{A}\|_F$
  3. 三角不等式: $\|\bm{A} + \bm{B}\|_F \leq \|\bm{A}\|_F + \|\bm{B}\|_F$

1と2は定義から即座に確かめられます。二乗和が $0$ になるのは全成分が $0$ のときだけですし、全成分を $c$ 倍すれば二乗和は $|c|^2$ 倍になるので、平方根を取れば $|c|$ 倍です。3は、$\bm{A}$ と $\bm{B}$ を長さ $mn$ のベクトルとみなせば、ユークリッドノルム(L2ノルム)の三角不等式そのものです。つまりフロベニウスノルムは、$\mathbb{C}^{mn}$ のユークリッドノルムを $\mathbb{C}^{m\times n}$ に移植したものであり、ノルムの公理は自動的に受け継がれます。

なお、記号は $\|\bm{A}\|_F$ のほか $\|\bm{A}\|_{\mathrm{HS}}$(Hilbert-Schmidtノルム)とも書きます。作用素論では無限次元へ拡張したものをヒルベルト・シュミットノルムと呼びますが、有限次元では同じものです。機械学習でHSIC(Hilbert-Schmidt独立性規準)という名前を見かけたら、そこで測られているのもこのノルムです。

定義そのものは素朴でした。しかしこの素朴な式をトレースという言葉で書き直すと、行列らしい構造が一気に見えてきます。次にそれをやってみましょう。

トレース表現とフロベニウス内積

ベクトルの長さの二乗は $\|\bm{x}\|^2 = \bm{x}^{\mathsf{H}}\bm{x}$ と、内積で書けました。行列でも同じことができないでしょうか。答えは「できる」で、その鍵がトレース(対角成分の和)です。

$\|\bm{A}\|_F^2 = \mathrm{tr}(\bm{A}^{\mathsf{H}}\bm{A})$ の導出

まず $\bm{A}^{\mathsf{H}}\bm{A}$($\bm{A}^{\mathsf{H}}$ は共役転置。実行列なら $\bm{A}^{\mathsf{T}}$)の対角成分を計算します。行列積の定義から、$(j,j)$ 成分は

$$ (\bm{A}^{\mathsf{H}}\bm{A})_{jj} = \sum_{i=1}^{m} (\bm{A}^{\mathsf{H}})_{ji} \, (\bm{A})_{ij} $$

です。ここで $(\bm{A}^{\mathsf{H}})_{ji} = \overline{a_{ij}}$(共役転置の定義)を代入すると、

$$ (\bm{A}^{\mathsf{H}}\bm{A})_{jj} = \sum_{i=1}^{m} \overline{a_{ij}} \, a_{ij} = \sum_{i=1}^{m} |a_{ij}|^2 $$

となります。つまり $\bm{A}^{\mathsf{H}}\bm{A}$ の第 $j$ 対角成分は、ちょうど$\bm{A}$ の第 $j$ 列の長さの二乗です。あとはこれを $j$ について全部足せばよいので、トレースを取って

$$ \begin{equation} \mathrm{tr}(\bm{A}^{\mathsf{H}}\bm{A}) = \sum_{j=1}^{n} \sum_{i=1}^{m} |a_{ij}|^2 = \|\bm{A}\|_F^2 \end{equation} $$

が得られました。まったく同じ計算を $\bm{A}\bm{A}^{\mathsf{H}}$ に対して行えば、今度は「行の長さの二乗」が対角に並びますから、

$$ \|\bm{A}\|_F^2 = \mathrm{tr}(\bm{A}^{\mathsf{H}}\bm{A}) = \mathrm{tr}(\bm{A}\bm{A}^{\mathsf{H}}) $$

も同時に分かります(トレースの巡回性 $\mathrm{tr}(\bm{X}\bm{Y}) = \mathrm{tr}(\bm{Y}\bm{X})$ からも直ちに従います)。$\bm{A}^{\mathsf{H}}\bm{A}$ は $n\times n$、$\bm{A}\bm{A}^{\mathsf{H}}$ は $m \times m$ とサイズが違うのに、トレースは一致する。縦長行列を扱うときは小さいほうを選べば計算が軽くなる、という実用的なメリットもあります。

3×2行列BについてB^TB(2×2)とBB^T(3×3)を計算し、対角成分の和がどちらも54でBの全成分の二乗和と一致することを示した図

$3\times2$ の行列 $\bm{B}$ で実際に確かめた図です。$\bm{B}^{\mathsf{T}}\bm{B}$ の対角にはオレンジで示した $25, 29$(=各列の長さの二乗)が並び、$\bm{B}\bm{B}^{\mathsf{T}}$ の対角には $9, 41, 4$(=各行の長さの二乗)が並びます。サイズは $2\times2$ と $3\times3$ でまったく違い、対角の中身も違うのに、トレースはどちらも $54$ で、$\bm{B}$ の全成分の二乗和と一致しています。非対角成分($20$ や $12$)はトレースには一切効いていない点にも注目してください。

フロベニウス内積

トレース表現の本当のご利益は、ノルムの背後にある内積が見えることです。2つの行列 $\bm{A}, \bm{B} \in \mathbb{C}^{m\times n}$ に対して

$$ \begin{equation} \langle \bm{A}, \bm{B} \rangle_F := \mathrm{tr}(\bm{A}^{\mathsf{H}}\bm{B}) = \sum_{i=1}^{m}\sum_{j=1}^{n} \overline{a_{ij}} \, b_{ij} \end{equation} $$

と定めます。これをフロベニウス内積(トレース内積、Hilbert-Schmidt内積)と呼びます。右辺を見れば分かるとおり、これは「対応する成分どうしを掛けて全部足す」だけの、ベクトルの標準内積とまったく同じ操作です。

この $\langle \cdot, \cdot \rangle_F$ が内積の公理を満たすことは、成分表示から一つずつ確かめられます。共役対称性 $\langle \bm{B}, \bm{A}\rangle_F = \overline{\langle \bm{A}, \bm{B}\rangle_F}$ は、和の各項で $\overline{b_{ij}}a_{ij} = \overline{\overline{a_{ij}}b_{ij}}$ が成り立つことから。第2引数についての線形性は和と定数倍の分配から。正定値性は $\langle \bm{A}, \bm{A}\rangle_F = \|\bm{A}\|_F^2 \geq 0$ かつ等号は $\bm{A}=\bm{O}$ のときのみ、というところから従います。

そして最後の式が示すとおり、

$$ \|\bm{A}\|_F = \sqrt{\langle \bm{A}, \bm{A} \rangle_F} $$

です。つまりフロベニウスノルムはフロベニウス内積が誘導するノルムであり、行列全体の空間 $\mathbb{C}^{m\times n}$ はこの内積によって(有限次元の)ヒルベルト空間になります。

2つの行列の対応成分を掛けて足すとフロベニウス内積になること、およびSVDのランク1成分どうしのフロベニウス内積が対角以外ゼロで直交することを示した図

左の3枚が定義の実演です。$\bm{A}$ と $\bm{B}$ の同じ位置の成分どうしを掛けて $3, 0, -4, 5$ を並べ、全部足すと $\langle\bm{A},\bm{B}\rangle_F = 4$ になります。ベクトルの内積と手続きがまったく同じであることが見て取れます。右の行列は、あるランダム行列のSVDから作った4つのランク1成分 $\sigma_i\bm{u}_i\bm{v}_i^{\mathsf{T}}$ どうしのフロベニウス内積を並べたもので、対角($9.22, 4.06, 1.64, 0.24$、これは $\sigma_i^2$ に等しい)以外がすべて $0.00$ になっています。SVDの各成分は互いにフロベニウス直交している、つまり低ランク近似は「直交成分を捨てる射影」なのだ、ということがこの1枚から読み取れます。

この事実は見た目以上に強力です。内積があるということは、行列に対して「角度」「直交」「射影」が定義できるということだからです。実際、$\langle \bm{A}, \bm{B}\rangle_F = 0$ なら「2つの行列は直交する」と言えますし、SVDで得られる各ランク1成分 $\sigma_i \bm{u}_i \bm{v}_i^{\mathsf{H}}$ は互いにフロベニウス直交します。低ランク近似が「射影」として理解できるのは、この内積構造のおかげです。

内積が入ったので、コーシー・シュワルツの不等式

$$ |\langle \bm{A}, \bm{B}\rangle_F| \leq \|\bm{A}\|_F \|\bm{B}\|_F $$

も無料で手に入ります。これは後で劣乗法性を証明するときに使います。

内積の話が出たところで、いよいよ行列らしい構造 — 特異値との関係に踏み込みます。ここがフロベニウスノルムのいちばん美しい部分です。

特異値との関係:$\|\bm{A}\|_F^2 = \sum_i \sigma_i^2$

行列の「本質的な大きさ」を語るとき、成分の値そのものはあまり意味がありません。座標系を回せば成分はいくらでも変わるからです。本質を握っているのは特異値 $\sigma_1 \geq \sigma_2 \geq \cdots \geq \sigma_r > 0$ で、これは「行列が空間をどの方向にどれだけ引き伸ばすか」の倍率を並べたものです。

驚くべきことに、成分を全部足し上げただけのフロベニウスノルムが、この特異値だけで書けてしまいます。

$$ \begin{equation} \|\bm{A}\|_F = \sqrt{\sum_{i=1}^{r} \sigma_i^2}, \qquad r = \mathrm{rank}(\bm{A}) \end{equation} $$

導出しましょう。$\bm{A}$ の特異値分解を

$$ \bm{A} = \bm{U}\bm{\Sigma}\bm{V}^{\mathsf{H}} $$

とします。$\bm{U} \in \mathbb{C}^{m\times m}$、$\bm{V}\in\mathbb{C}^{n\times n}$ はユニタリ行列($\bm{U}^{\mathsf{H}}\bm{U} = \bm{I}_m$、$\bm{V}^{\mathsf{H}}\bm{V} = \bm{I}_n$)、$\bm{\Sigma}\in\mathbb{R}^{m\times n}$ は対角位置に $\sigma_1,\dots,\sigma_{\min(m,n)}$ が並び他は $0$ の行列です。

まず前節のトレース表現から出発します。

$$ \|\bm{A}\|_F^2 = \mathrm{tr}(\bm{A}^{\mathsf{H}}\bm{A}) $$

ここに $\bm{A} = \bm{U}\bm{\Sigma}\bm{V}^{\mathsf{H}}$ を代入します。$(\bm{U}\bm{\Sigma}\bm{V}^{\mathsf{H}})^{\mathsf{H}} = \bm{V}\bm{\Sigma}^{\mathsf{H}}\bm{U}^{\mathsf{H}}$ に注意すると、

$$ \mathrm{tr}(\bm{A}^{\mathsf{H}}\bm{A}) = \mathrm{tr}\left(\bm{V}\bm{\Sigma}^{\mathsf{H}}\bm{U}^{\mathsf{H}} \, \bm{U}\bm{\Sigma}\bm{V}^{\mathsf{H}}\right) $$

となります。次に、真ん中の $\bm{U}^{\mathsf{H}}\bm{U}$ がユニタリ性より $\bm{I}_m$ になるので消せます。

$$ = \mathrm{tr}\left(\bm{V}\bm{\Sigma}^{\mathsf{H}}\bm{\Sigma}\bm{V}^{\mathsf{H}}\right) $$

ここでトレースの巡回性 $\mathrm{tr}(\bm{X}\bm{Y}) = \mathrm{tr}(\bm{Y}\bm{X})$ を使い、先頭の $\bm{V}$ を末尾に回します。

$$ = \mathrm{tr}\left(\bm{\Sigma}^{\mathsf{H}}\bm{\Sigma}\bm{V}^{\mathsf{H}}\bm{V}\right) = \mathrm{tr}\left(\bm{\Sigma}^{\mathsf{H}}\bm{\Sigma}\right) $$

最後の等号は再び $\bm{V}^{\mathsf{H}}\bm{V} = \bm{I}_n$ を使いました。あとは $\bm{\Sigma}^{\mathsf{H}}\bm{\Sigma}$ が対角行列 $\mathrm{diag}(\sigma_1^2, \sigma_2^2, \dots)$ であることを見れば、

$$ \|\bm{A}\|_F^2 = \sum_{i} \sigma_i^2 $$

が示せました。$\sigma_i = 0$ の項は和に寄与しないので、$i$ の範囲を $1$ から $r = \mathrm{rank}(\bm{A})$ に絞ってかまいません。

特異値6.708と2.236を直角三角形の2辺としたときの斜辺がフロベニウスノルム7.071になること、および特異値とその二乗の棒グラフを並べた図

左は $\bm{A}=[[3,0],[4,5]]$ の特異値 $\sigma_1=6.708$、$\sigma_2=2.236$ を直角三角形の2辺として描いたもので、斜辺の長さがちょうど $\|\bm{A}\|_F=7.071$ になります。フロベニウスノルムが「特異方向という直交軸ごとの寄与を、ピタゴラスの定理で合成した長さ」であることが、この三角形1つで見えます。右の棒グラフでは、$\sigma_1$ は $\sigma_2$ の3倍程度なのに、二乗したエネルギーでは $45$ 対 $5$ と9倍差に開いており、二乗によって大きい特異方向がさらに強調されることが分かります。

この結果の意味を噛みしめておきましょう。$\|\bm{A}\|_F^2$ は「行列が持つエネルギーの総量」で、それは各特異方向のエネルギー $\sigma_i^2$ の単純な足し算に分解されるということです。ピタゴラスの定理が、直交する軸ごとの寄与の二乗和として長さを与えるのと同じ構造です。画像圧縮で「上位 $k$ 個の特異値で全エネルギーの何%を説明できるか」という言い方をするとき、その「エネルギー」はまさにこの $\sum \sigma_i^2$ を指しています。

対称行列(あるいはエルミート行列)の場合は、特異値が固有値の絶対値に一致するので

$$ \|\bm{A}\|_F^2 = \sum_i \lambda_i^2 $$

とも書けます。共分散行列やグラム行列を扱うときに便利な形です。

なぜこんなにきれいに特異値だけで書けたのでしょうか。答えは、フロベニウスノルムがユニタリ行列を掛けても変わらないという性質を持っているからです。次にそれを正面から示します。

直交(ユニタリ)変換に対する不変性

ベクトルを回転させても長さは変わりません。$\bm{Q}$ が直交行列なら $\|\bm{Q}\bm{x}\|_2 = \|\bm{x}\|_2$ です。行列に対しても、まったく同じことが左右どちらからでも成り立ちます。

主張: $\bm{U} \in \mathbb{C}^{m\times m}$、$\bm{V}\in\mathbb{C}^{n\times n}$ をユニタリ行列(実なら直交行列)とすると、任意の $\bm{A}\in\mathbb{C}^{m\times n}$ に対して

$$ \begin{equation} \|\bm{U}\bm{A}\bm{V}\|_F = \|\bm{A}\|_F \end{equation} $$

証明: トレース表現から始めます。

$$ \|\bm{U}\bm{A}\bm{V}\|_F^2 = \mathrm{tr}\left((\bm{U}\bm{A}\bm{V})^{\mathsf{H}}(\bm{U}\bm{A}\bm{V})\right) $$

共役転置を展開すると $(\bm{U}\bm{A}\bm{V})^{\mathsf{H}} = \bm{V}^{\mathsf{H}}\bm{A}^{\mathsf{H}}\bm{U}^{\mathsf{H}}$ ですから、

$$ = \mathrm{tr}\left(\bm{V}^{\mathsf{H}}\bm{A}^{\mathsf{H}}\bm{U}^{\mathsf{H}}\bm{U}\bm{A}\bm{V}\right) $$

真ん中の $\bm{U}^{\mathsf{H}}\bm{U} = \bm{I}_m$ を使って $\bm{U}$ を消します。

$$ = \mathrm{tr}\left(\bm{V}^{\mathsf{H}}\bm{A}^{\mathsf{H}}\bm{A}\bm{V}\right) $$

最後にトレースの巡回性で先頭の $\bm{V}^{\mathsf{H}}$ を末尾へ送り、$\bm{V}\bm{V}^{\mathsf{H}} = \bm{I}_n$ を使えば、

$$ = \mathrm{tr}\left(\bm{A}^{\mathsf{H}}\bm{A}\bm{V}\bm{V}^{\mathsf{H}}\right) = \mathrm{tr}(\bm{A}^{\mathsf{H}}\bm{A}) = \|\bm{A}\|_F^2 $$

となり、証明が完了します。$\square$

回転角を0度から360度まで変えても左右どちらから掛けたフロベニウスノルムも一定であること、一方で個々の成分は大きく振動することを示した図

左は $3\times3$ のランダム行列に回転行列 $\bm{Q}$ を左から、右から、両側から掛けて、角度を $0^\circ$ から $360^\circ$ まで動かしたときのフロベニウスノルムです。3本の曲線はすべて元の値 $2.0469$ の水平線に重なったまま、まったく動きません。右は同じ変換を成分ごとに見たもので、9個の成分(灰色)は $-1$ から $1.4$ の範囲で激しく振動し、太い紫の $(1,1)$ 成分も符号を変えて動き回っています。それでも赤い線 — 9成分の二乗和の平方根 — だけは一定です。個々の数字は座標系しだいで好き勝手に変わるが、その二乗和だけは変わらない、というのが不変性の実態です。

この不変性が意味するのは、フロベニウスノルムは座標系の取り方に依存しないということです。入力側の基底を回しても(右から $\bm{V}$)、出力側の基底を回しても(左から $\bm{U}$)、測られる「大きさ」は変わりません。逆に言えば、フロベニウスノルムは行列の幾何学的な中身だけを見ていて、成分がどう並んでいるかという表面的な情報は見ていないのです。

この観点から前節を振り返ると、特異値表現は不変性のほとんど自明な帰結だと分かります。$\bm{A} = \bm{U}\bm{\Sigma}\bm{V}^{\mathsf{H}}$ と分解できるなら、不変性より $\|\bm{A}\|_F = \|\bm{\Sigma}\|_F$ であり、$\bm{\Sigma}$ は対角行列なのでその成分の二乗和は $\sum\sigma_i^2$。それだけの話です。

不変性が効く実例をひとつ挙げておきます。直交プロクラステス問題は、2つの点群 $\bm{A}, \bm{B}$ を最もよく重ね合わせる回転 $\bm{Q}$ を求める問題で、

$$ \min_{\bm{Q}: \, \bm{Q}^{\mathsf{T}}\bm{Q}=\bm{I}} \|\bm{A} – \bm{B}\bm{Q}\|_F $$

と定式化されます。目的関数を展開すると $\|\bm{A}\|_F^2 + \|\bm{B}\bm{Q}\|_F^2 – 2\langle \bm{A}, \bm{B}\bm{Q}\rangle_F$ ですが、不変性より $\|\bm{B}\bm{Q}\|_F^2 = \|\bm{B}\|_F^2$ は $\bm{Q}$ によらない定数です。よって問題は $\langle \bm{A}, \bm{B}\bm{Q}\rangle_F = \mathrm{tr}(\bm{Q}^{\mathsf{T}}\bm{B}^{\mathsf{T}}\bm{A})$ の最大化に帰着し、$\bm{B}^{\mathsf{T}}\bm{A}$ のSVDから閉形式解が得られます。他のノルムだとこうはいきません。分子構造の重ね合わせ、点群レジストレーション、単語埋め込み空間の言語間アラインメントなど、応用は広い問題です。

ここまでで、フロベニウスノルムの「内側の構造」は見えました。次は、他のノルムとの関係 — 大きいのか小さいのか — を整理しましょう。

他の行列ノルムとの関係

行列の大きさを測る流儀はフロベニウスノルムだけではありません。代表的なものを、特異値ベクトル $\bm{\sigma} = (\sigma_1,\dots,\sigma_r)$ に対する操作として並べると、驚くほど統一的に見えます。

ノルム 定義 特異値による表現
スペクトルノルム $\|\bm{A}\|_2$ $\max_{\|\bm{x}\|=1}\|\bm{A}\bm{x}\|_2$ $\sigma_1 = \|\bm{\sigma}\|_\infty$
フロベニウスノルム $\|\bm{A}\|_F$ $\sqrt{\sum |a_{ij}|^2}$ $\|\bm{\sigma}\|_2$
核ノルム $\|\bm{A}\|_*$ $\mathrm{tr}\sqrt{\bm{A}^{\mathsf{H}}\bm{A}}$ $\sum_i \sigma_i = \|\bm{\sigma}\|_1$
ランク $\mathrm{rank}(\bm{A})$ — $\|\bm{\sigma}\|_0$(非ゼロ成分数)

つまりこの3つはシャッテン $p$-ノルム $\|\bm{A}\|_{S_p} = \left(\sum_i \sigma_i^p\right)^{1/p}$ の $p = \infty, 2, 1$ に対応します。ベクトルに対する $L_\infty$、$L_2$、$L_1$ をそのまま特異値ベクトルに適用したもの、と覚えると忘れません。そしてランクは $L_0$ に相当します。「核ノルムがランクの凸緩和になる」という有名な事実は、「$L_1$ が $L_0$ の凸緩和になる」というスパース推定の話とまったく同じ構図なのです。

特異値ベクトルにL無限大・L2・L1・L0ノルムを適用するとスペクトルノルム・フロベニウスノルム・核ノルム・ランクになることを示した対応図

この図が本節の要点を1枚にまとめたものです。左の4本の棒($\sigma=(4.0,\,2.4,\,1.2,\,0.5)$)に対して、最大値を取ればスペクトルノルム $4.00$、二乗和の平方根を取ればフロベニウスノルム $4.84$、単純和を取れば核ノルム $8.10$、非ゼロの個数を数えればランク $4$ になります。行列ノルムを4種類も覚える必要はなく、「特異値ベクトルに $L_\infty$/$L_2$/$L_1$/$L_0$ のどれを当てるか」だけの違いだと分かります。値が $4.00 < 4.84 < 8.10$ と並ぶ順序も、ベクトルノルムの $\|\cdot\|_\infty \le \|\cdot\|_2 \le \|\cdot\|_1$ から自動的に決まります。

この対応関係から、フロベニウスノルムの立ち位置がはっきりします。フロベニウスノルムは特異値に対するリッジ(L2)罰則です。特異値を全体的に小さくはしますが、L1のように「特異値をぴったりゼロにする」効果は持ちません。だから低ランク性を誘導したいときは核ノルムを使い、単に大きさを抑えたいときはフロベニウスノルムを使う、という使い分けになります。

スペクトルノルムとの挟み込み

もっとも使う頻度が高い不等式が次の挟み込みです。$r = \mathrm{rank}(\bm{A})$ として、

$$ \begin{equation} \|\bm{A}\|_2 \leq \|\bm{A}\|_F \leq \sqrt{r}\,\|\bm{A}\|_2 \end{equation} $$

左側の証明: 特異値表現より $\|\bm{A}\|_F^2 = \sum_{i=1}^r \sigma_i^2$ です。この和は必ず最大項 $\sigma_1^2$ 以上なので、

$$ \|\bm{A}\|_F^2 = \sigma_1^2 + \sigma_2^2 + \cdots + \sigma_r^2 \geq \sigma_1^2 = \|\bm{A}\|_2^2 $$

両辺の平方根を取れば $\|\bm{A}\|_2 \leq \|\bm{A}\|_F$。等号は $\sigma_2 = \cdots = \sigma_r = 0$、つまり $\bm{A}$ がランク1のときに限ります。

右側の証明: 逆に、$r$ 個の項はすべて最大項 $\sigma_1^2$ 以下ですから、

$$ \|\bm{A}\|_F^2 = \sum_{i=1}^r \sigma_i^2 \leq \sum_{i=1}^r \sigma_1^2 = r\,\sigma_1^2 = r\,\|\bm{A}\|_2^2 $$

平方根を取って $\|\bm{A}\|_F \leq \sqrt{r}\|\bm{A}\|_2$。等号は $\sigma_1 = \sigma_2 = \cdots = \sigma_r$、つまりすべての特異値が等しいとき、すなわち $\bm{A}$ が(スカラー倍を除いて)部分等長写像のときです。$n\times n$ 直交行列 $\bm{Q}$ はまさにこのケースで、$\|\bm{Q}\|_2 = 1$、$\|\bm{Q}\|_F = \sqrt{n}$ となり右側の等号が成立します。$\square$

同様に核ノルムとの間にも $\|\bm{A}\|_F \leq \|\bm{A}\|_* \leq \sqrt{r}\,\|\bm{A}\|_F$ が成り立ちます(ベクトルの $\|\bm{\sigma}\|_2 \leq \|\bm{\sigma}\|_1 \leq \sqrt{r}\|\bm{\sigma}\|_2$ そのものです)。

安定ランク

挟み込みの式を変形すると、

$$ 1 \leq \frac{\|\bm{A}\|_F^2}{\|\bm{A}\|_2^2} \leq r $$

という比が現れます。

特異値が偏った行列と平坦な行列について、フロベニウスノルムが挟み込みの下限寄りか上限寄りかを数直線上に示し、安定ランクが1.03と3.80になることを比較した図

上下2段で、特異値の並び方が挟み込みのどこに落ちるかを比べた図です。上段の「ほぼランク1」の行列($\sigma=4.0, 0.6, 0.4, 0.2$)では、$\|\bm{A}\|_F=4.07$ が下限 $\sigma_1=4.00$ にほとんど貼り付いています。下段の「特異値が平坦」な行列($\sigma\approx3$ が4つ)では逆に $\|\bm{A}\|_F=5.85$ が上限 $\sqrt{4}\sigma_1=6.00$ のすぐ手前まで来ています。フロベニウスノルムが下限寄りなら特異値が一方向に偏っており、上限寄りならエネルギーが均等に散らばっているという読み方ができ、それを1つの数値にしたのが図中の $1.03$ と $3.80$、すなわち次に述べる安定ランクです。

この $\mathrm{srank}(\bm{A}) := \|\bm{A}\|_F^2 / \|\bm{A}\|_2^2$ を安定ランク(stable rank)と呼びます。通常のランクは「特異値が $10^{-15}$ でも非ゼロならカウントする」という不連続で不安定な量ですが、安定ランクは特異値の大きさで重み付けした連続量なので、ノイズに強い「実効的なランク」の指標になります。ランダム行列理論や、ニューラルネットの重み行列の解析でよく使われます。実際、後で扱う写真の輝度行列は数学的ランクが427もあるのに、安定ランクはわずか1.09しかありません。「実質的にはほぼランク1の行列」という直感が、この1つの数値で表せるわけです。

ノルムどうしの大小関係が整理できたので、次は行列積に対する振る舞い — 劣乗法性を見ます。

劣乗法性と両立性

行列の積を取ると、ノルムはどう変わるでしょうか。「掛け算したものは、それぞれの大きさの積より大きくならない」という性質を劣乗法性(submultiplicativity)といい、誤差解析や収束証明の要になります。

主張: $\bm{A}\in\mathbb{C}^{m\times k}$、$\bm{B}\in\mathbb{C}^{k\times n}$ に対し

$$ \begin{equation} \|\bm{A}\bm{B}\|_F \leq \|\bm{A}\|_F \, \|\bm{B}\|_F \end{equation} $$

証明: 積の $(i,j)$ 成分は $(\bm{A}\bm{B})_{ij} = \sum_{l=1}^{k} a_{il} b_{lj}$ です。これは「$\bm{A}$ の第 $i$ 行」と「$\bm{B}$ の第 $j$ 列」の内積ですから、コーシー・シュワルツの不等式が使えます。

$$ |(\bm{A}\bm{B})_{ij}|^2 \leq \left(\sum_{l=1}^{k} |a_{il}|^2\right)\left(\sum_{l=1}^{k} |b_{lj}|^2\right) $$

この不等式を $i = 1,\dots,m$ と $j = 1,\dots,n$ の全部について足し合わせます。右辺は $i$ にしか依存しない因子と $j$ にしか依存しない因子の積なので、二重和が積に分離できます。

$$ \|\bm{A}\bm{B}\|_F^2 = \sum_{i,j}|(\bm{A}\bm{B})_{ij}|^2 \leq \left(\sum_{i}\sum_{l} |a_{il}|^2\right)\left(\sum_{j}\sum_{l} |b_{lj}|^2\right) $$

括弧の中身はそれぞれ $\|\bm{A}\|_F^2$、$\|\bm{B}\|_F^2$ そのものです。よって

$$ \|\bm{A}\bm{B}\|_F^2 \leq \|\bm{A}\|_F^2\|\bm{B}\|_F^2 $$

となり、平方根を取れば主張が得られます。$\square$

実はこの不等式はかなり緩く、より鋭い評価が知られています。

$$ \|\bm{A}\bm{B}\|_F \leq \|\bm{A}\|_2 \|\bm{B}\|_F, \qquad \|\bm{A}\bm{B}\|_F \leq \|\bm{A}\|_F \|\bm{B}\|_2 $$

前者の証明は簡単で、$\bm{B}$ の列を $\bm{b}_j$ と書けば $\|\bm{A}\bm{B}\|_F^2 = \sum_j \|\bm{A}\bm{b}_j\|_2^2 \leq \sum_j \|\bm{A}\|_2^2\|\bm{b}_j\|_2^2 = \|\bm{A}\|_2^2\|\bm{B}\|_F^2$ です。スペクトルノルムはフロベニウスノルム以下なので、こちらのほうが常に強い評価になります。深層学習のリプシッツ定数評価でスペクトルノルムが好まれるのは、この鋭さの差が層を重ねるごとに指数的に効いてくるからです。

また、ベクトルとの両立性(compatibility)

$$ \|\bm{A}\bm{x}\|_2 \leq \|\bm{A}\|_F \, \|\bm{x}\|_2 $$

も成り立ちます(上の不等式で $\bm{B}$ を列ベクトルとしたもの)。フロベニウスノルムは、ベクトルのL2ノルムと安全に併用できるということです。

ただし注意点があります。フロベニウスノルムは作用素ノルム(誘導ノルム)ではありません。 誘導ノルムなら必ず $\|\bm{I}\| = 1$ になるはずですが、$n\times n$ 単位行列に対して

$$ \|\bm{I}_n\|_F = \sqrt{n} \neq 1 \quad (n \geq 2) $$

です。「$\bm{A}$ がベクトルを最大どれだけ引き伸ばすか」を測っているのはスペクトルノルムのほうで、フロベニウスノルムはあくまで「成分の詰まり具合」を測っています。この違いは、リプシッツ定数を厳密に見積もりたい場面で決定的になります(詳しくはLipschitz連続性とスペクトルノルムを参照してください)。

理論的な性質が出そろいました。ここで一度、小さな行列に具体的な数字を入れて全部を確かめてみましょう。

具体例:$2\times 2$ 行列で全部を確かめる

冒頭に出した

$$ \bm{A} = \begin{pmatrix} 3 & 0 \\ 4 & 5 \end{pmatrix} $$

を使って、ここまでの公式が本当に一致するかを手計算で追いかけます。

(1)定義から

$$ \|\bm{A}\|_F = \sqrt{3^2+0^2+4^2+5^2} = \sqrt{50} \approx 7.0711 $$

(2)トレースから

$$ \bm{A}^{\mathsf{T}}\bm{A} = \begin{pmatrix} 3 & 4 \\ 0 & 5\end{pmatrix}\begin{pmatrix}3&0\\4&5\end{pmatrix} = \begin{pmatrix} 25 & 20 \\ 20 & 25\end{pmatrix} $$

対角成分の和は $25 + 25 = 50$ で、たしかに $\|\bm{A}\|_F^2 = 50$ と一致します。

(3)特異値から

$\bm{A}^{\mathsf{T}}\bm{A}$ の固有値を求めます。特性方程式は

$$ \det\begin{pmatrix} 25-\lambda & 20 \\ 20 & 25-\lambda \end{pmatrix} = (25-\lambda)^2 – 400 = 0 $$

より $25 – \lambda = \pm 20$、つまり $\lambda = 5, 45$ です。特異値はその平方根なので

$$ \sigma_1 = \sqrt{45} = 3\sqrt{5} \approx 6.7082, \qquad \sigma_2 = \sqrt{5} \approx 2.2361 $$

二乗和は $45 + 5 = 50$。定義と完全に一致しました。3通りの計算がすべて同じ答えを返すことが確認できます。

(4)挟み込みの検証

$$ \|\bm{A}\|_2 = \sigma_1 \approx 6.7082, \qquad \sqrt{r}\,\|\bm{A}\|_2 = \sqrt{2}\times 6.7082 \approx 9.4868 $$

なので $6.7082 \leq 7.0711 \leq 9.4868$。挟み込みは成立しており、しかも下限にかなり近い値です。これは $\sigma_1$ が $\sigma_2$ よりだいぶ大きい(=ほぼランク1に近い)ことを反映しています。安定ランクは $50/45 \approx 1.11$ で、「ランクは2だが実質1.1くらい」という感覚が数値になっています。

(5)核ノルムとの比較

$$ \|\bm{A}\|_* = \sigma_1 + \sigma_2 = 4\sqrt{5} \approx 8.9443 $$

たしかに $\|\bm{A}\|_F \leq \|\bm{A}\|_* \leq \sqrt{2}\|\bm{A}\|_F \approx 10.0$ が成り立っています。

(6)最良ランク1近似

次節で扱う定理を先取りすると、$\bm{A}$ に最も近いランク1行列は $\sigma_1 \bm{u}_1\bm{v}_1^{\mathsf{T}}$ で、実際に計算すると

$$ \bm{A}_1 = \begin{pmatrix} 1.5 & 1.5 \\ 4.5 & 4.5 \end{pmatrix} $$

となります。誤差は

$$ \|\bm{A} – \bm{A}_1\|_F = \left\|\begin{pmatrix} 1.5 & -1.5 \\ -0.5 & 0.5\end{pmatrix}\right\|_F = \sqrt{2.25+2.25+0.25+0.25} = \sqrt{5} = \sigma_2 $$

と、ちょうど $\sigma_2$ になりました。相対誤差は $\sqrt{5}/\sqrt{50} = 1/\sqrt{10} \approx 31.6\%$ です。「切り捨てた特異値がそのまま誤差になる」という美しい構造が、この小さな例からも見て取れます。

この「切り捨てた分がそのまま誤差」という現象は偶然ではありません。それを一般的に保証するのが Eckart-Young-Mirsky の定理です。

Eckart-Young-Mirsky 定理:打ち切りSVDは最良の低ランク近似

大きな行列 $\bm{A}$ を、ランクが $k$ しかない行列 $\bm{B}$ で近似したいとします。ランク $k$ の $m\times n$ 行列は $k(m+n)$ 個程度のパラメータで表せるので、$k \ll \min(m,n)$ なら大幅な圧縮になります。問題は「どのランク $k$ 行列を選べばいちばん近いのか」です。

候補は無限にあります。総当たりで探すのは絶望的に見えます。ところが答えは拍子抜けするほど単純で、SVDを上位 $k$ 項で打ち切るだけです。

定理(Eckart-Young-Mirsky): $\bm{A}\in\mathbb{C}^{m\times n}$ の特異値分解を $\bm{A} = \sum_{i=1}^{r}\sigma_i \bm{u}_i\bm{v}_i^{\mathsf{H}}$($\sigma_1\geq\cdots\geq\sigma_r>0$)とし、その上位 $k$ 項による打ち切りを

$$ \bm{A}_k := \sum_{i=1}^{k}\sigma_i \bm{u}_i \bm{v}_i^{\mathsf{H}} $$

とする。このとき、$\mathrm{rank}(\bm{B})\leq k$ を満たす任意の $\bm{B}$ に対して

$$ \begin{equation} \|\bm{A} – \bm{B}\|_F \geq \|\bm{A} – \bm{A}_k\|_F = \sqrt{\sum_{i=k+1}^{r}\sigma_i^2} \end{equation} $$

が成り立つ。すなわち $\bm{A}_k$ はフロベニウスノルムの意味で最良のランク $k$ 近似である。

最小値が $\sqrt{\sum_{i>k}\sigma_i^2}$ になることは簡単です。$\bm{A} – \bm{A}_k = \sum_{i=k+1}^{r}\sigma_i\bm{u}_i\bm{v}_i^{\mathsf{H}}$ の特異値は $\sigma_{k+1},\dots,\sigma_r$ なので、特異値表現から直ちに従います。

最良性の証明はやや技巧的ですが、特異値に関するWeylの不等式

$$ \sigma_{i+j-1}(\bm{X}+\bm{Y}) \leq \sigma_i(\bm{X}) + \sigma_j(\bm{Y}) $$

を使うと3行で終わります。$\bm{X} = \bm{A}-\bm{B}$、$\bm{Y} = \bm{B}$、$j = k+1$ と置いてみましょう。$\mathrm{rank}(\bm{B})\leq k$ より $\sigma_{k+1}(\bm{B}) = 0$ なので、右辺の第2項が消えて

$$ \sigma_{i+k}(\bm{A}) \leq \sigma_i(\bm{A}-\bm{B}) + \sigma_{k+1}(\bm{B}) = \sigma_i(\bm{A}-\bm{B}) $$

が任意の $i \geq 1$ について成り立ちます。「$\bm{A}$ の $(i+k)$ 番目の特異値は、誤差行列の $i$ 番目の特異値で下から押さえられる」という主張です。あとは両辺を二乗して $i$ について足すだけです。

$$ \|\bm{A}-\bm{B}\|_F^2 = \sum_{i\geq 1}\sigma_i(\bm{A}-\bm{B})^2 \geq \sum_{i\geq 1}\sigma_{i+k}(\bm{A})^2 = \sum_{j > k}\sigma_j(\bm{A})^2 $$

右辺は $\|\bm{A}-\bm{A}_k\|_F^2$ に等しいので、証明が完了します。$\square$

ランク20の近似について、上位20個の特異値を使う打ち切りSVDの誤差13.64%が、他の選び方(無作為に選んだ20個や2番目から20個)の誤差より必ず小さいことを示した図

定理の主張を、後で使う写真の輝度行列で数値的に確かめた図です。左は「$\sigma_1$ は必ず入れたうえで、残り19個を上位100個から無作為に選ぶ」を400通り試した誤差のヒストグラムで、最小でも $16.9\%$ と、赤い線(上位20個をそのまま取る打ち切りSVD)の $13.64\%$ より右側にしか現れません。右の棒グラフでは、1個飛ばしで20個拾うと $24.32\%$、最大の $\sigma_1$ を外して2番目から20個拾うと $96.59\%$ まで誤差が跳ね上がります。同じランク20という制約でも、上位から順に取る以外の選び方はすべて損をすることが、定理の不等式どおりに現れています。

Mirsky はさらに、この最良性がすべてのユニタリ不変ノルム(フロベニウス、スペクトル、核ノルムなど、$\|\bm{U}\bm{A}\bm{V}\| = \|\bm{A}\|$ を満たすノルム全体)について同時に成り立つことを示しました。つまり「打ち切りSVDが最良」というのは、測り方の細部に依存しない極めて頑健な事実なのです。

この定理が実務で果たす役割は絶大です。

  • PCA(主成分分析): 中心化データ行列の打ち切りSVDが、再構成誤差(フロベニウスノルム)を最小にする低次元表現を与えます。「PCAが最適である」という主張の中身がこの定理です。詳しくは主成分分析(PCA)完全ガイドを参照してください。
  • 画像・信号の圧縮: 上位 $k$ 特異値だけを残すことで、$\sqrt{\sum_{i>k}\sigma_i^2}$ の誤差と引き換えにデータ量を削減できます。しかも「$k$ をいくつにすれば誤差が何%になるか」が事前に特異値だけから読めます。
  • 推薦システム・行列補完: 「評価行列は本質的に低ランクである」という仮定のもと、観測部分に合う低ランク行列を探します。目的関数は観測成分上のフロベニウス誤差です。
  • モデル圧縮・LoRA: 学習済み重み行列を低ランク近似する、あるいは差分を低ランクに制約して学習する手法の理論的な裏付けになります。

理論はここまでです。次はコードで、これらの性質が本当に成り立つことを目で確かめましょう。

Pythonでの実装と実験

実験1:3種のノルムを比較して挟み込みを確認する

まず小さなランダム行列に対して、定義・トレース・特異値の3通りの計算が一致すること、そして挟み込みの不等式が成立することを確認します。

import numpy as np
import matplotlib, matplotlib.pyplot as plt

# 日本語フォント設定
for cand in ["Hiragino Sans", "Yu Gothic", "Noto Sans CJK JP", "IPAexGothic", "Meiryo"]:
    if any(cand == f.name for f in matplotlib.font_manager.fontManager.ttflist):
        plt.rcParams["font.family"] = cand
        break
plt.rcParams["axes.unicode_minus"] = False

np.random.seed(0)
A = np.random.randn(6, 4)          # 6×4 のランダム行列

# --- 3通りの計算 ---
fro_def   = np.sqrt(np.sum(A**2))                    # 定義:全成分の二乗和
fro_trace = np.sqrt(np.trace(A.T @ A))               # トレース表現
s = np.linalg.svd(A, compute_uv=False)               # 特異値
fro_svd   = np.sqrt(np.sum(s**2))                    # 特異値の二乗和

print(f"定義から       : {fro_def:.6f}")
print(f"tr(A^T A) から : {fro_trace:.6f}")
print(f"特異値から     : {fro_svd:.6f}")
print(f"numpy の値     : {np.linalg.norm(A, 'fro'):.6f}")
print(f"特異値 sigma   : {np.round(s, 4)}")

# --- 3種のノルムと挟み込み ---
r = np.linalg.matrix_rank(A)
spec = s[0]                    # スペクトルノルム
nuc  = s.sum()                 # 核ノルム
print(f"\nrank = {r}")
print(f"||A||_2 = {spec:.4f} <= ||A||_F = {fro_def:.4f} <= sqrt(r)||A||_2 = {np.sqrt(r)*spec:.4f}")
print(f"||A||_F = {fro_def:.4f} <= ||A||_* = {nuc:.4f} <= sqrt(r)||A||_F = {np.sqrt(r)*fro_def:.4f}")
print(f"安定ランク = {fro_def**2 / spec**2:.4f}  (1 <= srank <= {r})")

実行すると次のような出力になります。

定義から       : 5.402045
tr(A^T A) から : 5.402045
特異値から     : 5.402045
numpy の値     : 5.402045
特異値 sigma   : [4.3211 2.7602 1.5697 0.6536]

rank = 4
||A||_2 = 4.3211 <= ||A||_F = 5.4020 <= sqrt(r)||A||_2 = 8.6423
||A||_F = 5.4020 <= ||A||_* = 9.3047 <= sqrt(r)||A||_F = 10.8041
安定ランク = 1.5629  (1 <= srank <= 4)

3通りの計算が小数点以下6桁まで完全に一致しました。導出したトレース表現と特異値表現が正しいことの数値的な裏付けです。挟み込みも成立しており、$4.3211 \leq 5.4020 \leq 8.6423$ と、フロベニウスノルムは下限(スペクトルノルム)寄りに位置しています。$\sigma_1 = 4.32$ が他より一段大きいためで、そのことは安定ランク $1.56$(数学的ランクは4)にも表れています。ガウス乱数の行列であっても、エネルギーは一様に散らばらず先頭の特異方向に偏るという、ランダム行列の典型的な振る舞いです。

次に、特異値の分布とノルムの関係を可視化してみます。

import numpy as np
import matplotlib.pyplot as plt

np.random.seed(0)
A = np.random.randn(6, 4)
s = np.linalg.svd(A, compute_uv=False)
fro, spec, nuc = np.sqrt((s**2).sum()), s[0], s.sum()
r = len(s)

fig, axes = plt.subplots(1, 2, figsize=(12, 4.5))

# 左:特異値とその二乗(エネルギー)
ax = axes[0]
idx = np.arange(1, r + 1)
ax.bar(idx - 0.2, s, width=0.4, label=r"特異値 $\sigma_i$", color="#4C72B0")
ax.bar(idx + 0.2, s**2, width=0.4, label=r"エネルギー $\sigma_i^2$", color="#DD8452")
ax.set_xticks(idx); ax.set_xlabel("番号 $i$"); ax.set_ylabel("大きさ")
ax.set_title("特異値と、その二乗(=各方向のエネルギー)")
ax.legend(); ax.grid(alpha=0.3, axis="y")

# 右:3種のノルムと挟み込みの範囲
ax = axes[1]
names = [r"$\|A\|_2$" + "\n(スペクトル)", r"$\|A\|_F$" + "\n(フロベニウス)", r"$\|A\|_*$" + "\n(核ノルム)"]
vals = [spec, fro, nuc]
ax.bar(names, vals, color=["#55A868", "#C44E52", "#8172B3"])
ax.axhline(spec, ls="--", c="gray"); ax.axhline(np.sqrt(r) * spec, ls="--", c="gray")
ax.fill_between([-0.5, 2.5], spec, np.sqrt(r) * spec, color="gray", alpha=0.15,
                label=r"$\|A\|_F$ の存在範囲 $[\sigma_1,\ \sqrt{r}\sigma_1]$")
ax.set_xlim(-0.5, 2.5); ax.set_ylabel("ノルムの値")
ax.set_title("3種のノルムの大小関係")
for i, v in enumerate(vals):
    ax.text(i, v + 0.2, f"{v:.2f}", ha="center")
ax.legend(); ax.grid(alpha=0.3, axis="y")

plt.tight_layout(); plt.show()

6×4ランダム行列の特異値と二乗の棒グラフ、およびスペクトルノルム4.32・フロベニウスノルム5.40・核ノルム9.30の大小関係と挟み込みの範囲を示した図

左のグラフから、特異値そのもの(青)よりも二乗(橙)のほうが減衰が急なことが読み取れます。$\sigma_1 = 4.32$ に対して $\sigma_1^2 = 18.7$、$\sigma_4 = 0.65$ に対して $\sigma_4^2 = 0.43$ ですから、二乗することで大きい方向がさらに強調されるわけです。フロベニウスノルムがこの二乗和で定義されている以上、「フロベニウスノルムはほぼ上位の特異方向で決まる」という感覚を持っておくと役に立ちます。

右のグラフでは、$\|\bm{A}\|_F = 5.40$ がグレーの帯(挟み込みが許す範囲 $[4.32,\ 8.64]$)の下側に位置しています。核ノルム $9.30$ はその帯すら超えていますが、これは別の不等式 $\|\bm{A}\|_F \le \|\bm{A}\|_* \le \sqrt{r}\|\bm{A}\|_F$ の範囲内なので矛盾しません。3つのノルムが常に $\|\bm{A}\|_2 \le \|\bm{A}\|_F \le \|\bm{A}\|_*$ の順に並ぶことも確認できます。

劣乗法性 $\|\bm{A}\bm{B}\|_F \leq \|\bm{A}\|_F\|\bm{B}\|_F$ が「どのくらい緩い」不等式なのかも見ておきましょう。

import numpy as np
import matplotlib.pyplot as plt

rng = np.random.default_rng(3)
ratios = []
for _ in range(2000):
    X = rng.standard_normal((4, 3))
    Y = rng.standard_normal((3, 5))
    ratios.append(np.linalg.norm(X @ Y, "fro") /
                  (np.linalg.norm(X, "fro") * np.linalg.norm(Y, "fro")))
ratios = np.array(ratios)

plt.figure(figsize=(8, 4.5))
plt.hist(ratios, bins=50, color="#4C72B0", alpha=0.8)
plt.axvline(1.0, color="red", ls="--", lw=2, label="劣乗法性の上限 = 1")
plt.axvline(ratios.mean(), color="orange", ls="-", lw=2,
            label=f"平均 = {ratios.mean():.3f}")
plt.xlabel(r"比 $\|AB\|_F\ /\ (\|A\|_F\|B\|_F)$")
plt.ylabel("頻度")
plt.title("劣乗法性はどれくらい緩い不等式か(ランダム行列2000組)")
plt.legend(); plt.grid(alpha=0.3); plt.xlim(0, 1.05)
plt.tight_layout(); plt.show()

print(f"比の平均 = {ratios.mean():.4f}, 最大 = {ratios.max():.4f}")

ランダム行列2000組についてAB のフロベニウスノルムを A と B のノルムの積で割った比のヒストグラム。平均0.573で上限1には届かないことを示す図

出力は「比の平均 = 0.5728, 最大 = 0.8537」となり、ヒストグラムは 0.6 付近を中心にまとまって、上限の 1.0 には一度も届きません。劣乗法性は破れないものの、実際にはかなり余裕のある評価だということが分かります。理由は、コーシー・シュワルツの等号が成立するには「$\bm{A}$ のすべての行が $\bm{B}$ のすべての列と平行」という極端な状況が必要だからです。層を何十層も重ねる深層ネットワークでこの緩い不等式を繰り返し適用すると、リプシッツ定数の上界が天文学的に大きくなって使い物にならなくなります。より鋭い $\|\bm{A}\bm{B}\|_F \le \|\bm{A}\|_2\|\bm{B}\|_F$ が好まれる理由がここにあります。

数値実験で基本性質が確認できました。次は Eckart-Young 定理を、実際の写真で体感してみましょう。

実験2:画像の低ランク近似と相対フロベニウス誤差

scikit-learn に同梱されているサンプル画像をグレースケール化して $427\times 640$ の行列とみなし、ランク $k$ を変えながら打ち切りSVDで近似します。誤差が理論値 $\sqrt{\sum_{i>k}\sigma_i^2}$ と一致するかも同時に確認します。

import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_sample_image

# 画像をグレースケール行列にする(427×640)
img = load_sample_image("china.jpg").astype(np.float64).mean(axis=2)
U, s, Vt = np.linalg.svd(img, full_matrices=False)
fro_total = np.sqrt((s**2).sum())
print(f"画像サイズ: {img.shape}, 数学的ランク: {np.linalg.matrix_rank(img)}")
print(f"||A||_F = {fro_total:.1f}, sigma_1 = {s[0]:.1f}")
print(f"安定ランク = {fro_total**2 / s[0]**2:.3f}")

def low_rank(k):
    """上位k個の特異値だけで再構成した行列を返す"""
    return (U[:, :k] * s[:k]) @ Vt[:k]

# ランクを変えて相対誤差を測る(実測 vs 理論値)
print("\n  k | 実測相対誤差 | 理論値√(Σσ²)/‖A‖_F | 説明できるエネルギー | 圧縮率")
for k in [1, 5, 10, 20, 50, 100, 200]:
    Ak = low_rank(k)
    err_emp = np.linalg.norm(img - Ak, "fro") / fro_total
    err_thy = np.sqrt((s[k:]**2).sum()) / fro_total
    energy  = 100 * (s[:k]**2).sum() / (s**2).sum()
    comp    = k * (img.shape[0] + img.shape[1] + 1) / img.size
    print(f"{k:3d} | {err_emp*100:11.3f}% | {err_thy*100:17.3f}% | {energy:17.3f}% | {comp*100:5.2f}%")

出力は次のとおりです。

画像サイズ: (427, 640), 数学的ランク: 427
||A||_F = 87236.3, sigma_1 = 83442.2
安定ランク = 1.093

  k | 実測相対誤差 | 理論値√(Σσ²)/‖A‖_F | 説明できるエネルギー | 圧縮率
  1 |      29.170% |            29.170% |            91.491% |  0.39%
  5 |      18.414% |            18.414% |            96.609% |  1.95%
 10 |      16.022% |            16.022% |            97.433% |  3.91%
 20 |      13.637% |            13.637% |            98.140% |  7.82%
 50 |      10.280% |            10.280% |            98.943% | 19.54%
100 |       7.355% |             7.355% |            99.459% | 39.08%
200 |       3.610% |             3.610% |            99.870% | 78.16%

実測誤差と理論値 $\sqrt{\sum_{i>k}\sigma_i^2}\,/\,\|\bm{A}\|_F$ が小数点以下3桁まで完全に一致しています。Eckart-Young-Mirsky 定理の誤差公式が正しいことの直接的な確認です。ここから読み取れることが3つあります。

第一に、$k=1$ ですでにエネルギーの91.5%を説明しています。安定ランクが1.093しかないことと整合的で、その正体は「画像全体の平均的な明るさ」です。$\sigma_1$ に対応する成分は輝度のDC的な土台を表し、これが巨大なエネルギーを持ちます。第二に、それでも相対誤差は29%と大きく、エネルギー比と見た目の品質は別物だという教訓が得られます。残り8.5%のエネルギーにこそ、輪郭や質感といった「見えている情報」が入っているのです。第三に、$k=50$ なら圧縮率19.5%(データ量が約5分の1)で相対誤差10%です。実用的なトレードオフの目安になります。

実際の見た目も並べて確認しましょう。

import numpy as np
import matplotlib.pyplot as plt

ks = [1, 5, 20, 50, 200]
fig, axes = plt.subplots(2, 3, figsize=(13, 7.5))
axes = axes.ravel()

axes[0].imshow(img, cmap="gray"); axes[0].set_title("元画像(ランク427)")
axes[0].axis("off")
for ax, k in zip(axes[1:], ks):
    Ak = low_rank(k)
    err = np.linalg.norm(img - Ak, "fro") / fro_total
    ax.imshow(np.clip(Ak, 0, 255), cmap="gray")
    ax.set_title(f"ランク {k}:相対誤差 {err*100:.1f}%")
    ax.axis("off")

plt.suptitle("打ち切りSVDによる低ランク近似(フロベニウス最良近似)", fontsize=14)
plt.tight_layout(); plt.show()

元画像とランク1・5・20・50・200の低ランク近似を並べ、相対誤差29.2%から3.6%まで見た目がどう変わるかを比較した図

ランク1では画像は縦方向の縞模様にしか見えません。1本の列ベクトルと1本の行ベクトルの外積、つまり「縦のプロファイル×横のプロファイル」しか表現できないので当然です。ランク5で建物の輪郭がうっすら現れ、ランク20では塔の屋根の重なりまで判別でき、何が写っているかがはっきり分かるようになります。ランク50ではほぼ実用的な品質で、ランク200になると元画像との違いを目視で見つけるのが難しくなります。「相対誤差13.6%(ランク20)」という数値が視覚的にはどの程度なのかを体感できるのが、この図の価値です。

誤差がどう減っていくかを、特異値の減衰と並べて描くとさらに見通しがよくなります。

import numpy as np
import matplotlib.pyplot as plt

ks = np.arange(1, 428)
err_curve = np.array([np.sqrt((s[k:]**2).sum()) / fro_total for k in ks])
energy_curve = np.cumsum(s**2) / (s**2).sum()

fig, axes = plt.subplots(1, 3, figsize=(15, 4.5))

axes[0].semilogy(np.arange(1, len(s) + 1), s, color="#4C72B0")
axes[0].set_xlabel("番号 $i$"); axes[0].set_ylabel(r"特異値 $\sigma_i$(対数軸)")
axes[0].set_title("特異値の減衰"); axes[0].grid(alpha=0.3)

axes[1].plot(ks, err_curve * 100, color="#C44E52", lw=2)
for k in [1, 20, 50, 200]:
    axes[1].plot(k, err_curve[k - 1] * 100, "o", color="black")
    axes[1].annotate(f"k={k}\n{err_curve[k-1]*100:.1f}%", (k, err_curve[k - 1] * 100),
                     textcoords="offset points", xytext=(12, 8), fontsize=9)
axes[1].set_xlabel("ランク $k$"); axes[1].set_ylabel("相対フロベニウス誤差 [%]")
axes[1].set_title(r"誤差 $\sqrt{\sum_{i>k}\sigma_i^2}\,/\,\|A\|_F$"); axes[1].grid(alpha=0.3)

axes[2].plot(ks, energy_curve * 100, color="#55A868", lw=2)
for t, c in [(90, "gray"), (99, "orange"), (99.9, "red")]:
    axes[2].axhline(t, ls="--", color=c, lw=1)
    axes[2].text(300, t + 0.15, f"{t}%", color=c, fontsize=9)
axes[2].set_xlabel("ランク $k$"); axes[2].set_ylabel("累積エネルギー [%]")
axes[2].set_ylim(85, 100.5)
axes[2].set_title("上位 $k$ 個で説明できるエネルギー"); axes[2].grid(alpha=0.3)

plt.tight_layout(); plt.show()

c = np.cumsum(s**2) / (s**2).sum()
for t in [0.90, 0.95, 0.99, 0.999]:
    print(f"エネルギー{t*100:5.1f}% を説明するのに必要なランク: {int(np.searchsorted(c, t)) + 1}")

特異値の対数減衰、ランクに対する相対フロベニウス誤差の減少、上位k個で説明できる累積エネルギーの3枚を並べた図

出力は「90.0% → ランク1、95.0% → ランク3、99.0% → ランク54、99.9% → ランク216」です。

左のグラフ(対数軸)は、特異値が最初に一気に落ちたあと、緩やかな減衰に移ることを示しています。この「最初の急落」が低ランク近似が効く条件で、逆にホワイトノイズ行列のように特異値がフラットな行列は圧縮できません。中央のグラフでは誤差が単調に減りますが、その減り方は緩やかで、誤差を半分にするにはランクを大幅に増やす必要があります。右のグラフはエネルギー基準の見方で、同じ「99%」でもエネルギー基準ならランク54で足りるのに、99.9%を狙うとランク216が要るという急激な要求増が見て取れます。実務でランクを決めるときは、エネルギー基準だけでなく、必ず実際の再構成品質を目で見て確認したほうがよいという教訓です。

低ランク近似はフロベニウスノルムの「距離としての使い方」でした。最後に、もうひとつの主要な使い方 — 「罰則としての使い方」を見ます。

実験3:重み減衰(L2正則化)はフロベニウスノルム罰則である

ニューラルネットの学習で当たり前に使われる重み減衰は、損失関数に重み行列のフロベニウスノルムの二乗を足しているだけです。層 $l$ の重み行列を $\bm{W}^{(l)}$ とすると、正則化つきの目的関数は

$$ J(\bm{W}) = L(\bm{W}) + \frac{\lambda}{2}\sum_{l}\left\|\bm{W}^{(l)}\right\|_F^2 $$

です。なぜこれが「重みを減衰させる」ことになるのか、勾配を計算すれば一目瞭然です。$\|\bm{W}\|_F^2 = \sum_{i,j} w_{ij}^2$ を $w_{ij}$ で偏微分すると、その項だけが残って

$$ \frac{\partial}{\partial w_{ij}}\|\bm{W}\|_F^2 = 2w_{ij} \quad\Longleftrightarrow\quad \nabla_{\bm{W}}\|\bm{W}\|_F^2 = 2\bm{W} $$

という、驚くほど素直な形になります。$\lambda/2$ を掛けた項の勾配は $\lambda\bm{W}$ です。これを勾配降下の更新式に入れると、

$$ \bm{W} \leftarrow \bm{W} – \eta\left(\nabla_{\bm{W}} L + \lambda \bm{W}\right) = (1 – \eta\lambda)\,\bm{W} – \eta \nabla_{\bm{W}} L $$

となります。$(1-\eta\lambda)$ という係数が前に付いている点に注目してください。毎ステップ、重みを一定割合だけ原点方向に縮めてから、通常の勾配ステップを踏む。これが「weight decay(重みの減衰)」という名前の由来です。もしフロベニウスノルムの代わりに核ノルムを使えば勾配は特異値の符号に依存する複雑な形になり、L1を使えば場合分けが必要になります。フロベニウスノルムだけが、勾配が元の行列そのものという理想的な単純さを持つわけで、これが実務で圧倒的に使われる最大の理由です。

実際に、正則化の強さ $\lambda$ を変えて $\|\bm{W}\|_F$ と汎化性能がどう動くかを見てみます。ノイズの多い月型データを、あえて過剰な容量のネットワークで学習させます。

import numpy as np
import torch
import torch.nn as nn
from sklearn.datasets import make_moons
from sklearn.model_selection import train_test_split

X, y = make_moons(n_samples=300, noise=0.35, random_state=0)
Xtr, Xte, ytr, yte = train_test_split(X, y, test_size=0.5, random_state=0)
T = lambda a: torch.tensor(a, dtype=torch.float32)
Xtr_, ytr_, Xte_, yte_ = T(Xtr), T(ytr)[:, None], T(Xte), T(yte)[:, None]

def train(wd, epochs=3000):
    """weight_decay=wd で学習し、‖W‖_F と精度の履歴を返す"""
    torch.manual_seed(0)
    model = nn.Sequential(nn.Linear(2, 128), nn.Tanh(),
                          nn.Linear(128, 128), nn.Tanh(),
                          nn.Linear(128, 1))
    opt = torch.optim.Adam(model.parameters(), lr=0.01, weight_decay=wd)
    lossf = nn.BCEWithLogitsLoss()
    hist = []
    for _ in range(epochs):
        opt.zero_grad()
        out = model(Xtr_)
        loss = lossf(out, ytr_)
        loss.backward()
        opt.step()
        with torch.no_grad():
            # 全重み行列のフロベニウスノルム(バイアスは除く)
            fro = torch.sqrt(sum((p**2).sum() for n, p in model.named_parameters()
                                 if "weight" in n)).item()
            tr_acc = (((out > 0).float() == ytr_).float().mean()).item()
            te_acc = (((model(Xte_) > 0).float() == yte_).float().mean()).item()
        hist.append((loss.item(), fro, tr_acc, te_acc))
    W = np.concatenate([p.detach().numpy().ravel()
                        for n, p in model.named_parameters() if "weight" in n])
    return np.array(hist), W, model

results = {wd: train(wd) for wd in [0.0, 1e-3, 1e-2, 1e-1]}
print("weight_decay | ||W||_F | 訓練精度 | テスト精度 | 重みの標準偏差")
for wd, (h, W, _) in results.items():
    print(f"{wd:12} | {h[-1,1]:7.3f} | {h[-1,2]:8.3f} | {h[-1,3]:10.3f} | {W.std():.4f}")

出力は次のようになります。

weight_decay | ||W||_F | 訓練精度 | テスト精度 | 重みの標準偏差
         0.0 |  57.292 |    1.000 |      0.873 | 0.4424
       0.001 |   9.987 |    0.920 |      0.920 | 0.0771
        0.01 |   4.749 |    0.913 |      0.913 | 0.0367
         0.1 |   1.822 |    0.773 |      0.847 | 0.0141

この4行に、正則化のすべてが凝縮されています。$\lambda = 0$ では $\|\bm{W}\|_F$ が57.3まで膨らみ、訓練精度は100%に達しますが、テスト精度は87.3%止まりです。ノイズを暗記するために重みが極端に大きくなった典型的な過学習です。$\lambda = 10^{-3}$ にすると $\|\bm{W}\|_F$ は10.0へと6分の1に縮み、テスト精度は92.0%まで改善します。訓練精度とテスト精度の差(汎化ギャップ)が12.7ポイントから0ポイントへ消えている点が印象的です。さらに $\lambda = 0.1$ まで強めると $\|\bm{W}\|_F = 1.82$ と縮みすぎて、訓練精度77.3%と表現力不足に陥ります。フロベニウスノルムが「モデルの複雑さ」の代理指標として機能していることが、数値としてはっきり見えます。

学習の過程と重み分布も描いてみましょう。

import numpy as np
import matplotlib.pyplot as plt

fig, axes = plt.subplots(1, 3, figsize=(15, 4.5))
colors = {0.0: "#C44E52", 1e-3: "#DD8452", 1e-2: "#4C72B0", 1e-1: "#55A868"}

# 左:||W||_F の推移
for wd, (h, W, _) in results.items():
    axes[0].plot(h[:, 1], color=colors[wd], lw=1.8, label=f"$\\lambda$={wd}")
axes[0].set_xlabel("エポック"); axes[0].set_ylabel(r"$\|W\|_F$")
axes[0].set_title(r"重み行列のフロベニウスノルムの推移")
axes[0].legend(); axes[0].grid(alpha=0.3)

# 中央:テスト精度の推移
for wd, (h, W, _) in results.items():
    axes[1].plot(h[:, 3], color=colors[wd], lw=1.5, label=f"$\\lambda$={wd}")
axes[1].set_xlabel("エポック"); axes[1].set_ylabel("テスト精度")
axes[1].set_title("汎化性能の推移"); axes[1].set_ylim(0.6, 1.0)
axes[1].legend(); axes[1].grid(alpha=0.3)

# 右:学習後の重みの分布
for wd, (h, W, _) in results.items():
    axes[2].hist(W, bins=120, histtype="step", lw=1.8, density=True,
                 color=colors[wd], label=f"$\\lambda$={wd} ($\\|W\\|_F$={h[-1,1]:.1f})")
axes[2].set_xlim(-1.0, 1.0); axes[2].set_xlabel("重みの値 $w_{ij}$"); axes[2].set_ylabel("密度")
axes[2].set_title("学習後の重み分布(罰則が強いほど原点に集中)")
axes[2].legend(fontsize=9); axes[2].grid(alpha=0.3)

plt.tight_layout(); plt.show()

重み減衰の強さλを変えたときの重み行列フロベニウスノルムの推移、テスト精度の推移、学習後の重み分布を並べた図

左のグラフでは、$\lambda=0$ の曲線だけが学習とともに単調に上昇し続けます。損失を下げるために重みを大きくすることに何のブレーキもかからないからです。一方 $\lambda>0$ の曲線は、途中で「損失を下げる力」と「原点へ引き戻す力 $-\eta\lambda\bm{W}$」が釣り合い、$\|\bm{W}\|_F$ が一定値に落ち着きます。$\lambda$ が大きいほど低い水準で平衡するという、更新式 $(1-\eta\lambda)\bm{W}$ から予想したとおりの挙動です。

右のヒストグラムは、罰則の効果をもっとも直接的に示しています。$\lambda=0$(赤)の分布は裾が大きく広がり、$|w_{ij}| > 1$ の重みが全体の 4.6%(最大で 3.81)もあります(標準偏差 0.442)。$\lambda$ を強めるにつれて分布はどんどん原点付近に集中し、$\lambda=0.1$(緑)では標準偏差 0.014、最大値でも 0.094 と、ゼロ付近に押し込まれた鋭いピークになります。ここで大事なのは、分布がゼロ付近に集まってはいるが、ぴったりゼロの重みが大量にできるわけではないという点です。これがL2(フロベニウス)罰則の特徴で、スパース性を生むL1罰則との決定的な違いです。L1・L2の幾何学的な違いについては正則化の理論 — L1(Lasso)とL2(Ridge)の幾何学的理解で詳しく扱っています。

中央のテスト精度を見ると、$\lambda=0$(赤)は学習のごく初期、30エポック目に 92.0% というピークを付けたあと下がり続け、最終的に 87.3% で終わっています。もし30エポックで学習を止めていれば、正則化なしでも $\lambda=10^{-3}$ と同じ 92.0% が得られていたわけです。「早期終了はL2正則化と似た働きをする」と言われる根拠が、この曲線に直接表れています。一方 $\lambda=10^{-3}$ や $10^{-2}$ は3000エポック回しても91〜92%の水準を保ち続けており、止めどきを気にせずに済みます。過学習を「時間で止める」か「罰則で止める」かの違いです。

3つの実験で、フロベニウスノルムが「距離」としても「罰則」としても働くことが確認できました。最後に、実務で出会いやすい疑問を整理しておきます。

よくある疑問

Q. スペクトルノルムとフロベニウスノルム、どちらを使えばいいの?

「行列がベクトルを最大どれだけ引き伸ばすか」を知りたいならスペクトルノルムです。リプシッツ定数、安定性解析、GANの識別器のスペクトル正規化などがこれにあたります。一方、「行列が全体としてどれくらい大きいか」「2つの行列がどれくらい違うか」を測りたいならフロベニウスノルムです。計算コストの差も無視できません。フロベニウスノルムは $O(mn)$ で全成分を舐めるだけですが、スペクトルノルムは特異値を求める必要があり $O(mn\min(m,n))$ かかります。$4096\times 4096$ の重み行列を毎ステップ監視するようなケースでは、この差が効いてきます。

Q. なぜMSE損失はフロベニウスノルムの二乗なのか?

回帰でよく使う平均二乗誤差 $\frac{1}{N}\sum_i \|\bm{y}_i – \hat{\bm{y}}_i\|_2^2$ は、予測値を行列 $\hat{\bm{Y}}$ に束ねれば $\frac{1}{N}\|\bm{Y} – \hat{\bm{Y}}\|_F^2$ と1行で書けます。オートエンコーダの再構成損失も、行列補完の目的関数も、みな同じ形です。二乗しているおかげで平方根の微分($\sqrt{\cdot}$ は原点で微分不可能)を避けられるのも重要な理由で、実装では $\|\cdot\|_F^2$ の形で使うのが定石です。

Q. $\|\bm{A}\|_F$ が小さければ $\bm{A}$ はゼロに近いと言えるか?

言えます。挟み込み $\|\bm{A}\|_2 \le \|\bm{A}\|_F$ より、フロベニウスノルムが小さければスペクトルノルムも小さく、したがって任意のベクトルに対する作用 $\|\bm{A}\bm{x}\|_2 \le \|\bm{A}\|_F\|\bm{x}\|_2$ も小さくなります。逆は成り立ちません。$\|\bm{A}\|_2$ が小さくても、$\sqrt{r}$ 倍まではフロベニウスノルムが大きくなりえます。「フロベニウスが小さい」は「スペクトルが小さい」より強い主張だと覚えておくとよいでしょう。

Q. 行と列でスケールが違うデータでも使えるか?

注意が必要です。フロベニウスノルムは全成分を平等に扱うので、単位の異なる特徴量(たとえば「身長 [cm]」と「体重 [kg]」)が混在した行列にそのまま適用すると、値の大きい特徴量だけがノルムを支配してしまいます。低ランク近似やPCAの前に標準化が推奨されるのは、まさにこの理由です。直交変換には不変でも、対角行列によるスケーリングには不変ではないという点は押さえておきましょう。

まとめ

本記事では、フロベニウスノルムの定義から性質、応用までを解説しました。

  • 定義: $\|\bm{A}\|_F = \sqrt{\sum_{i,j}|a_{ij}|^2}$。行列を長さ $mn$ のベクトルとみなしたときのユークリッド長さ
  • トレース表現: $\|\bm{A}\|_F^2 = \mathrm{tr}(\bm{A}^{\mathsf{H}}\bm{A}) = \mathrm{tr}(\bm{A}\bm{A}^{\mathsf{H}})$。背後にフロベニウス内積 $\langle\bm{A},\bm{B}\rangle_F = \mathrm{tr}(\bm{A}^{\mathsf{H}}\bm{B})$ があり、行列空間はヒルベルト空間になる
  • 特異値表現: $\|\bm{A}\|_F = \sqrt{\sum_i\sigma_i^2}$。各特異方向のエネルギーの二乗和というピタゴラス的な構造
  • 直交不変性: $\|\bm{U}\bm{A}\bm{V}\|_F = \|\bm{A}\|_F$。座標の取り方によらない幾何学的な量
  • 不等式: $\|\bm{A}\|_2 \le \|\bm{A}\|_F \le \sqrt{r}\|\bm{A}\|_2$、$\|\bm{A}\bm{B}\|_F \le \|\bm{A}\|_F\|\bm{B}\|_F$。ただし作用素ノルムではない($\|\bm{I}_n\|_F = \sqrt{n}$)
  • Eckart-Young-Mirsky: 打ち切りSVD $\bm{A}_k$ が最良のランク $k$ 近似で、誤差はちょうど $\sqrt{\sum_{i>k}\sigma_i^2}$。実画像で理論値と実測値が完全一致することを確認
  • 正則化: $\nabla\|\bm{W}\|_F^2 = 2\bm{W}$ という単純な勾配が、$(1-\eta\lambda)\bm{W}$ という乗法的な縮小を生む。実験では $\lambda$ の増加とともに $\|\bm{W}\|_F$ が $57.3 \to 10.0 \to 4.7 \to 1.8$ と縮み、汎化ギャップが解消された

シャッテン $p$-ノルムという枠組みで見ると、フロベニウスノルムは「特異値ベクトルのL2ノルム」であり、スペクトルノルム($L_\infty$)と核ノルム($L_1$)のちょうど中間に位置します。この地図を持っておくと、「低ランク性がほしいから核ノルム」「リプシッツ性を抑えたいからスペクトルノルム」「単純に大きさを抑えたいからフロベニウス」という使い分けが自然に見えてくるはずです。

次のステップとして、以下の記事も参考にしてください。