GNNの過平滑化問題 — 層を深くすると性能が落ちる理由と対策

CNNは層を重ねるほど豊かな特徴表現が得られます。ResNetは152層、最新のモデルでは数百層の構造が当たり前です。では、グラフニューラルネットワーク(GNN)も同じように深くすれば性能が上がるでしょうか?

実際に試すとすぐ壁にぶつかります。GCN(Graph Convolutional Network)を4層・6層・8層と積み重ねると、2〜3層のときより精度がはっきりと落ちていくのです。なぜでしょうか。

この現象を「過平滑化(over-smoothing)」と呼びます。層を重ねるほどノードの表現が平均化されていき、最終的には全ノードの埋め込みが区別のつかない同じ値に収束してしまう—これがGNNを深くできない根本的な原因です。

GNNの過平滑化:層を重ねるほどノード表現が均一化する

この図は空手クラブグラフ(Karate Club Graph)でGCNの集約を繰り返した結果です。左(入力)では赤・青の2クラスがはっきり分かれていますが、右(5層後)ではすべてのノードが同じ色に均一化されています。クラス情報が完全に消えてしまいました。

この問題を解決するための応用先は2つあります。第一に分子グラフへの応用です。原子・化学結合の複雑なグラフを扱うとき、複数ホップ先の原子との長距離依存関係を捉えるには深いGNNが必要です。しかし過平滑化がその妨げになります。第二にソーシャルネットワーク解析です。大規模SNSグラフでは何千ホップもの影響関係があるのに、GNNを深くできないせいで局所近傍の情報しか活かせません。

本記事では、この過平滑化が数学的になぜ起きるのか、そしてどう対処するかを丁寧に解説します。

本記事の内容

  • メッセージパッシングの仕組みと、集約がグラフラプラシアン平滑化に等しいことの確認
  • ディリクレエネルギーの定義と、層ごとに指数減衰することの証明
  • 無限回集約時に全ノード表現が次数比例の定常分布へ収束することの導出
  • 残差接続・PairNorm・DropEdge・Jumping KnowledgeによるPython実測

前提知識

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

メッセージパッシングの復習

まず、GNNの基本操作を整理しておきましょう。GNNが行っていることをひとことで言えば「近傍ノードの情報を集めて自分の表現を更新する」という繰り返しです。これをメッセージパッシングと呼びます。

メッセージパッシング1ステップ:近傍ノードの情報を集約して表現を更新

図の中心ノード $v$ は、近傍の3つのノード $u_1, u_2, u_3$ からメッセージを受け取って自分の表現を更新しています。このステップを $\ell$ 層目と $(\ell+1)$ 層目の関係として書くと、次のようになります。

$$ \mathbf{h}_v^{(\ell+1)} = \sigma\!\left(\mathbf{W}^{(\ell)} \cdot \mathrm{AGG}\!\left\{\mathbf{h}_u^{(\ell)} \mid u \in \mathcal{N}(v) \cup \{v\}\right\}\right) $$

ここで $\mathbf{h}_v^{(\ell)} \in \mathbb{R}^d$ はノード $v$ の $\ell$ 層目の埋め込み、$\mathcal{N}(v)$ は $v$ の近傍集合、$\mathbf{W}^{(\ell)}$ は学習パラメータ、$\sigma$ は活性化関数(ReLUなど)、$\mathrm{AGG}$ は集約関数(平均・和・最大値など)です。

GCNの場合、集約は正規化平均で行われます。グラフの隣接行列を $\bm{A}$、次数行列を $\bm{D}$($D_{ii} = \sum_j A_{ij}$)として、自己ループを加えた正規化隣接行列を次のように定義します。

$$ \hat{\bm{A}} = \tilde{\bm{D}}^{-1/2} \tilde{\bm{A}} \tilde{\bm{D}}^{-1/2} $$

ここで $\tilde{\bm{A}} = \bm{A} + \bm{I}$(自己ループを追加)、$\tilde{\bm{D}} = \bm{D} + \bm{I}$(対応する次数行列)です。この行列を使うと、GCNの第 $\ell$ 層は行列形式で次のように書けます。

$$ \bm{H}^{(\ell+1)} = \sigma\!\left(\hat{\bm{A}} \bm{H}^{(\ell)} \bm{W}^{(\ell)}\right) $$

$\bm{H}^{(\ell)} \in \mathbb{R}^{n \times d}$ は全ノードの埋め込みを並べた行列です。この更新式の核心は、$\hat{\bm{A}}$ を掛ける操作にあります。これが何を意味するのか—次のセクションで明らかにします。

集約 = グラフラプラシアン平滑化

ここが過平滑化問題の核心です。$\hat{\bm{A}}$ を掛けるという操作は、実はグラフ信号の低域通過フィルタリングに等しいのです。

グラフ信号のラプラシアン平滑化:集約は低域通過フィルタとして働く

左図では隣接するノード間で符号が交互に変わる「高周波信号」があります。右図では3回の集約後、隣接ノード間の差が大幅に小さくなり、信号がなめらかになっています。まるで音声処理で高い周波数成分をカットする低域通過フィルタと同じ動きです。

なぜそうなるのかを、グラフラプラシアンの観点から考えましょう。

正規化グラフラプラシアン $\bm{\mathcal{L}}$ は次のように定義されます。

$$ \bm{\mathcal{L}} = \bm{I} – \bm{D}^{-1/2} \bm{A} \bm{D}^{-1/2} $$

つまり $\bm{D}^{-1/2} \bm{A} \bm{D}^{-1/2} = \bm{I} – \bm{\mathcal{L}}$ です。

自己ループなしの正規化隣接行列 $\bar{\bm{A}} = \bm{D}^{-1/2} \bm{A} \bm{D}^{-1/2}$ で考えると、集約操作は次のように書けます。

$$ \bm{H}^{(\ell+1)} = \bar{\bm{A}} \bm{H}^{(\ell)} = (\bm{I} – \bm{\mathcal{L}}) \bm{H}^{(\ell)} $$

$\bm{I} – \bm{\mathcal{L}}$ を繰り返し適用するということは、ラプラシアンが大きい方向(グラフ上の高周波成分)を繰り返し除去することです。$L$ 回繰り返すと:

$$ \bm{H}^{(L)} = (\bm{I} – \bm{\mathcal{L}})^L \bm{H}^{(0)} $$

$\bm{\mathcal{L}}$ の固有値を $\lambda_1 \leq \lambda_2 \leq \cdots \leq \lambda_n$ としたとき、$(\bm{I} – \bm{\mathcal{L}})$ の固有値は $(1 – \lambda_1) \geq (1 – \lambda_2) \geq \cdots \geq (1 – \lambda_n)$ です。

正規化グラフラプラシアンの固有値は常に $\lambda \in [0, 2]$ の範囲に収まるため、$(1 – \lambda) \in [-1, 1]$ となります。低周波成分($\lambda$ が小さい)は $1 – \lambda \approx 1$ なのでほぼ変化しません。しかし高周波成分($\lambda$ が大きい)は $|1 – \lambda| < 1$ となり、繰り返すうちに指数的に小さくなります。

つまりGNNのメッセージパッシングは層を重ねるたびに高周波成分(クラス間の差異)を取り除くローパスフィルタであり、これが過平滑化の数学的本質です。

このことを確認したうえで、過平滑化を定量的に測る指標に移りましょう。

ディリクレエネルギーと指数減衰

過平滑化の進行具合を測る最も自然な指標が「ディリクレエネルギー」です。

直感として理解しましょう。ディリクレエネルギーとは「隣り合ったノードの表現がどれだけ違うか」の総量です。値が大きければノード間に差異があり(分類に有利)、値が小さければノード表現が均一化されています(過平滑化)。

$$ E(\bm{H}) = \sum_{(u,v) \in \mathcal{E}} \|\mathbf{h}_u – \mathbf{h}_v\|^2 $$

ここで $\mathcal{E}$ はグラフのエッジ集合です。これは行列形式では次のように書き換えられます。

