ニューラルネットの基礎
ニューロン1個の動作から始めて、活性化関数、全結合層、なぜ層を重ねるか、をインタラクティブに学びます。 スライダーを動かしながら読み進めてください。
この章の全体像 — ボトムアップで組み立てる
ニューラルネットワークは、たった3つの構成要素を 順に積み上げて できています。 まず全体像を把握してから、各セクションで詳しく見ていきましょう。
ニューロン1個
入力に 重みを掛けて足し、活性化関数を通すだけの、1個のスカラー値を出す関数。
$y = \sigma(w_1 x_1 + w_2 x_2 + w_3 x_3 + b)$
全結合層(1層)
ニューロンを 横に並べて並列化。全員が同じ入力を見る。ベクトル → ベクトルの変換になる。
$\mathbf{y} = \sigma(W \mathbf{x} + \mathbf{b})$
多層(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個のニューロンがやることは、入力に重みを掛けて足して、活性化関数を通すだけ。
数式で書くと:
- $x_1, x_2, x_3$ : 入力
- $w_1, w_2, w_3$ : 重み(学習で決まる)
- $b$ : バイアス(学習で決まる)
- $\sigma$ : 活性化関数(ReLU, Sigmoid 等)
- $y$ : 出力
下のスライダーで入力 $x_i$、重み $w_i$、バイアス $b$ を動かすと、ニューロンの出力 $y$ がリアルタイムで変わります。
入力
重みとバイアス
活性化関数
2. 活性化関数 — なぜ非線形が必要か
活性化関数 $\sigma$ は「線形な総和($w \cdot x + b$)にひと手間加える非線形変換」です。 なぜ必要なのか? 非線形変換がないと、層を重ねても1層分の表現力しか出ないからです。これは後で詳しく見ます。
代表的な活性化関数を順に紹介します。それぞれ「何をする関数か」「いつ使うか」「歴史的な位置づけ」を見ていきましょう。 読んだあと、下のインタラクティブグラフで形を比較すると理解が深まります。
2.1 ReLU(Rectified Linear Unit)
動作:「入力 $z$ が正ならそのまま通す、負ならゼロにする」だけ。 数学的にも実装的にも極めて単純な関数。
- $z = 3.5$ → $\sigma(z) = 3.5$(そのまま)
- $z = -2.0$ → $\sigma(z) = 0$(負はゼロ)
- $z = 0$ → $\sigma(z) = 0$
なぜ重要か:
- 計算が速い:「負を0にする」だけ。掛け算も指数関数も不要
- 微分が簡単:$z > 0$なら微分は1、$z < 0$なら0。学習時の勾配計算が楽
- 勾配消失問題が起きにくい:正の領域で微分が常に1なので、深いNNでも勾配が消えない
使われる場所:現代の深層学習の事実上のデフォルト。CNN、Transformer、ほとんどの中間層で使われている。 「迷ったらReLU」が機械学習エンジニアの常識。
📚 コラム:2.2 Sigmoid(シグモイド関数)— 歴史的主役と勾配消失問題(クリックで展開)
動作:どんな実数を入れても、出力を 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」のように使える。
歴史的位置づけ:
- 1980〜2000年代:ニューラルネットの活性化関数の主役だった。 生物学的なニューロンが「発火するかしないか」(0か1か)を連続的に近似する関数として、自然に思えた
- 2010年代以降:中間層ではほぼ使われなくなった。理由は次の「勾配消失問題」
- 現在: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の中心化版(クリックで展開)
動作: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)で標準採用される量子化対応版(クリックで展開)
動作: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 問題への対処(クリックで展開)
動作: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 まとめ
使い分けの大方針:
- 中間層 → ReLU(ほぼ全部これ)
- 2値分類の出力層 → Sigmoid
- 多クラス分類の出力層 → Softmax(後の章で扱う)
- NNUE 等の量子化前提の場面 → ClippedReLU
- RNN / LSTM の内部 → tanh(歴史的経緯)
- ReLU で死ぬ問題が起きたら → Leaky ReLU
では、これらの関数の 形を実際に見比べてみましょう。タブで切り替えると、グラフがリアルタイムで描き直されます。
下のタブで活性化関数を切り替えると、グラフがリアルタイムで更新されます。
ReLU: 負の入力をすべて0にする。最も高速で、深いNNの主流。
3. 全結合層(Fully Connected Layer)— 「1層」の中身
💡 このセクションで扱うのは「1層分」。 ニューラルネットは これを複数積み重ねた もので、 1層分の構造を理解すれば、何層あっても同じ仕組みです。次の §4 多層化(MLP) で何層も積みます。
ニューロンを複数並べて、全員が同じ入力を見る構成を 全結合層と呼びます。 これがニューラルネットの「層(layer)」の正体です。
数式:
ここで $W$ は重み行列、$b$ はバイアスベクトル。具体的に書くと:
入力 $x$ が3次元、出力 $y$ が2次元の場合:
つまり:
- $y_1 = \sigma(w_{11} x_1 + w_{12} x_2 + w_{13} x_3 + b_1)$
- $y_2 = \sigma(w_{21} x_1 + w_{22} x_2 + w_{23} x_3 + b_2)$
2個のニューロンが、それぞれ独自の重みで同じ入力を見ている、というだけです。
3.1 重み行列 W の見方 — 行が1ニューロンに対応
ここが 全結合層を理解する核心。 $W$ の各行が、1個のニューロンの重みベクトルです。 複数ニューロンの重みを 1つの行列にパッケージしているわけです。
入力3次元 → 出力4次元(ニューロン4個)の場合を見てみましょう:
| ニューロン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 = σ( W · x + b )
(4,) (4, 3) (3,) (4,)
↑ ↑ ↑ ↑
出力 重み行列 入力 バイアス
(ニューロン4個) (3次元) (各ニューロン1個ずつ)
プログラマ的に言えば、これは「N個のニューロンをforループで回さず、行列演算で一発処理する」という効率化。 CPUのSIMD命令やGPUとも相性が良く、現代のニューラルネットがGPUで爆速で動く理由でもあります。
各入力ノードから、すべてのニューロンに線が伸びている=「全」結合。
重みの数 = 3 × 4 = 12個。バイアスは出力数と同じ4個。
合計 16 個のパラメータが、この全結合層を支配します。
4. 多層化 — MLP(Multi-Layer Perceptron)
全結合層を直列に重ねたものを MLP(多層パーセプトロン)と呼びます。
各層の間に活性化関数を挟んで処理を流していきます:
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段に重ねたのに、表現できる範囲が広がっていない。
同じ重みで、活性化関数あり/なしを切り替えて出力を比較します。右側のグラフが直線か折れ線かに注目。
1層目: f(x) = w₁·x + b₁
2層目: g(z) = w₂·z + b₂
y = 3.0x - 1.0
どれだけパラメータを動かしても、必ず直線になる。
y = w₂ · ReLU(w₁x + b₁) + b₂
折れ線になる。直線では表現できない関数を表現できる。
📐 数学・補足:普遍近似定理(Universal Approximation Theorem)(クリックで展開)
活性化関数を挟んだ多層NNには、強力な性質があります:
📐 普遍近似定理 (Universal Approximation Theorem)
活性化関数を持つ十分大きな隠れ層を1つ持つNNは、任意の連続関数を任意の精度で近似できる。
これがNNが「あらゆる関数の近似器」として使える理由です。 将棋の評価関数のような複雑な非線形関数も、層を重ねたNNなら表現できます。
まとめ
- ニューロン = 入力に重みを掛けて足して、活性化関数を通す関数
- 全結合層 = 複数のニューロンを並列に並べたもの。$y = \sigma(Wx + b)$
- MLP = 全結合層を直列に重ねたシンプルなNN
- 活性化関数なしでは、何層重ねても1層分の表現力しか出ない
- 活性化関数を挟むと、層を重ねるほど表現力が指数的に広がる
次の章
「重みパラメータをどうやって決めるのか?」が次のテーマ。 数百万個のパラメータをデータから自動的に決めるのが「学習」。 勾配降下法と誤差逆伝播法を、アニメーションを動かして体感します。