Day 110 — ニューラルネットワークとは何か — パーセプトロン・活性化関数・誤差逆伝播の直感

2026-07-31 紫 / Phase 5 理論→コーディング Phase 5 開幕 / パーセプトロン・活性化関数・逆伝播

📚 背景知識(読んでから問題へ)

🟣
Phase 4 では GBDT(XGBoost・LightGBM・CatBoost)を軸に、表形式データ(Tabular)で上位10%(Silver) を狙える武器を揃えました。今日から始まる Phase 5(紫帯) では、GBDTが苦手とする領域 —— 画像・テキスト・音声・時系列の生データ —— に強い ニューラルネットワーク(Neural Network, NN) を学びます。目標は Master ランク(Gold 1枚 + Bronze 2枚)です。

なぜGBDTでは足りないのか

GBDTは「人間が意味のある特徴量を作ってあげれば」非常に強力ですが、生の画像ピクセルや生の文章を渡されると途端に無力です。1枚の画像は数万〜数百万個のピクセル値の羅列にすぎず、GBDTはその「並び」に隠れた意味(輪郭・質感・単語の並び順)をうまく学習できません。ニューラルネットワークは、層を重ねることで「生データ → 単純な特徴 → 複雑な特徴 → 予測」という変換を自動的に学習する仕組みです。これが画像・テキスト・音声で圧倒的な強さを発揮する理由です。

項目GBDT(Phase 4)ニューラルネットワーク(Phase 5)
得意なデータ表形式(数値・カテゴリ)画像・テキスト・音声・系列データ
特徴量人間が設計(Aggregation・TargetEncoding等)データから自動的に学習(表現学習)
基本単位決定木ニューロン(パーセプトロン)
学習法勾配ブースティング(木を順に追加)誤差逆伝播(重みを繰り返し微調整)
主要ライブラリLightGBM・XGBoost・CatBoostPyTorch(Day 111から本格導入)
🔑
キーワード
パーセプトロン: ニューラルネットワークの最小単位。複数の入力を受け取り重み付き合計を計算し、活性化関数を通して1つの出力を返す「1個の判断ユニット」
重み・バイアス: 各入力の重要度(重み)と判断の基準点をずらす調整値(バイアス)。線形回帰の係数・切片と同じ役割
活性化関数: 重み付き合計に「曲がり」を加える関数(sigmoid・ReLU等)。これがないと何層重ねても直線(線形)にしかならない
順伝播: 入力から出力へ、層を順番に計算していく処理
逆伝播: 出力の誤差を、どのニューロンがどれだけ「悪かったか」を遡って計算し、重みを修正するための情報を作る処理

🗂️ 今日使うデータ: XOR(排他的論理和)

今日は実データの代わりに、ニューラルネットワークの本質を最小構成で示す「XOR問題」を使います。データはたった4行、しかしニューラルネット研究の歴史を左右した重要な例です。

カラム説明
x1int(0 or 1)入力1
x2int(0 or 1)入力2
yint(0 or 1)正解ラベル = x1 XOR x2(どちらか片方だけ1のときに1)
x1x2y
000
011
101
110

📐 線形分離可能性を視覚的に理解する

左は OR ゲート(1本の直線できれいに分けられる)、右は XOR ゲート(どんな直線を引いても必ず誤分類が出る)。同じ「2入力・2値分類」でも構造が根本的に違うことを見比べてください。

OR ゲート(線形分離◎) x1 x2 境界線 (0,0)→0 (0,1)→1 (1,0)→1 (1,1)→1
XOR ゲート(線形分離✕) x1 x2 試した境界線 (0,0)→0 (1,1)→0 (0,1)→1 (1,0)→1 対角の2点が同じラベルなので、1本の直線では必ずどこかで誤分類が出る
💡
直感: XORの `y=0` 2点 (0,0),(1,1) は対角線上、`y=1` 2点 (0,1),(1,0) ももう一方の対角線上に位置します。1本の直線は平面を2つの半分に分けるだけなので、対角に並ぶ2点を同じ側に、もう一方の対角2点を反対側に、同時に分けることは幾何学的に不可能です。理論上の上限は4点中3点(75%)までしか正解できません。

🎯 問題

1
ロジスティック回帰=1個のニューロン(理論): Day 052のロジスティック回帰の「重み」「バイアス」「シグモイド関数」が、パーセプトロンの用語で何に対応するかを対応表で整理する
2
XORはなぜ直線で解けないか(理論・図解): 上のXORの4点が「1本の直線」では分けられない理由を自分の言葉で説明する
3
単層 vs 多層の数値比較(コーディング): ①単層パーセプトロンでランダム探索してもXORの正解率が100%に届かないことを確認し、②手設計した隠れ層1つのネットワークで100%を達成する
4
誤差逆伝播を比喩で説明する(理論): バックプロパゲーションを身近な比喩(組立ライン等)を使って3〜4文で説明する