正規化グラフラプラシアン $\bm{\mathcal{L}} = \bm{I} – \bm{D}^{-1/2}\bm{A}\bm{D}^{-1/2}$ を使うと:

$$ E(\bm{H}) = \mathrm{tr}\!\left(\bm{H}^\top \tilde{\bm{L}} \bm{H}\right) $$

ここで $\tilde{\bm{L}}$ は非正規化ラプラシアン $\bm{L} = \bm{D} – \bm{A}$ から導かれます。この形式を使うとエネルギーの変化を解析できます。

エネルギー減衰の証明

GCN集約 $\bm{H}^{(\ell+1)} = \hat{\bm{A}} \bm{H}^{(\ell)}$(活性化関数を除いた線形版)のもとで、エネルギーがどう変化するかを考えます。

正規化隣接行列 $\hat{\bm{A}}$ の固有値を $\mu_i$ とすると、$\mu_i \in [-1, 1]$ です。スペクトル分解 $\hat{\bm{A}} = \bm{U} \bm{\Sigma} \bm{U}^\top$ を使ってエネルギーを書き直すと:

$\hat{\bm{A}}$ を $L$ 回掛けた後のエネルギーは、各固有方向でスケールが $\mu_i^{2L}$ 倍になります。つまり:

$$ E(\bm{H}^{(L)}) \leq \mu_{\max}^{2L} \cdot E(\bm{H}^{(0)}) $$

ここで $\mu_{\max} = \max_{i} |\mu_i|$ は $\hat{\bm{A}}$ の最大絶対固有値です。

$\hat{\bm{A}}$ の固有値は $-1 \leq \mu_i \leq 1$ の範囲にあり、$\mu_{\max} < 1$ が成り立つ場合(非二部グラフでは $\mu_{\max} = 1$ は最大固有値のみ)、エネルギーは層数 $L$ に対して指数的に減衰します。

$$ E(\bm{H}^{(L)}) \sim C \cdot \mu_{\max}^{2L} \to 0 \quad (L \to \infty) $$

これが過平滑化の定量的な証明です。層を1つ増やすたびにエネルギーが $\mu_{\max}^2$ 倍になり、ノード表現の多様性が失われていきます。

ディリクレエネルギーの指数減衰:層を重ねるほど隣接ノード差が消える

左は密なグラフ(減衰率0.85)、右は疎なグラフ(減衰率0.95)でのエネルギー推移を対数スケールで表示しています。いずれも層数が増えるにつれてエネルギーが指数的に減少し、10〜20層で実用的な閾値(グレー破線)を下回ることがわかります。密なグラフのほうが減衰が速い点に注目してください—これは近傍が多いほど情報が急速に混ざり合うことを意味します。

続いて、エネルギーがゼロに向かう過程でノード表現が具体的にどんな形に収束するかを見ていきましょう。

ノード表現が収束する先 — 定常分布

GNNの集約を無限回繰り返すと、ノード表現はどこへ向かうのでしょうか。これはグラフ上のランダムウォークの定常分布として理解できます。

GCN層数を増やすにつれてノード埋め込みが1点に収束(過平滑化)

散布図の横軸・縦軸はノード埋め込みの2次元です。入力時(左端)では赤クラスと青クラスが空間的に分かれています。層数が増えるにつれて、両クラスのノードが1点に集まっていきます。10層後(右端)では標準偏差が小さくなり、全ノードがほぼ同じ座標に位置しています—分類情報が消えてしまいました。

では収束先は具体的にどこでしょうか。

正規化隣接行列 $\bar{\bm{A}} = \bm{D}^{-1/2} \bm{A} \bm{D}^{-1/2}$ の最大固有値は $\mu_1 = 1$ で、対応する固有ベクトルは次数の平方根に比例します。

$$ \bm{u}_1 \propto \bm{D}^{1/2} \bm{1} = \left(\sqrt{d_1}, \sqrt{d_2}, \ldots, \sqrt{d_n}\right)^\top $$

ここで $d_i$ はノード $i$ の次数です。集約を繰り返すと、最大固有値 $\mu_1 = 1$ に対応する固有方向の成分だけが残り、他の方向の成分はすべてゼロに収束します。

結果として、全ノードの埋め込みは次数 $d_i$ に比例した一定のベクトルへ収束します。

$$ \mathbf{h}_v^{(\infty)} \propto \frac{d_v}{\sum_u d_u} \cdot \mathbf{c} $$

ここで $\mathbf{c}$ は定数ベクトル(チャネル方向の初期値から決まる)、$d_v / \sum_u d_u$ は次数の正規化です。これはグラフ上のランダムウォークの定常分布(次数比例)そのものです。

GCNの無限層極限:全ノード表現が次数比例の定常分布に収束

左図は空手クラブグラフの各ノードをその定常分布の確率(色の濃さ・サイズ)で表示しています。次数の高い「ハブ」ノードが大きく描かれ、収束後もこれらが残る成分です。右図はランダム初期分布から定常分布への収束過程を全変動距離で示しており、繰り返し回数(= GNN層数)が増えるほど指数的に定常分布へ近づくことが確認できます。

この収束先にはクラスラベルの情報が含まれていないという点が重要です。次数の大きいノードが赤クラスか青クラスかは問わず、次数だけで表現が決まります。これが過平滑化による精度劣化の本質です。

理論的な理解が深まったところで、実際のデータで確認してみましょう。

Pythonで実測:エネルギー減衰と精度劣化

理論上は「層が深くなるほどディリクレエネルギーが指数減衰し精度が落ちる」と予測されます。これをPythonで実証します。

空手クラブグラフ(34ノード、2クラス分類)を使い、ノード初期特徴量はランダム8次元ベクトル(クラスに微弱な相関あり)を用意します。

import numpy as np
import networkx as nx
from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import StandardScaler

np.random.seed(0)

# グラフと正規化隣接行列の構築
G = nx.karate_club_graph()
clubs = nx.get_node_attributes(G, "club")
labels = np.array([0 if clubs[n] == "Mr. Hi" else 1 for n in G.nodes()])
n = len(G)

adj = nx.to_numpy_array(G)
A_self = adj + np.eye(n)
D_inv_sqrt = np.diag(1.0 / np.sqrt(A_self.sum(axis=1)))
A_hat = D_inv_sqrt @ A_self @ D_inv_sqrt  # GCNの正規化隣接行列

# 初期特徴量(ランダム、クラスに微弱な相関)
np.random.seed(0)
H_init = np.random.randn(n, 8)
H_init[labels == 0] += 0.5

# 訓練/テスト分割(各クラス50%)
train_mask = np.zeros(n, dtype=bool)
for cls in [0, 1]:
    idx = np.where(labels == cls)[0]
    train_mask[idx[:len(idx)//2]] = True
test_mask = ~train_mask

# ディリクレエネルギー計算
def dirichlet_energy(H, adj):
    E = 0.0
    for u, v in zip(*np.nonzero(adj)):
        if u < v:
            E += np.sum((H[u] - H[v]) ** 2)
    return E

# 各層数で精度とエネルギーを計測
for n_layers in [1, 2, 3, 5, 6, 8, 10, 16]:
    Htmp = H_init.copy()
    for _ in range(n_layers):
        Htmp = A_hat @ Htmp   # 1層のGCN集約(重み行列なし)

    E = dirichlet_energy(Htmp, adj)

    scaler = StandardScaler()
    Xtrain = scaler.fit_transform(Htmp[train_mask])
    Xtest  = scaler.transform(Htmp[test_mask])
    clf = LogisticRegression(max_iter=1000, C=1.0, random_state=0)
    clf.fit(Xtrain, labels[train_mask])
    acc = clf.score(Xtest, labels[test_mask])
    print(f"  {n_layers:2d}層: 精度 = {acc:.4f},  エネルギー = {E:.1f}")

実行結果:

   1層: 精度 = 0.8889,  エネルギー = 208.2
   2層: 精度 = 0.9444,  エネルギー = 110.0
   3層: 精度 = 0.9444,  エネルギー = 64.7
   5層: 精度 = 0.8889,  エネルギー = 42.5
   6層: 精度 = 0.7778,  エネルギー = 38.3
   8層: 精度 = 0.7222,  エネルギー = 30.4
  10層: 精度 = 0.6111,  エネルギー = 27.1
  16層: 精度 = 0.6111,  エネルギー = 23.3

2〜3層でテスト精度0.9444というピークに達し、6層から0.7778へ落ち、10層以降は0.6111まで低下しています。一方ディリクレエネルギーは単調に減少しており、理論の予測と一致します。

層数 vs テスト精度:標準GCNは2〜3層がピークで深くなると急速に劣化

グラフから2点が読み取れます。第一に、標準GCN(赤)は2〜3層がピークで、層を重ねるほど性能が急速に劣化することが確認できます。第二に、残差接続あり(青破線)は深くなっても性能の低下が緩やかで、16層でも実用的な精度を保っています。これはまさに過平滑化対策の効果であり、次のセクションで詳しく説明します。

精度劣化の原因が過平滑化にあることを実測で確認できました。では、どうすれば深いGNNを作れるのでしょうか。

対策1: 残差接続(GCNII)

CNNでResNetが深さの壁を突き破ったように、GNNでもスキップコネクション(残差接続)が有効です。

残差接続:初期特徴量を直接後段に渡してノード固有性を保持

左図(残差なし)では各層が前の層の出力だけを受け取るため、初期の個別情報が層を経るたびに薄まっていきます。右図(残差あり)では各層が2層前の出力を加算で受け取るため、初期特徴量のノード固有性が保たれます。

GCNII(Graph Convolutional Network via Initial residual and Identity mapping、2020年)はこのアイデアを徹底したモデルです。その更新式は次のようになります。

$$ \bm{H}^{(\ell+1)} = \sigma\!\left(\left((1 – \alpha)\hat{\bm{A}}\bm{H}^{(\ell)} + \alpha \bm{H}^{(0)}\right)\!\left((1-\beta)\bm{I} + \beta \bm{W}^{(\ell)}\right)\right) $$

2つの工夫があります。

初期残差(Initial Residual): $\alpha \in (0, 1)$ のパラメータで、各層に入力時の特徴量 $\bm{H}^{(0)}$ を直接加算します。これにより各ノードは「自分は元々どんな特徴量を持っていたか」という固有の情報を常に参照できます。 $\alpha = 0$ なら通常のGCN、$\alpha = 1$ なら純粋な恒等写像です。

恒等写像(Identity Mapping): $\beta$ は層ごとのパラメータで、重み行列 $\bm{W}^{(\ell)}$ を単位行列からの偏差として学習します。$(1-\beta)\bm{I} + \beta\bm{W}^{(\ell)}$ という形により、$\beta$ が小さいとほぼ恒等写像になり、層が深くなるほど小さな更新だけを学べばよい状況を作ります。

この2つの工夫の組み合わせにより、GCNIIは64層という深いアーキテクチャでも過平滑化を抑制できることが実証されています。

APPNPも同様の発想で、まず最終層だけで特徴変換を行い、その後で集約(パーソナライズドPageRank)を実行します。

$$ \bm{H}^{(0)} = \mathrm{MLP}(\bm{X}), \quad \bm{H}^{(\ell+1)} = (1-\alpha)\hat{\bm{A}}\bm{H}^{(\ell)} + \alpha\bm{H}^{(0)} $$

集約と変換を分離することで、「初期特徴量から遠ざかりすぎない」という制約を学習と独立に入れられます。

対策2: PairNorm

PairNorm(2020年)は、ディリクレエネルギーが指数減衰する問題を直接ターゲットにした正規化手法です。考え方はシンプルです—「集約のたびに隣接ノード間の差が縮まるなら、その差を毎層人工的に引き延ばせばよい」という発想です。

具体的な操作は2ステップです。

まずセンタリング(平均ゼロ化)を行います。

$$ \tilde{\mathbf{h}}_v = \mathbf{h}_v – \frac{1}{n}\sum_{u=1}^{n}\mathbf{h}_u $$

全ノードの埋め込みの平均をゼロにすることで、全体の定数シフトを除去します。

次にスケーリングを行います。

$$ \hat{\mathbf{h}}_v = s_c \cdot \frac{\tilde{\mathbf{h}}_v}{\sqrt{\frac{1}{n}\sum_{u}\|\tilde{\mathbf{h}}_u\|^2}} $$

分母は全ノード埋め込みのRMS(二乗平均平方根)ノルムです。$s_c$ は超パラメータで、典型的には $s_c = 1$ とします。

この操作により、毎層後のノード埋め込みは「平均ゼロ・スケール一定」が保証されます。過平滑化でノード表現が均一化しようとしても、PairNormが常に一定の分散を維持するため、エネルギーが完全にゼロに落ちることを防ぎます。

PairNormの利点はモデルアーキテクチャを変更せず、集約の後に挿入するだけでよい点です。GCN、GAT、GraphSAGEなどあらゆるGNNに適用できます。

ただし注意点もあります。PairNormは「スケールを保つ」だけで「情報を保つ」わけではありません。均一化がゆっくりになるという意味では有効ですが、初期特徴量の個別性(どのノードがどのクラスか)を保存する機構ではありません。

対策3: DropEdge

DropEdge(2020年)はDropoutをエッジに適用するというシンプルなアイデアです。訓練の各エポック(ミニバッチ)で、グラフのエッジをランダムに一部除去してからメッセージパッシングを行います。

DropEdge:訓練時にエッジをランダム除去して過平滑化を抑制

左図(元グラフ、全エッジ使用)と右図(DropEdge後)を比べると、灰色の破線で示されたエッジが除去されていることがわかります。このとき注目すべきは2点です。第一に、一部の近傍が除去されることで「集約しすぎる」ことが防がれます。第二に、毎エポックで異なるグラフ構造を使うため、アンサンブル効果も得られます。

DropEdgeが過平滑化に効く理由を数学的に考えましょう。エッジを割合 $p$ でランダム削除すると、実効的な正規化隣接行列は:

$$ \hat{\bm{A}}_{\text{drop}} = \frac{1}{1-p}\bm{M} \odot \hat{\bm{A}} $$

ここで $\bm{M}$ はベルヌーイ分布で生成したランダムマスク(0または1の行列)、$\odot$ はアダマール積です。$\frac{1}{1-p}$ はスケールを補正するためのファクタです。

エッジを削除すると、各ノードの実効的な近傍が減ります。これにより隣接ノードとの差が維持されやすくなります。理論的には、DropEdgeで生成された疎なグラフの正規化隣接行列の最大固有値が元のグラフより小さくなる(= エネルギー減衰が遅くなる)ことが期待されます。

実装も非常に簡単です。

import numpy as np

def drop_edge(A, drop_prob=0.3):
    """エッジを確率 drop_prob でランダム除去する。"""
    n = A.shape[0]
    mask = (np.random.rand(n, n) > drop_prob).astype(float)
    mask = np.maximum(mask, mask.T)   # 無向グラフ対称性を保つ
    mask = np.maximum(mask, np.eye(n))  # 自己ループは保持
    A_dropped = A * mask
    # 正規化
    D_inv_sqrt = np.diag(1.0 / np.sqrt(A_dropped.sum(axis=1) + 1e-9))
    return D_inv_sqrt @ A_dropped @ D_inv_sqrt

テスト時はすべてのエッジを使うため、DropEdgeは訓練と推論で挙動が変わります。この点はDropoutと同じです。

対策4: Jumping Knowledge Network

Jumping Knowledge Network(JK-Net)(2018年)は「各層の出力をすべて集めて最終予測に使う」という発想です。最終層だけの表現を使う代わりに、全層の出力を結合(concatenate、max pooling、LSTMなど)して予測します。

$$ \mathbf{h}_v^{\text{final}} = \mathrm{AGGREGATE}\!\left(\mathbf{h}_v^{(1)}, \mathbf{h}_v^{(2)}, \ldots, \mathbf{h}_v^{(L)}\right) $$

「Jumping」という名前は、中間層の情報が最終予測に「ジャンプ」してくることに由来します。

この手法の直感はシンプルです。層が深くなるにつれてノードの「局所的な」情報が失われます。しかし浅い層の出力には、その情報がまだ残っています。JK-Netはその浅い層の情報を捨てずに保存しておき、最終予測のときに使えるようにします。

具体的には次の3つの集約方法が提案されています。

  • Concatenation(連結): 全層の出力を単純に連結する。表現次元は $d \times L$ になる。
  • Max Pooling: 各次元ごとに全層にわたる最大値を取る。次元数は $d$ のまま。
  • LSTM Attention: 双方向LSTMで各層の重みを学習する。浅い層か深い層かをノードごとに適応的に決定。

JK-Netの特徴は、「何層が最適か」というハイパーパラメータ調整が不要になる点です。データによって最適な層数は異なりますが、全層の情報を保存しておけばモデルが自分で必要な深さを選べます。

各対策手法のディリクレエネルギー減衰比較

4つの手法を比較した図では、標準GCN(赤)が最も速くエネルギーが落ちています。DropEdge(橙)は少し緩やかで、残差接続/GCNII(青)はさらに緩やかです。PairNorm(緑)はほぼ一定を保っています。対策なしGCNは5〜6層で実用的な閾値(グレー破線)を下回りますが、対策ありではその閾値を超えた深さまで利用可能です。

4つの対策を整理すると、それぞれ過平滑化への「攻め方」が異なります。次のセクションでは実装の視点から見て何が違うかをまとめます。

対策の比較と使い分け

4つの対策は「どうエネルギーを保つか」という観点で整理できます。

手法 アイデア 強み 注意点
GCNII 初期特徴量 $\bm{H}^{(0)}$ を毎層参照 個別性を数学的に保証 初期特徴量の質に依存
APPNP 集約と変換を分離 シンプルで安定 局所近傍のみ反映
PairNorm 毎層のスケールを強制維持 既存モデルに差し込むだけ スケールのみで情報は未保証
DropEdge エッジをランダム削除 正則化効果も同時に得られる 推論時のエッジ数が変わる
JK-Net 全層の出力を集約 最適層数を学習で決定 パラメータ数・計算量が増加

実務での選択指針を述べると次のようになります。

分子グラフや化学インフォマティクスでは、長距離依存関係を捉えるために深いGNNが必要です。GCNIIとAPPNPが実績豊富です。

大規模グラフ(SNS、知識グラフ)では計算効率が重要です。DropEdgeはエッジ削除で計算量が下がる副次効果もあるため有用です。

既存のGNNパイプラインに追加したい場合は、PairNormが最もシンプルで導入コストが低いです。

最適層数が不明な場合は、JK-Netのmax poolingが堅牢な選択肢です。どの層も情報として残るため、浅くしすぎ・深くしすぎのリスクが減ります。

まとめ

本記事では、GNNの過平滑化問題を数学的な根拠から説明し、4つの対策を紹介しました。

  • メッセージパッシング = ラプラシアン平滑化: GCNの集約操作は低域通過フィルタと等価であり、高周波成分(クラス間の差異)を層ごとに減衰させる
  • ディリクレエネルギーの指数減衰: 隣接ノード間の埋め込み差の総量は、層数に対して $\mu_{\max}^{2L}$ 倍で指数的に減衰することが証明できる
  • 定常分布への収束: 無限回集約すると、全ノード表現は次数比例の一定ベクトルへ収束し、クラス情報が失われる
  • 実測で確認: 空手クラブグラフで2〜3層ピーク(精度0.9444)→6層で0.7778→10層で0.6111という劣化を実証
  • 4つの対策: 残差接続(GCNII/APPNP)・PairNorm・DropEdge・JK-Netが状況に応じた対策手法として有効

次のステップとして、グラフ構造の理解をさらに深めるには以下の記事も参考にしてください。

GNN・メッセージパッシングの基礎
GNNの基本フレームワーク、メッセージパッシングの仕組みとGCN・GraphSAGE・GINとの関係を解説します。
グラフラプラシアンの定義と性質
グラフラプラシアン行列の定義、固有値分解、スペクトルグラフ理論の基礎を数式で解説します。