第3章

ニューラルネットの基礎

ニューロン1個の動作から始めて、活性化関数、全結合層、なぜ層を重ねるか、をインタラクティブに学びます。 スライダーを動かしながら読み進めてください。

この章の全体像 — ボトムアップで組み立てる

ニューラルネットワークは、たった3つの構成要素を 順に積み上げて できています。 まず全体像を把握してから、各セクションで詳しく見ていきましょう。

1

ニューロン1個

入力に 重みを掛けて足し活性化関数を通すだけの、1個のスカラー値を出す関数

σ

$y = \sigma(w_1 x_1 + w_2 x_2 + w_3 x_3 + b)$

↓ 並列に並べる
2

全結合層(1層)

ニューロンを 横に並べて並列化。全員が同じ入力を見る。ベクトル → ベクトルの変換になる。

$\mathbf{y} = \sigma(W \mathbf{x} + \mathbf{b})$

↓ 直列に重ねる
3

多層(MLP / Deep NN)

全結合層を 縦に積み重ねる。間に必ず活性化関数を挟むことで、複雑な関数を表現できるようになる。

$\mathbf{h_1} = \sigma(W_1 \mathbf{x} + \mathbf{b_1})$, $\mathbf{h_2} = \sigma(W_2 \mathbf{h_1} + \mathbf{b_2})$, ...

💡 核心: ニューラルネットは複雑そうに見えて、実態はこの3要素の組み合わせだけ。 ChatGPT も画像認識AIも、基本構造はこの「ニューロン → 全結合層 → 多層」の延長線にあります。 それぞれを順に詳しく見ていきましょう。

1. ニューロン1個

ニューラルネットの最小単位は ニューロン(unit)。 1個のニューロンがやることは、入力に重みを掛けて足して、活性化関数を通すだけ。

数式で書くと:

$$y = \sigma(w_1 x_1 + w_2 x_2 + w_3 x_3 + b)$$
インタラクティブ・デモ
ニューロン1個を動かしてみる

下のスライダーで入力 $x_i$、重み $w_i$、バイアス $b$ を動かすと、ニューロンの出力 $y$ がリアルタイムで変わります。

入力

x₁ 1.0
x₂ 0.5
x₃ -0.5

重みとバイアス

w₁ 0.8
w₂ -0.3
w₃ 1.2
b 0.1

活性化関数

w₁=0.8 w₂=-0.3 w₃=1.2 1.0 x₁ 0.5 x₂ -0.5 x₃ Σ σ(z) y 出力
z = (1.0 × 0.8) + (0.5 × -0.3) + (-0.5 × 1.2) + 0.1 = 0.15
y = ReLU(0.15)
y = 0.15

2. 活性化関数 — なぜ非線形が必要か

活性化関数 $\sigma$ は「線形な総和($w \cdot x + b$)にひと手間加える非線形変換」です。 なぜ必要なのか? 非線形変換がないと、層を重ねても1層分の表現力しか出ないからです。これは後で詳しく見ます。

代表的な活性化関数を順に紹介します。それぞれ「何をする関数か」「いつ使うか」「歴史的な位置づけ」を見ていきましょう。 読んだあと、下のインタラクティブグラフで形を比較すると理解が深まります。

2.1 ReLU(Rectified Linear Unit)

$$\sigma(z) = \max(0, z)$$

動作:「入力 $z$ が正ならそのまま通す、負ならゼロにする」だけ。 数学的にも実装的にも極めて単純な関数。

なぜ重要か

  1. 計算が速い:「負を0にする」だけ。掛け算も指数関数も不要
  2. 微分が簡単:$z > 0$なら微分は1、$z < 0$なら0。学習時の勾配計算が楽
  3. 勾配消失問題が起きにくい:正の領域で微分が常に1なので、深いNNでも勾配が消えない

使われる場所:現代の深層学習の事実上のデフォルト。CNN、Transformer、ほとんどの中間層で使われている。 「迷ったらReLU」が機械学習エンジニアの常識。

📚 コラム:2.2 Sigmoid(シグモイド関数)— 歴史的主役と勾配消失問題(クリックで展開)
$$\sigma(z) = \frac{1}{1 + e^{-z}}$$

動作:どんな実数を入れても、出力を 0〜1の範囲に押し込める 関数。 S字カーブ(シグモイド曲線)を描く。

  • $z = -10$ → $\sigma(z) \approx 0.00005$(ほぼ0)
  • $z = 0$ → $\sigma(z) = 0.5$(ちょうど中央)
  • $z = +10$ → $\sigma(z) \approx 0.99995$(ほぼ1)

「確率」として解釈できるのが最大の特徴。出力が0〜1に収まるので、 「猫である確率は0.87」「スパムである確率は0.03」のように使える。

歴史的位置づけ

  1. 1980〜2000年代:ニューラルネットの活性化関数の主役だった。 生物学的なニューロンが「発火するかしないか」(0か1か)を連続的に近似する関数として、自然に思えた
  2. 2010年代以降:中間層ではほぼ使われなくなった。理由は次の「勾配消失問題」
  3. 現在2値分類の出力層でのみ標準的に使われる (例:「スパムである確率」を出したいとき)

なぜ中間層では廃れたか — 勾配消失問題

Sigmoidは入力 $z$ が大きい/小さいときに 傾き(微分値)が極端に小さくなる。 例えば $z = 10$ では微分値は約 $0.00005$。

深いNNで誤差逆伝播するとき、各層で微分値を掛け合わせていきます。 Sigmoidを10層通すと、勾配が $0.00005^{10} \approx 10^{-43}$ という事実上ゼロに。 結果、奥の層の重みが学習されなくなる。これが 勾配消失問題(vanishing gradient problem)です。

ReLUは正の領域で微分値が常に1なので、何層通しても勾配が消えない。 これが2010年代の 「Sigmoid → ReLU 大移行」の理由です。

📚 コラム:2.3 tanh(ハイパボリックタンジェント)— Sigmoidの中心化版(クリックで展開)
$$\sigma(z) = \tanh(z) = \frac{e^z - e^{-z}}{e^z + e^{-z}}$$

動作:Sigmoidに似たS字カーブだが、出力範囲が -1〜+1(中心が0)。 Sigmoidの「中心化版」と理解してよい。

  • $z = -3$ → $\sigma(z) \approx -0.995$
  • $z = 0$ → $\sigma(z) = 0$(出力の中心が0)
  • $z = +3$ → $\sigma(z) \approx +0.995$

Sigmoid との違い:出力の中心が0なので、次の層への入力が偏らない。 これが学習の安定性で有利。Sigmoidよりも「少しマシ」という位置づけ。

使われる場所:RNN(リカレントNN)や LSTM の中で標準的に使われていた。 ただし勾配消失問題は Sigmoid と同様にあり、現代の深いNNではあまり使われない。

📚 コラム:2.4 ClippedReLU — NNUE(将棋AI)で標準採用される量子化対応版(クリックで展開)
$$\sigma(z) = \max(0, \min(127, z))$$

動作:ReLUに「上限」を加えた版。負はゼロ、127超は127にクリップする。

  • $z = -5$ → $\sigma(z) = 0$(ReLUと同じ)
  • $z = 50$ → $\sigma(z) = 50$(そのまま通す)
  • $z = 200$ → $\sigma(z) = 127$(上限でクリップ)

なぜこの形か:出力を整数 8bit(0〜127)の範囲に収めることで、整数演算で計算できるようになる。 CPU の SIMD 命令(AVX2 など)で大量のデータを並列処理しやすい。

使われる場所NNUE(やねうら王、水匠、Háo)で標準的に使用。 CPU上で秒間数百万回も評価関数を呼ぶ将棋AIには、整数演算による高速化が必須なので、 ReLU ではなく ClippedReLU が選ばれている。

📚 コラム:2.5 Leaky ReLU — Dying ReLU 問題への対処(クリックで展開)
$$\sigma(z) = \begin{cases} z & (z \geq 0) \\ 0.1 z & (z < 0) \end{cases}$$

動作:ReLU と似ているが、負の領域でも完全にゼロにせず、少しだけ通す(典型的には係数 0.1)。

  • $z = 3$ → $\sigma(z) = 3$(ReLUと同じ)
  • $z = -3$ → $\sigma(z) = -0.3$(ReLUなら0だが、Leakyだと少し通す)

なぜ作られたか — Dying ReLU 問題

純粋なReLUには、ニューロンが「死ぬ」現象がある。 重みが大きく更新された結果、そのニューロンの出力がずっと負になり、ReLUによって常に0を出力するようになる。 微分も0なので、もう二度と学習されない=死んだ状態

Leaky ReLU は負の領域にも傾きがあるので、勾配が完全にはゼロにならず、 ニューロンが「復活」する余地を残す。

使われる場所:GAN(生成モデル)や、ReLU で学習が安定しないときの代替として。 ただし通常のCNNなどでは、ReLU で十分なことが多く、無理に使う必要はない。

2.6 まとめ

使い分けの大方針

では、これらの関数の 形を実際に見比べてみましょう。タブで切り替えると、グラフがリアルタイムで描き直されます。

インタラクティブ・グラフ
活性化関数の形を見比べる

下のタブで活性化関数を切り替えると、グラフがリアルタイムで更新されます。

$$\sigma(z) = \max(0, z)$$

ReLU: 負の入力をすべて0にする。最も高速で、深いNNの主流。

3. 全結合層(Fully Connected Layer)— 「1層」の中身

💡 このセクションで扱うのは「1層分」。 ニューラルネットは これを複数積み重ねた もので、 1層分の構造を理解すれば、何層あっても同じ仕組みです。次の §4 多層化(MLP) で何層も積みます。

ニューロンを複数並べて、全員が同じ入力を見る構成を 全結合層と呼びます。 これがニューラルネットの「層(layer)」の正体です。

数式:

$$y = \sigma(W x + b)$$

ここで $W$ は重み行列、$b$ はバイアスベクトル。具体的に書くと:

入力 $x$ が3次元、出力 $y$ が2次元の場合:

$$\begin{pmatrix} y_1 \\ y_2 \end{pmatrix} = \sigma\left(\begin{pmatrix} w_{11} & w_{12} & w_{13} \\ w_{21} & w_{22} & w_{23} \end{pmatrix} \begin{pmatrix} x_1 \\ x_2 \\ x_3 \end{pmatrix} + \begin{pmatrix} b_1 \\ b_2 \end{pmatrix}\right)$$

つまり:

2個のニューロンが、それぞれ独自の重みで同じ入力を見ている、というだけです。

3.1 重み行列 W の見方 — 行が1ニューロンに対応

ここが 全結合層を理解する核心$W$ の各行が、1個のニューロンの重みベクトルです。 複数ニューロンの重みを 1つの行列にパッケージしているわけです。

入力3次元 → 出力4次元(ニューロン4個)の場合を見てみましょう:

入力次元 →
出力次元(ニューロン数)↓
x₁ x₂ x₃
ニューロン1 → w₁₁ w₁₂ w₁₃ ← ニューロン1の重み(1行)
ニューロン2 → w₂₁ w₂₂ w₂₃ ← ニューロン2の重み
ニューロン3 → w₃₁ w₃₂ w₃₃ ← ニューロン3の重み
ニューロン4 → w₄₁ w₄₂ w₄₃ ← ニューロン4の重み

形状: $W$ の shape = (4, 3) = (出力次元, 入力次元) = (ニューロン数, 入力次元)

📊 補足図解:3.2 行と列の意味(早見表)(クリックで展開)
意味 サイズの決まり方
行(row) 1つのニューロンの重みベクトル = 出力次元 = ニューロン数
列(column) 入力ベクトルの各成分に対応する重み = 入力次元

3.3 行列ベクトル積で複数ニューロンを一発計算

この行列構造のおかげで、4個のニューロンを別々に計算するループは不要になり、 1回の行列ベクトル積で全員を同時に処理できます:

$$y = \sigma(W \cdot x + b)$$
形状チェック:
   y      =  σ(  W      ·   x     +   b   )
  (4,)        (4, 3)      (3,)        (4,)
   ↑           ↑           ↑          ↑
  出力        重み行列     入力       バイアス
(ニューロン4個)        (3次元)    (各ニューロン1個ずつ)

プログラマ的に言えば、これは「N個のニューロンをforループで回さず、行列演算で一発処理する」という効率化。 CPUのSIMD命令やGPUとも相性が良く、現代のニューラルネットがGPUで爆速で動く理由でもあります。

図解
全結合層 — 3入力 × 4ニューロン

各入力ノードから、すべてのニューロンに線が伸びている=「全」結合。

x₁ x₂ x₃ y₁ y₂ y₃ y₄ 入力 (3次元) 出力 (4次元)

重みの数 = 3 × 4 = 12個。バイアスは出力数と同じ4個。
合計 16 個のパラメータが、この全結合層を支配します。

4. 多層化 — MLP(Multi-Layer Perceptron)

全結合層を直列に重ねたものMLP(多層パーセプトロン)と呼びます。

図解
3層MLP — 入力2次元 → 中間4次元 → 中間4次元 → 出力1次元
x₁ x₂ y 入力層 中間層1 中間層2 出力層

各層の間に活性化関数を挟んで処理を流していきます:

h_1 = σ(W_1 · x + b_1)       ← 中間層1の出力
h_2 = σ(W_2 · h_1 + b_2)     ← 中間層2の出力
y   = W_3 · h_2 + b_3        ← 最終出力

5. なぜ層を重ねる意味があるのか

ニューラルネットの核心的な数学的事実がここにあります。

💡 重要な事実

活性化関数なしで、線形変換を何回重ねても、結局1層分の表現力しか出ない。

これを防ぐために、層と層の間に必ず非線形な活性化関数を挟む必要があります。

📝 具体例:1次元の数値で「線形2段=1段」を確認(クリックで展開)

1次元での例:

  • 1層目: $f(x) = 2x + 3$
  • 2層目: $g(x) = 4x + 5$

合成すると:

g(f(x)) = g(2x + 3)
        = 4·(2x + 3) + 5
        = 8x + 12 + 5
        = 8x + 17

これは結局 $h(x) = 8x + 17$ という1個の線形関数と同じ。 2段に重ねたのに、表現できる範囲が広がっていない。

インタラクティブ・デモ
「線形2段」 vs 「ReLU入り2段」を比較

同じ重みで、活性化関数あり/なしを切り替えて出力を比較します。右側のグラフが直線か折れ線かに注目。

1層目: f(x) = w₁·x + b₁

w₁ 2.0
b₁ -1.0

2層目: g(z) = w₂·z + b₂

w₂ 1.5
b₂ 0.5
🔴 線形2段(活性化なし)

y = 3.0x - 1.0

どれだけパラメータを動かしても、必ず直線になる。

🟢 ReLU入り2段

y = w₂ · ReLU(w₁x + b₁) + b₂

折れ線になる。直線では表現できない関数を表現できる。

📐 数学・補足:普遍近似定理(Universal Approximation Theorem)(クリックで展開)

活性化関数を挟んだ多層NNには、強力な性質があります:

📐 普遍近似定理 (Universal Approximation Theorem)

活性化関数を持つ十分大きな隠れ層を1つ持つNNは、任意の連続関数を任意の精度で近似できる

これがNNが「あらゆる関数の近似器」として使える理由です。 将棋の評価関数のような複雑な非線形関数も、層を重ねたNNなら表現できます。

まとめ

  1. ニューロン = 入力に重みを掛けて足して、活性化関数を通す関数
  2. 全結合層 = 複数のニューロンを並列に並べたもの。$y = \sigma(Wx + b)$
  3. MLP = 全結合層を直列に重ねたシンプルなNN
  4. 活性化関数なしでは、何層重ねても1層分の表現力しか出ない
  5. 活性化関数を挟むと、層を重ねるほど表現力が指数的に広がる

次の章

「重みパラメータをどうやって決めるのか?」が次のテーマ。 数百万個のパラメータをデータから自動的に決めるのが「学習」。 勾配降下法と誤差逆伝播法を、アニメーションを動かして体感します。

→ 第4章「学習の仕組み」へ進む