💡 ヒント

ヒント1方向性

タスク1・2は「新しい概念」というより「Phase 2で習ったことの言い換え」です。ロジスティック回帰の数式 sigmoid(w1*x1 + w2*x2 + b) をそのままパーセプトロンの図に当てはめてみてください。タスク2は、XORの4点を実際に紙やこのページの図で見比べると直感的に分かります。

ヒント2アプローチ
  • タスク3-1: w = np.random.uniform(-2, 2, size=2)b = np.random.uniform(-2, 2) を何千回も試し、step(X @ w + b) の正解率の最大値を記録する
  • タスク3-2: 隠れ層の2ユニットに ORNAND(NOT AND)の役割を持たせ、出力層でその2つを AND する、と XOR が作れる(OR(h1) AND NAND(h2) = XOR
  • 活性化関数は sigmoid(gain * z)gain を大きくすると、階段関数(0か1かをくっきり分ける関数)に近づく
ヒント3コード骨格
import numpy as np

X = np.array([[0,0],[0,1],[1,0],[1,1]])
y = np.array([0,1,1,0])

def step(z):
    return (z > 0).astype(int)

# --- 単層パーセプトロン: ランダム探索で最高正解率を確認 ---
rng = np.random.default_rng(42)
best_acc = 0
for _ in range(5000):
    w = rng.uniform(-2, 2, size=2)
    b = rng.uniform(-2, 2)
    pred = step(X @ w + b)
    acc = (pred == y).mean()
    best_acc = max(best_acc, acc)
print(f"単層パーセプトロンの最高正解率: {best_acc:.2f}")

# --- 隠れ層ありネットワーク: 手設計の重みでXORを解く ---
def sigmoid(z, gain=20):
    return 1 / (1 + np.exp(-gain * z))

W1 = np.array([[1, -1], [1, -1]])   # h1=OR用, h2=NAND用
b1 = np.array([-0.5, 1.5])
W2 = np.array([1, 1])               # 出力=AND(h1,h2)
b2 = -1.5

def forward(X):
    h = sigmoid(X @ W1 + b1)
    return sigmoid(h @ W2 + b2)

pred = forward(X)
print("2層ネットワークの予測:", np.round(pred, 2))

模範解答

タスク1: ロジスティック回帰 ⇔ パーセプトロン 対応表

ロジスティック回帰の用語パーセプトロンの用語役割
係数(coefficient)重み(weight)各入力の重要度を表す数値
切片(intercept)バイアス(bias)判断の基準点をずらす調整値
シグモイド関数活性化関数(activation function)重み付き合計を0〜1の確率に変換
sigmoid(w1x1+...+wnxn+b)1個のニューロンの出力入力から出力までの一連の計算
予測確率(0〜1)ニューロンの活性化値そのニューロンが「どれだけ強く発火しているか」
🧩
結論: ロジスティック回帰は「入力層 → 出力層1個」だけの、最もシンプルな(隠れ層なしの)ニューラルネットワークとみなせます。ニューラルネットワークは、このパーセプトロンを縦(層)にも横(ユニット数)にも増やしたものです。

タスク2: XORが線形分離不可能な理由

XORの4点を平面に置くと、y=0 の2点 (0,0),(1,1) が左下と右上の対角、y=1 の2点 (0,1),(1,0) が左上と右下の対角に位置します。1本の直線は平面を2つの半分(半平面)に分けるだけなので、どの直線を引いても対角線上にある2点は必ず反対側に来てしまい、同じラベルの2点を同時に同じ側へ揃えることは幾何学的に不可能です(理論上の上限は4点中3点=75%)。この「曲がった境界線」を作るために、隠れ層と非線形の活性化関数が必要になります。

タスク3: コード実装

import numpy as np

X = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
y = np.array([0, 1, 1, 0])  # XOR

def step(z):
    return (z > 0).astype(int)

# ====== 3-1. 単層パーセプトロン: ランダム探索で最高正解率を確認 ======
rng = np.random.default_rng(42)
best_acc = 0
best_wb = None
for _ in range(5000):
    w = rng.uniform(-2, 2, size=2)
    b = rng.uniform(-2, 2)
    pred = step(X @ w + b)
    acc = (pred == y).mean()
    if acc > best_acc:
        best_acc = acc
        best_wb = (w, b)

print(f"単層パーセプトロンの最高正解率(5000通り試行): {best_acc:.2f}")
# 出力例: 0.75 → どれだけ探しても100%には到達しない(理論上の上限どおり)

# ====== 3-2. 隠れ層ありネットワーク: 手設計の重みでXORを100%解く ======
def sigmoid(z, gain=20):
    # gainを大きくして階段関数に近似(学習後の重みの動きを模倣)
    return 1 / (1 + np.exp(-gain * z))

# 隠れ層: h1 = OR(x1,x2), h2 = NAND(x1,x2)
W1 = np.array([[1, -1],
               [1, -1]])       # 列0: h1(OR)用, 列1: h2(NAND)用
b1 = np.array([-0.5, 1.5])

# 出力層: out = AND(h1, h2)
W2 = np.array([1, 1])
b2 = -1.5

def forward(X):
    h = sigmoid(X @ W1 + b1)     # 隠れ層の出力
    out = sigmoid(h @ W2 + b2)   # 出力層の出力
    return out

pred_prob = forward(X)
pred_label = (pred_prob > 0.5).astype(int)

print("XOR予測確率:", np.round(pred_prob, 3))
print("XOR予測ラベル:", pred_label)
print("正解率:", (pred_label == y).mean())
# 出力例: [0.001 0.999 0.999 0.001] → [0 1 1 0] → 正解率 1.0

タスク4: バックプロパゲーションの比喩

🏭
「完成品の不良を、組立ラインの逆順にたどって、各工程の担当者に『あなたの工程がどれだけ不良に関与したか』を伝え、それぞれ少しだけ作業を調整してもらう」プロセスです。最終検品(出力層)で不良(誤差)が見つかったら、それをいきなり全工程に均等に配分するのではなく、直前の工程から順に「あなたの担当分がこれくらい影響した」を計算しながら遡ります(これが数学的には「連鎖律」)。各担当者(各ニューロンの重み)は自分の関与度に応じて作業のやり方を微調整し、これをバッチごとに繰り返すことでライン全体の不良率が徐々に下がっていきます。

🕸️ 今日組み立てたネットワークの構造

x1 x2 入力層 h1 OR h2 NAND 隠れ層(活性化関数あり) out AND 出力層 = XOR(x1,x2) 2入力 → 隠れ層2ユニット → 1出力(本日の手設計ネットワーク)

h1が「OR」、h2が「NAND」という単純なパターンをそれぞれ学習(今回は手設計)し、出力層がその2つを「AND」で組み合わせることで、単層では表現できなかったXORが再現できる。これが「層を重ねるほど複雑な表現ができる」というディープラーニングの最小の実例。

📊 正解率で見る「単層」と「多層」の差

XORデータに対する正解率(accuracy) 単層パーセプトロン 75%(理論上の上限) 隠れ層1つのネットワーク 100%
⚠️
単層パーセプトロンはどれだけ重みを探しても75%の壁を超えられません(数学的に不可能)。隠れ層をたった1つ足すだけで100%に到達する —— この落差こそが「なぜディープラーニングには層の深さが必要なのか」の最小の答えです。

🪜 Step-by-Step 解説

1ロジスティック回帰=1個のニューロンと捉え直す

# Phase 2で書いたロジスティック回帰の予測式
prob = 1 / (1 + np.exp(-(w1*x1 + w2*x2 + b)))
🔧
なぜこうするか: 新しい概念に見えるニューラルネットワークも、根っこは既に習った数式の組み合わせです。「知らないもの」ではなく「知っているものの拡張」として捉えることで、Phase 5 の学習コストが大きく下がります。

2XORの4点を図で確認する(線形分離不可能性)

X = np.array([[0,0],[0,1],[1,0],[1,1]])
y = np.array([0,1,1,0])
📐
なぜこうするか: 「1本の直線では分けられないデータが存在する」という事実を、抽象的な説明ではなく具体的な4点で確認することで、「なぜ隠れ層が必要か」が腹落ちします。

3単層パーセプトロンの限界を数値で体感する

best_acc = 0
for _ in range(5000):
    w = rng.uniform(-2, 2, size=2)
    b = rng.uniform(-2, 2)
    acc = (step(X @ w + b) == y).mean()
    best_acc = max(best_acc, acc)
🔁
なぜこうするか: 5000通りものランダムな直線を試しても75%の壁を超えられないことを実際に確認することで、「単層では原理的に不可能」であることを実感できます。

4隠れ層で「OR」と「NAND」を作り、出力層で「AND」する

h = sigmoid(X @ W1 + b1)     # h1=OR(x1,x2), h2=NAND(x1,x2)
out = sigmoid(h @ W2 + b2)   # out=AND(h1,h2) = XOR(x1,x2)
🧬
なぜこうするか: XORは実は OR AND NAND という2つの単純な論理演算の組み合わせで表現できます。隠れ層が「単純なパターン」を作り、出力層がそれらを「組み合わせる」ことで、単層では不可能だった複雑な境界線を再現できます。これがディープラーニングの「層を重ねるほど複雑な表現ができる」という考え方の最小の実例です。

5この先、重みは「手設計」ではなく「学習」で決める

🎓
今回は重みを手で設計しましたが、実際のニューラルネットワークでは誤差逆伝播 + 勾配降下法によって、ランダムな初期値から自動的にこの「OR/NAND/AND」に相当するような重みを見つけ出します。Day 111 以降、PyTorchでこの「自動で重みを学習する」部分を実装していきます。

🧮 数学・統計の補足(文系向け)

🌀
シグモイド関数の直感: 「どんな数字を入れても、0〜1の間の『確率っぽい値』に押し込めてくれる変換機」。Phase 2 のロジスティック回帰で既に登場した関数で、ニューラルネットワークではこれ(や後述のReLU)を活性化関数と呼びます。もしこれがなかったら: 各層が「重み付き合計」だけだと、何層重ねても数学的には1層の重み付き合計と同じになってしまいます(線形変換を何回繰り返しても線形変換のまま)。活性化関数という「曲がり」を挟むことで、初めて層を重ねる意味が生まれます。
⛓️
連鎖律(Chain Rule)の直感: 「AがBに影響し、BがCに影響するなら、AがCに与える影響は『AがBに与える影響』×『BがCに与える影響』で計算できる」。誤差逆伝播は、この考え方を「出力層の誤差 → 最後の層の重み → その前の層の重み → …」と順番に遡って適用しているだけです。
∂L/∂w = (∂L/∂out) × (∂out/∂w)
→ 「重み w を少し変えたら最終的な誤差 L がどれだけ変わるか」を、途中の出力 out を経由して段階的に計算しているだけ、という意味。

🏆 Kaggleでの実践的な使い方

よく使われるコンペカテゴリ: ☐ 表形式データ(Tabular) / ☑ 自然言語処理(NLP) / ☑ 画像認識(CV) / ☑ 時系列(Time Series)

画像

🖼️ CNN(Day 121〜)

ピクセルから直接学習

Petfinder・Plant Pathology等の画像コンペで、ピクセルの並びから輪郭・質感などの特徴を自動抽出する。

テキスト

📝 BERT系(Day 116〜)

文脈を理解する

Jigsaw・US Patent Phrase Matching等のNLPコンペで、単語の並びや文脈をTransformerが捉える。

Tabularでも稀に

🔗 GBDT×NNアンサンブル

Stackingの発展形

数値・カテゴリが非常に多く複雑な相互作用を持つ場合、GBDTとNNを組み合わせると単体より強くなることがある。

⚠️ よくある誤解・ミス

誤解・ミスなぜ起こるか正しい理解
ニューラルネットワークはGBDTの完全上位互換だと思う「ディープラーニング=最新・最強」というイメージ先行Tabularデータでは今もGBDTが優位なことが多い。NNが強いのは画像・テキスト・音声など「生の非構造化データ」
活性化関数はなくても層を重ねれば複雑な表現ができると思う線形代数の直感がまだない活性化関数(非線形性)がなければ、何層重ねても数学的には1層の線形変換と等価になる
誤差逆伝播は「新しいアルゴリズム」だと身構える数式の見た目が複雑やっていることは連鎖律(掛け算の繰り返し)。Phase 2の勾配降下法の延長線上の概念
XORのような単純な例に実用性がないと思うトイ問題に見える「単層で解けない・多層なら解ける」という最小の反例として、なぜ深さが必要かを理解する上で最も重要な例。歴史的にもNN研究の停滞と復活の分岐点になった問題
パーセプトロン=ニューラルネットワーク全体だと思う用語が似ているパーセプトロンは「ニューロン1個」の名称。ニューラルネットワークはそれを多数組み合わせたネットワーク全体を指す

🚀 次のステップ

  • 発展: 今回は重みを手設計しましたが、W1, b1, W2, b2 をランダム初期化し、勾配降下法で少しずつ更新するコード(バックプロパゲーションの自作実装)を書いて、XORの正解率が0.5前後から徐々に1.0に近づく過程を確認してみましょう
  • 次回予告: Day 111 — PyTorch入門①(Tensor・自動微分の仕組み)。今日手計算で行った順伝播・誤差逆伝播を、PyTorchが loss.backward() の一行でどう自動化しているかを学ぶ

Phase 5 の学習マップ(全20テーマ予定)

1-5 DL基礎(PyTorch)
6-10 NLP
11-15 CV
16-18 時系列
19-20 マルチモーダル

本日(Day 110)は「1-5 DL基礎」の1テーマ目。Phase 4で培った評価指標・CV・過学習対策の土台の上に、ニューラルネットワークという新しい武器を積み上げ、Master ランク(Gold + Bronze×2)を目指す。

🟣 Phase 5(紫帯)スタート! GBDTで培った土台の上に、ニューラルネットワークという新しい武器を積み上げていきます。

📝 自己評価(解いた後に記入)

自分の回答・気づき・メモ: