埋め込みの次元を増やす・結合するとは何をしているのか — 次元拡張の意図とメリット・落とし穴

100人を10畳の部屋に詰め込むと、誰もが隣の人とぶつかります。同じ100人を、体育館くらいの広さに散らばせれば、ほとんどの人は誰にもぶつからずに立っていられます。深層学習の埋め込み(ベクトル表現)でも、まったく同じことが起きています。特徴やデータを表すベクトルの「置き場所」を広くすればするほど、無関係な特徴同士が偶然重なってしまう確率は下がるのです。

しかし「次元を増やす」という設計判断は、実はひとつの理由に集約できるものではありません。深層学習のアーキテクチャを見渡すと、次元を増やす場面は大きく3つの異なる意図に分かれます。

  1. 埋め込み自体を高次元にする——単語埋め込みを100次元でなく300次元にする、画像埋め込みを512次元でなく2048次元にする、といった判断
  2. 拡張してから縮小する——Transformerの全結合層(FFN)が $d_{model}$ を4倍に広げてから元に戻す、CNNが層を経るごとにチャネル数を増やす、といった設計
  3. 複数の埋め込みを結合する——テキストと画像、トレンドとボラティリティのように異なる視点の埋め込みを連結して、より大きな次元のベクトルにする設計

次元拡張の3つのパターン概観

この記事では、この3つのパターンをそれぞれ直感・数式・実装で解き明かします。特に3つ目については、実際に検証する中で見つかった「単純に結合すると、片方の情報が犠牲になる」という落とし穴と、その対処法までを実測データで示します。

3つとも「次元を増やす」という表面上の操作は共通していますが、①は静的な「置き場所」の広さの話、②は計算の途中経過で使う「作業スペース」の広さの話、③は複数の情報源を「潰さずに残す」ための広さの話です。同じ「次元を増やす」でも、何を目的にしているかによって設計上の判断基準がまったく異なります。順番に見ていきましょう。

この記事の内容

  • パターン①:ランダムな高次元ベクトルが「ほぼ直交」する現象と、その意味
  • パターン②:Coverの定理を実演する——隠れ層を広げると非線形分離が安定する
  • パターン③:複数の埋め込みを結合する意図と、等ウェイト結合の落とし穴・解消法
  • 3つのパターンのまとめ

前提知識

カーネル法とカーネルトリック
『高次元に飛ばせば線形分離できる』という発想の理論的な土台です。
画像なし
Superposition(重ね合わせ)と特徴の多義性
逆に次元が『足りない』とき、ニューラルネットが特徴をどう詰め込むかを扱った記事です。

1. パターン① — 埋め込み自体を高次元にする

1.1 ランダムなベクトルは高次元ほど「ほぼ直交」する

埋め込みベクトルの次元を増やすと、なぜ「特徴がぶつからなくなる」のでしょうか。これを最も直接的に示すのが、ランダムな高次元ベクトル同士はほぼ直交するという性質です。

$d$ 次元空間からランダムに2つの単位ベクトル $\bm{u}, \bm{v}$ を取ったとき、そのコサイン類似度 $\bm{u}\cdot\bm{v}$ は平均0、標準偏差はおよそ $1/\sqrt{d}$ になります。もう少し丁寧に見てみましょう。$\bm{u}, \bm{v}$ の各成分がおおよそ独立で平均0・分散 $1/d$(単位ベクトルなので $\sum_i u_i^2 \approx 1$ となるようにスケールされている)とみなせるなら、

$$ \begin{equation} \mathrm{Var}[\bm{u}\cdot\bm{v}] = \mathrm{Var}\left[\sum_{i=1}^d u_i v_i\right] = \sum_{i=1}^d \mathrm{Var}[u_i v_i] \approx d \times \frac{1}{d}\times\frac{1}{d} = \frac{1}{d} \end{equation} $$

各項 $u_i v_i$ は独立で期待値0($u_i,v_i$ の符号がランダムなため)なので、和全体の分散は各項の分散の単純な合計になり(共分散項が0に消える)、次元 $d$ に反比例します。したがって標準偏差は $1/\sqrt{d}$ のオーダーで縮んでいくわけです。これは「測度の集中」と呼ばれる現象の一例で、高次元空間の幾何学に共通する性質です。

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

for d in [2, 8, 32, 128, 512, 2048]:
    n = 3000
    a = rng.normal(size=(n, d)); a /= np.linalg.norm(a, axis=1, keepdims=True)
    b = rng.normal(size=(n, d)); b /= np.linalg.norm(b, axis=1, keepdims=True)
    cos = (a * b).sum(1)
    print(f"d={d:5d}  mean={cos.mean():.4f}  std={cos.std():.4f}  理論std~1/sqrt(d)={1/np.sqrt(d):.4f}")
d=    2  mean=0.0072  std=0.7066  理論std~1/sqrt(d)=0.7071
d=    8  mean=-0.0114  std=0.3581  理論std~1/sqrt(d)=0.3536
d=   32  mean=0.0000  std=0.1790  理論std~1/sqrt(d)=0.1768
d=  128  mean=0.0009  std=0.0873  理論std~1/sqrt(d)=0.0884
d=  512  mean=0.0001  std=0.0444  理論std~1/sqrt(d)=0.0442
d= 2048  mean=-0.0003  std=0.0220  理論std~1/sqrt(d)=0.0221

次元が上がるほどランダムなベクトルはほぼ直交する

実測値は理論値 $1/\sqrt{d}$ とほぼ完全に一致しています。$d=2$ ではコサイン類似度が $-1$ か $+1$ の近くに偏る(平面上でランダムな2方向はしばしば大きく重なる)のに対し、$d=2048$ では類似度はほぼ0に集中し、ヒストグラムの山がきわめて狭くなっています。

この性質が意味するのは、低次元では無関係な特徴同士が偶然大きな内積を持ってしまいやすいが、高次元ではその心配がほとんどなくなるということです。単語埋め込みや画像埋め込みで次元を増やすメリットの本質はここにあります。関係のない概念(例えば「リンゴ」と「民主主義」)を表すベクトルが、次元が低いと(ランダムに配置しただけでも)ある程度似た方向を向いてしまい、モデルが混同するリスクが上がります。次元を増やせば、無関係な概念同士は自然と「ぶつからない」場所に収まりやすくなるのです。

実際のモデルの埋め込み次元を見ても、この傾向は一貫しています。word2vecの単語埋め込みは100〜300次元程度でしたが、BERT-baseは768次元、BERT-largeは1024次元、CLIPの画像・テキスト埋め込みは512〜768次元、GPT-3の最大モデルに至っては12,288次元まで使われています。もちろん次元数が大きいほど計算コストやメモリも増えるため無制限に大きくできるわけではありませんが、モデルが表現しなければならない「概念」の種類が増えるにつれて、埋め込み次元も大きくする必要がある、という関係がここに表れています。

1.2 特徴が次元より多いとどうなるか

逆に、埋め込みの次元が「詰め込みたい特徴の数」より少ないとどうなるでしょうか。この状況は Superposition(重ね合わせ) と呼ばれ、ニューラルネットは互いに(ほぼ)直交する方向を確保できない場合、複数の特徴を干渉を許しながら同じ次元に重ねて格納することが知られています。

画像なし
Superposition(重ね合わせ)と特徴の多義性
次元が足りないとき、ニューラルネットが特徴をどう『重ねて』格納するかを実測した記事です。

つまり、次元を増やすことと重ね合わせは表裏一体です。次元が十分にあれば特徴は「素直に」直交した方向に収まり、次元が足りなければ「重ね合わせ」という形で無理やり詰め込まれる——このトレードオフを理解しておくと、埋め込み次元をどれくらい確保すべきかの勘所がつかめます。


2. パターン② — 拡張してから縮小する

2.1 Coverの定理を「学習された」写像で使う

パターン①は「ランダムな高次元空間に置く」という話でしたが、深層学習でもっと頻繁に使われるのは、学習可能な非線形写像で一時的に高次元へ持ち上げてから、また元の次元に戻すという設計です。この発想の理論的な土台は、冒頭で紹介したカーネル法の記事で扱った「非線形写像で高次元に飛ばせば線形分離しやすくなる」というCoverの定理の直感と同じです。カーネル法は写像を陽に計算しない(カーネルトリックで内積だけ扱う)のに対し、ここで見るのはニューラルネットが写像そのものを学習するケースです。

具体例で見てみましょう。三日月が2つ組み合わさった “two moons” という、直線では分離できない2値分類データを使います。

import torch, torch.nn as nn
from sklearn.datasets import make_moons

X, y = make_moons(n_samples=500, noise=0.15, random_state=0)
Xt = torch.tensor(X, dtype=torch.float32); yt = torch.tensor(y, dtype=torch.float32)

def train_moons(hidden, epochs=800, seed=0, lr=0.01):
    torch.manual_seed(seed)
    model = nn.Sequential(nn.Linear(2, hidden), nn.ReLU(), nn.Linear(hidden, 1))
    opt = torch.optim.Adam(model.parameters(), lr=lr)
    lossfn = nn.BCEWithLogitsLoss()
    for _ in range(epochs):
        opt.zero_grad()
        out = model(Xt).squeeze(1)
        loss = lossfn(out, yt)
        loss.backward(); opt.step()
    with torch.no_grad():
        pred = (torch.sigmoid(model(Xt).squeeze(1)) > 0.5).float()
        acc = (pred == yt).float().mean().item()
    return acc

入力は2次元、出力は1次元(2クラス分類)のまま、間の隠れ層の幅だけを変えて精度を比較します。

import numpy as np
for hidden in [1, 2, 4, 8, 16, 32, 64, 128]:
    accs = [train_moons(hidden, seed=s) for s in range(8)]
    print(f"hidden={hidden:4d}  acc mean={np.mean(accs):.3f}  std={np.std(accs):.3f}")
hidden=   1  acc mean=0.779  std=0.161
hidden=   2  acc mean=0.825  std=0.123
hidden=   4  acc mean=0.907  std=0.048
hidden=   8  acc mean=0.937  std=0.055
hidden=  16  acc mean=0.997  std=0.002
hidden=  32  acc mean=0.998  std=0.000
hidden=  64  acc mean=0.998  std=0.000
hidden= 128  acc mean=0.998  std=0.000

隠れ層の幅による決定境界の違い

隠れ層が2次元のときは、ある乱数シードでは境界がほとんど直線的にしかならず(精度0.5、まったく分離できていない失敗例)、隠れ層を64次元に広げると滑らかで安定した三日月型の境界が学習されます。これはまさにCoverの定理の実演です。元の2次元空間では線形分離できない問題も、非線形なReLU写像で一時的に高次元(隠れ層)へ持ち上げれば、最後の1層は単なる線形分類器で済むのです。

隠れ層幅と精度・安定性

さらに注目すべきは、隠れ層を広げると精度が上がるだけでなく、8個の乱数シードにわたる標準偏差もどんどん小さくなることです。隠れ層が1〜2次元のときは「たまたま上手くいく初期値」と「まったく学習できない初期値」の差が激しく(std=0.16程度)、隠れ層が16次元を超えるとほぼ全ての初期値で安定して高精度に達します(std≈0)。これは、ネットワークを広くするほど損失地形の「悪い局所解」に阻まれるリスクが下がるという、現代の深層学習理論(Neural Tangent Kernelなど)とも符合する挙動です。幅を広げることは、精度だけでなく学習の再現性・頑健性も向上させるという点は見落とされがちですが重要な効果です。

2.2 「広い作業台」を確保してから戻す — Transformer FFNとCNN

この「一時的に広げる」という考え方は、Transformerの全結合層(Feed-Forward Network, FFN)ブロックや、CNNのチャネル設計に、そのままの形で現れています。

Transformer FFNとCNNチャネルにおける拡張パターン

Transformerの各層にあるFFNブロックは、通常 $d_{model} \to 4 d_{model} \to d_{model}$ という形をしています。例えば $d_{model}=512$ なら、中間層は2048次元まで一時的に拡張されます。なぜ4倍にしてまた戻すのでしょうか。理由は2つの層の役割分担にあります。

  • 中間の広い層($4d_{model}$):非線形活性化関数(ReLUやGELU)を使って、豊かな非線形合成を行う「作業台」。ここが広いほど、複雑な関数を表現する余地が増えます(2.1節で見たCoverの定理そのものです)。
  • 最後に $d_{model}$ に戻す層:Transformerの各層は残差接続(residual connection)で結ばれており、層をまたいで情報が流れる「通信路」の次元は固定されている必要があります。だからこそ、内部でどれだけ広げても、外に出るときは元の次元に圧縮して戻すのです。

なお「4倍」という比率自体は絶対的なものではありません。オリジナルのTransformer論文は $d_{model}=512$ に対し中間層を2048(4倍)としていますが、LLaMAなどSwiGLU系の活性化関数を使うモデルでは、ゲート機構の分だけパラメータ数の帳尻を合わせるために $8/3$ 倍程度に調整されることもあります。重要なのは倍率そのものではなく、「入出力のインターフェース次元とは別に、計算途中だけ広げる領域を用意する」という設計原理が共通しているという点です。

CNN(特にResNet系)でも似た設計思想が見られます。層を経るごとに空間解像度(画像の縦横サイズ)を落としながら、チャネル数(特徴の種類)を増やしていきます。空間的な広がりという形の「容量」を、チャネル方向の「容量」に変換していくようなイメージです。

「広い作業台で計算してから、決まった大きさの通信路に戻す」——これがパターン②の共通する設計原理です。パラメータ数や計算量は中間層の広さで増えますが、モデル全体のインターフェース(層と層のつなぎ目の次元)は変えずに済むという利点があります。


3. パターン③ — 複数の埋め込みを結合する

3.1 なぜ結合するのか

3つ目のパターンは、異なる視点から得られた複数の埋め込みを、無理に1つの共有表現に混ぜ込まず、それぞれ独立に学習してから連結するという設計です。

複数埋め込みの結合という考え方

例えば、金融の時系列データを検索するタスクを考えます。ある時系列の「トレンド(右肩上がりか下がりか)」と「ボラティリティ(値動きの荒さ)」は、どちらも重要な性質ですが、性質としてはかなり異なります。これらを無理やり1つの小さな埋め込み空間に押し込めると、片方の情報を表現するために使った「方向」が、もう片方の情報を壊してしまうことがあります。そこで、トレンド用のエンコーダとボラティリティ用のエンコーダを別々に学習し、それぞれの出力を連結して1つの、より高次元な埋め込みにするのです。

画像なし
自然言語とスケッチで株価を検索する:CLIP流対照学習とツインオートエンコーダによる金融時系列検索
トレンド埋め込みとボラティリティ埋め込みを連結するツインオートエンコーダの実例です。

同じ発想は、テキストと画像を組み合わせるマルチモーダル学習、複数のセンサ系統を組み合わせるマルチモーダル異常検知など、あらゆる場面に現れます。次元を増やしてでも、複数の視点の情報を「競合させず併存させる」というのがこのパターンの意図です。

3.2 落とし穴 — 等ウェイト結合は片方のブランチを犠牲にする

しかし、単純に埋め込みを連結するだけでは、思わぬ落とし穴があります。トレンド用埋め込み $\bm{e}_t$ とボラティリティ用埋め込み $\bm{e}_v$(どちらも単位ベクトルに正規化済み)を素直に連結し、全体をまた正規化する状況を考えます。

$$ \begin{equation} \bm{e} = \mathrm{normalize}([\bm{e}_t;\, \bm{e}_v]) \end{equation} $$

2つの連結・正規化済みベクトル $\bm{e} = [\bm{e}_t; \bm{e}_v]$ と $\bm{e}’ = [\bm{e}_t’; \bm{e}_v’]$ のコサイン類似度は、次のように各ブロックのコサイン類似度の平均になります(各ブロックが単位ノルムなので、連結後の全体ノルムは $\sqrt{2}$ で共通)。

$$ \begin{equation} \bm{e}\cdot\bm{e}’ = \bm{e}_t\cdot\bm{e}_t’ + \bm{e}_v\cdot\bm{e}_v’, \qquad \cos(\bm{e},\bm{e}’) = \frac{\bm{e}_t\cdot\bm{e}_t’ + \bm{e}_v\cdot\bm{e}_v’}{2} \end{equation} $$

この式が意味するのは、「トレンド」ブロックと「ボラティリティ」ブロックが、それぞれのクラス間で類似度がどれくらい鋭くばらつくかによって、結合後の最近傍検索の勝敗が決まってしまうということです。もしボラティリティのクラス間差(低ボラ vs 高ボラ、振幅が数倍違う)がトレンドのクラス間差(ノイズに埋もれがちな緩やかな傾き)よりずっとシャープなら、等ウェイトで連結しても、ボラティリティ側がほぼ一方的に最近傍検索の結果を決めてしまいます

実際に検証してみます。トレンド(上昇/下降)とボラティリティ(低/高)の2×2、計4クラスの合成時系列データを作り、価格系列用・ボラティリティ系列用の2本のオートエンコーダ(前掲の金融時系列検索の記事と同じ構造)で埋め込みを学習します。

import numpy as np, torch, torch.nn as nn

def gen_series(L=60, r_bar=50.0, kappa=0.05, sigma=1.0, trend=0.0,
                p_shock=0.0, sigma_shock=8.0, rng=None):
    r = np.zeros(L); r[0] = r_bar
    for t in range(1, L):
        u = rng.normal(0, sigma)
        shock = rng.normal(0, sigma_shock) if rng.random() < p_shock else 0.0
        r[t] = max(0.0, kappa * r_bar + (1 - kappa) * r[t - 1] + u + trend + shock)
    return r

def vol_ts(x, m=4):
    L = len(x); v = np.zeros(L)
    for i in range(L):
        lo, hi = max(0, i - m), min(L, i + m + 1)
        v[i] = x[lo:hi].std()
    return v

torch.manual_seed(0); rng = np.random.default_rng(0)
L = 60
configs = [("up_low", dict(sigma=0.6, trend=0.5)), ("down_low", dict(sigma=0.6, trend=-0.5)),
           ("up_high", dict(sigma=2.4, trend=0.5)), ("down_high", dict(sigma=2.4, trend=-0.5))]
N_per = 200
X, V, Y = [], [], []
for label, (name, kw) in enumerate(configs):
    for _ in range(N_per):
        s = gen_series(L=L, rng=rng, **kw)
        X.append(s); V.append(vol_ts(s)); Y.append(label)
X, V, Y = np.array(X), np.array(V), np.array(Y)

2本のオートエンコーダ(60→512→256→16)を学習し、埋め込みを取り出します。

def minmax(A):
    lo, hi = A.min(), A.max(); return (A - lo) / (hi - lo + 1e-8)
Xn, Vn = minmax(X), minmax(V)
idx = rng.permutation(len(Xn)); n_tr = int(0.8 * len(idx)); tr, te = idx[:n_tr], idx[n_tr:]
Xtr = torch.tensor(Xn[tr], dtype=torch.float32); Xte = torch.tensor(Xn[te], dtype=torch.float32)
Vtr = torch.tensor(Vn[tr], dtype=torch.float32); Vte = torch.tensor(Vn[te], dtype=torch.float32)
Ytr, Yte = Y[tr], Y[te]

class AE(nn.Module):
    def __init__(self, L=60, h=(512, 256, 16)):
        super().__init__()
        self.enc = nn.Sequential(nn.Linear(L, h[0]), nn.ReLU(), nn.Linear(h[0], h[1]), nn.ReLU(), nn.Linear(h[1], h[2]))
        self.dec = nn.Sequential(nn.Linear(h[2], h[1]), nn.ReLU(), nn.Linear(h[1], h[0]), nn.ReLU(), nn.Linear(h[0], L))
    def forward(self, x):
        z = self.enc(x); return z, self.dec(z)

def train_ae(model, data, epochs=300, lr=1e-3):
    opt = torch.optim.Adam(model.parameters(), lr=lr)
    for _ in range(epochs):
        opt.zero_grad(); z, xr = model(data); loss = ((xr - data) ** 2).mean(); loss.backward(); opt.step()
    return loss.item()

E_t, E_v = AE(L), AE(L)
train_ae(E_t, Xtr); train_ae(E_v, Vtr)

with torch.no_grad():
    zt_tr, _ = E_t(Xtr); zt_te, _ = E_t(Xte)
    zv_tr, _ = E_v(Vtr); zv_te, _ = E_v(Vte)

def l2norm(z): return z / (z.norm(dim=1, keepdim=True) + 1e-8)
et_tr, et_te = l2norm(zt_tr), l2norm(zt_te)
ev_tr, ev_te = l2norm(zv_tr), l2norm(zv_te)

トレンド枝の重み $w$ を変えながら連結し($w=1$ が単純な等ウェイト連結)、最近傍検索でトレンド/ボラティリティのラベルがそれぞれどれくらい一致するかを調べます。

def split_labels(Yarr):
    trend = np.where(np.isin(Yarr, [0, 2]), 1, 0)
    vol = np.where(np.isin(Yarr, [0, 1]), 0, 1)
    return trend, vol
trend_te, vol_te = split_labels(Yte); trend_tr, vol_tr = split_labels(Ytr)

def nn_match(emb_te, emb_tr, lab_te, lab_tr):
    sims = emb_te @ emb_tr.T
    idx2 = sims.argmax(dim=1).numpy()
    return (lab_tr[idx2] == lab_te).mean()

for w in [0.25, 0.5, 1.0, 2.0, 4.0, 8.0, 12.0, 16.0, 24.0, 32.0]:
    comb_tr = l2norm(torch.cat([w * et_tr, ev_tr], dim=1))
    comb_te = l2norm(torch.cat([w * et_te, ev_te], dim=1))
    tm = nn_match(comb_te, comb_tr, trend_te, trend_tr)
    vm = nn_match(comb_te, comb_tr, vol_te, vol_tr)
    print(f"w={w:5.2f}  trend一致={tm:.3f}  vol一致={vm:.3f}")
w= 0.25  trend一致=0.475  vol一致=0.956
w= 0.50  trend一致=0.475  vol一致=0.956
w= 1.00  trend一致=0.625  vol一致=0.963
w= 2.00  trend一致=0.800  vol一致=0.969
w= 4.00  trend一致=0.900  vol一致=0.975
w= 8.00  trend一致=0.956  vol一致=0.963
w=12.00  trend一致=0.963  vol一致=0.963
w=16.00  trend一致=0.969  vol一致=0.956
w=24.00  trend一致=0.969  vol一致=0.919
w=32.00  trend一致=0.969  vol一致=0.900

重み付き結合による支配ブランチ問題の解消

$w=1$(等ウェイト結合)では、トレンド一致率がわずか0.625しかありません。トレンド埋め込み単体なら0.98前後まで出るクラス分離能力を持っているにもかかわらず、ボラティリティ枝と等ウェイトで結合しただけで、トレンド情報がほとんど埋もれてしまっているのです。しかしトレンド枝の重みを大きくしていくと、トレンド一致率は着実に回復し、$w=8\sim16$ 付近で両方の一致率が0.96前後という「釣り合いの取れた」状態に到達します。$w$ をさらに大きくすると、今度はボラティリティ側が犠牲になり始め、トレードオフが反転します。

この結果が教えてくれるのは、「次元を増やして情報を併存させる」という設計は正しくても、各ブランチの寄与度を無自覚に等しいと仮定してはいけないという実務上の教訓です。単純な等ウェイト連結は「中立」に見えて、実際には片方の枝に支配された結合になっていることがある、というのがこの実験の核心です。

対処法は今回試した「固定の重み $w$ を手で調整する」方法だけではありません。実務でよく使われる選択肢を整理すると次のようになります。

  • 学習可能なスケールパラメータ:各ブランチの埋め込みに、データから最適な値を学習するスケール(今回の $w$ に相当)を持たせ、手動チューニングではなく損失関数を通じて自動で調整させる。
  • 類似度分布の事前標準化:連結する前に、各ブランチの「クラス内・クラス間の類似度の典型的な広がり」を測定し、平均・分散を揃えてから連結する。統計学における特徴量のスケーリング(標準化)と同じ発想です。
  • ゲーティングやアテンションによる動的な重み付け:Mixture-of-ExpertsやGated Multimodal Unitのように、入力ごとに「どのブランチをどれだけ信頼するか」をネットワーク自身に学習させる。固定の重みでは対応しきれない、サンプルごとの事情の違いに対応できます。

どの方法を選ぶにせよ、出発点は同じです。複数の埋め込みを連結するときは、「本当に等ウェイトで良いのか」を一度疑ってみる——これが、次元拡張による情報の併存を狙い通りに機能させるための第一歩です。


4. まとめ

深層学習・埋め込み設計における「次元を増やす」という判断を、3つの異なるパターンに整理しました。

パターン 何をしているか 主な例 意図
① 埋め込み自体を高次元にする ベクトルの置き場所を広げる 単語・画像埋め込みの次元数 無関係な特徴が偶然重ならないようにする(ランダムな高次元ベクトルはほぼ直交)
② 拡張してから縮小する 一時的に広い空間で非線形合成し、元の次元に戻す Transformer FFNの4倍拡張、CNNのチャネル増加 学習された非線形写像でCoverの定理を活かしつつ、層間インターフェースは固定する
③ 複数の埋め込みを結合する 異なる視点の埋め込みを連結し、より高次元な表現にする マルチモーダル学習、トレンド+ボラティリティ融合 情報を競合させず併存させる。ただし等ウェイト結合は片方の枝に支配されるリスクがある

3つとも「次元を増やす」という表面上は同じ操作に見えますが、①は表現の「置き場所」を広げる話、②は計算途中の「作業台」を広げる話、③は複数の情報源を「潰さずに残す」話——それぞれ異なる問題に対する異なる解決策です。次に埋め込みの次元数やアーキテクチャの設計に迷ったときは、「自分が今解決したいのはこの3つのうちどれか」を考えると、判断の軸が見えてきます。

次元を増やすことは万能薬ではなく、計算コストやメモリ、過学習のリスクとのトレードオフを常に伴います。しかし、なぜ次元を増やすのかという「意図」を3つのパターンに分けて理解しておけば、どこにどれだけ次元を割くべきかという設計判断に、根拠を持って臨めるようになるはずです。

主な参考文献

  • T. M. Cover, “Geometrical and Statistical Properties of Systems of Linear Inequalities with Applications in Pattern Recognition,” IEEE Transactions on Electronic Computers, 1965.
  • A. Vaswani et al., “Attention Is All You Need,” NeurIPS 2017.
  • K. He, X. Zhang, S. Ren, J. Sun, “Deep Residual Learning for Image Recognition,” arXiv:1512.03385, 2015.
  • A. Jacot, F. Gabriel, C. Hongler, “Neural Tangent Kernel: Convergence and Generalization in Neural Networks,” NeurIPS 2018.