序
私はAIの研究者ではありません。一介のプログラマーです。中身を漠然としか理解していませんが、昨今のAIの進展により、できる事の幅が増えてきました。BP無しで学習できたら、それは確かに夢のような事です。面白そうだし、AIの助けを借りれば、やれるんじゃね?と思って実験を始めました。やった流れとしては、まずBPなしのMINISTで層を10層まで増やしても学習できるようにする事をしました。次に英文学習をやらせました。するとEDLAの特性からアルファベットの文字分だけ層を分けて学習しないとうまく行かないようで行き詰まりました。そもそも層はマトリックスである必要があるのか?動的にニューロンを形成する仕組みの方が向いているのではないか?という発想に至り、動的EDLAを考えて実装してみようという事にしました。課題は多く、なるほど、AI研究は沼だというのを実感しているところです。
本文書の目的: AIに手伝ってもらいながら試していると、リソースが散らばってしまい、自分でも何をやってきたのか、分からなくなってきました。中途半端な状態ですが、本プロジェクトで何を目指し、何を試し、何がわかったのかを、AIにまとめさせました。以下は、AIによるまとめになります。コードを書いて実験し検証した事ですが、内容は保証されるものではありません。そこは差っ引いて読んでください。
EDLA研究報告書 — BPなし学習アルゴリズムの探究と発見
目次
- はじめに — 何をしたかったのか
- ED法とは何か — BPを使わない学習の基本原理
- 静的EDLA実験(Phase 1〜20)— 固定構造ネットワークの最適化
- DynamicEDLA実験(Phase 01〜11)— 構造そのものを学習する
- PRELLM — 言語モデルへの挑戦
- 手法の体系的評価 — 何が効いて何が効かなかったか
- ノード状態診断ガイド — 学習の「健康診断」の方法
- 結論と今後の展望
- 付録: 数式・コードリファレンス
1. はじめに — 何をしたかったのか
1.1 研究の動機
ディープラーニング(深層学習)の成功は、バックプロパゲーション(BP) という手法に支えられています。
BPは「出力の誤差を、ネットワークの奥に向かって逆向きに伝え、全ての重みを一斉に調整する」手法です。
非常に強力ですが、人間の脳はBPを行っていないと考えられています。
本研究は、BPを一切使わない学習法「ED法(Error Diffusion)」 で、
画像分類や言語モデルといった実用的なタスクをどこまで解けるか?を探る実験です。
1.2 研究の全体像
研究の全体像
❶ 静的EDLA実験 (Phase 1〜20)
└ 固定サイズのネットワークでMNIST分類を最適化
ベスト: 10層 97.48% / 2層 97.53%
❷ PRELLM (Phase 1)
└ 文字レベルの言語モデルに挑戦
状態: 実装完了・実験初期段階
❸ DynamicEDLA実験 (Phase 01〜11)
└ ネットワークの「形」自体を学習させる
ベスト: Grid+Neurogenesis 95.97%
1.3 使用データ
- MNIST: 手書き数字(0〜9)の白黒画像 28×28ピクセル。訓練60,000枚、テスト10,000枚
- Tiny Shakespeare: シェイクスピア全集約110万文字(PRELLM用)
1.4 実行環境
- Apple M1 MacBook Pro
- C++17, clang++, NEON SIMD / Apple Accelerate (BLAS)
2. ED法とは何か — BPを使わない学習の基本原理
2.1 通常の学習(BP法)との違い
通常の深層学習(BP法)では、出力の誤差を**チェーンルール(連鎖律)**で
各層に逆伝播させて重みを更新します。これは数学的に最も効率的ですが、
脳の動作原理とは大きく異なります。
ED法(Error Diffusion)は、BP法の代わりに**「誤差をそのまま全層に拡散させる」**手法です。
BP法(誤差逆伝播)
入力 → 層1 → 層2 → 出力
← 誤差 ← 逆伝播
(重みの値を使って、精密に誤差を遡る)
ED法(誤差拡散)
入力 → 層1 → 層2 → 出力
↑ ↑ ↑ 誤差
(同じ誤差信号を、全層にそのまま配る)
(重みの「符号」だけを使って更新方向を決定)
最大の違い: BP法は「重みの値」を使って誤差を逆方向に送りますが、
ED法は「重みの符号(プラスかマイナスか)」だけを使います。
重みの大きさ自体は逆伝播に使いません。
2.2 P/Nニューロン構造
ED法の中核は P型(Positive)とN型(Negative)のニューロン対 です。
入力 x = [x₁, x₂, ..., xₙ]
↓ 複製
拡張入力 = [x₁,...,xₙ, x₁,...,xₙ]
├── P半分 ──┤├── N半分 ──┤
P型ニューロン: 正の重み(w_pp≥0)で前半を、負の重み(w_np≤0)で後半を受け取る
N型ニューロン: 負の重み(w_pn≤0)で前半を、正の重み(w_nn≥0)で後半を受け取る
出力 = g(P出力 + N出力) ※ g = 活性化関数
なぜこうするのか? 通常のBP法では重みが自由に正負を行き来できますが、
ED法では 重みの符号を固定 することで、「符号だけで更新方向を決める」仕組みが成立します。
2.3 更新則(数式)
学習の更新ルールを具体的に書くと:
$$d = \text{target} - \text{output}$$
$d > 0$ のとき(出力が小さすぎる → もっと大きく出力したい):
$$\Delta w_{pp} = \eta \cdot d \cdot g'(a) \cdot x \cdot \text{sign}(w_{pp})$$
$$\Delta w_{np} = \eta \cdot d \cdot g'(a) \cdot x \cdot \text{sign}(w_{np})$$
$d < 0$ のとき(出力が大きすぎる → もっと小さく出力したい):
$$\Delta w_{nn} = \eta \cdot |d| \cdot g'(a) \cdot x \cdot \text{sign}(w_{nn})$$
$$\Delta w_{pn} = \eta \cdot |d| \cdot g'(a) \cdot x \cdot \text{sign}(w_{pn})$$
ここで:
- $\eta$ = 学習率(本研究では 1.0 が最適と判明)
- $g'(a)$ = 活性化関数の微分
- $\text{sign}(w)$ = 重みの符号(+1 または -1)
重要: $\text{sign}(w)$ を掛けることで、重みの「大きさ」は更新量に影響しません。
これがBP法との最大の違いであり、ED法の核心です。
2.4 K個の独立ネットワーク並列
ED法の特性上、1つのネットワークで多クラス分類をすることはできません。
理由: 全層に同じ誤差 $d$ を拡散するため、複数の出力が互いに矛盾する更新を受けてしまうからです。
解決策: クラスごとに独立したEDLAネットワークを用意し、各々が「このクラスか否か」を判定します。
入力画像
├── EDLA[0]: 「0か?」 → スコア 0.12
├── EDLA[1]: 「1か?」 → スコア 0.03
├── EDLA[2]: 「2か?」 → スコア 0.87 ← 最大 → 予測: 2
├── ...
└── EDLA[9]: 「9か?」 → スコア 0.04
MNIST(10クラス)なら $K=10$ 個のネットワークを並列実行します。
これは一見非効率に見えますが、本研究で多クラス分類が動作する唯一の安定した方式でした。
2.5 活性化関数
本研究では $\tanh(a/5)$ を $[0, 1]$ にスケーリングした関数を使用:
$$g(a) = \frac{\tanh(a/5) + 1}{2}$$
これは一般的なシグモイド関数の約2.3倍の勾配を持ち、
「信号が弱くなりすぎて学習できない」問題を軽減します(Phase 3で発見)。
3. 静的EDLA実験(Phase 1〜20)— 固定構造ネットワークの最適化
3.1 全体の精度推移
以下は、各フェーズで達成した最高精度の推移です。
精度 %
98 ┤ ★97.53(2層)
│ ★97.48(10層)
97 ┤ ★97.13
│ ★96.39
96 ┤
│
95 ┤
│
94 ┤
│
93 ┤
│
92 ┤
91 ┤ ★91.04──────────────┐
90 ┤ │
│ │
85 ┤ ★85.05 │
│ │
11 ┤★──────┐ │
│ │ │
0 ├───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬──→ Phase
2 9a 9b 11 13 14 15 16 18 20
│←── バグ修正 ──→│← 公平条件 →│← Xavier ──→│← DepthSkip→│
3.2 Phase 1: Qiita記事の再現(2値分類)— 99.91%
目的: ED法が「そもそも動くのか」を最小構成で検証。
- データ: MNIST の「0」と「1」だけ(約12,000枚)
- 構成: 1隠れ層、P/Nニューロン対
- 結果: 99.91% — ED法のコアアルゴリズムが正しいことを確認
3.3 Phase 2: 多クラス分類への拡張 — 11.35%(失敗)
目的: 10クラスに拡張。
- 1つのネットワークの出力を10個に増やす素朴な方法を試行
- 結果: 11.35%(ランダムと同等) — 完全に失敗
- 原因: 全層に同じ誤差信号が拡散される構造では、10個の出力が矛盾する更新を受ける
- 教訓: → $K=10$ 個の独立ネットワーク並列に方針転換(Phase 9aで実現)
3.4 Phase 9a: 5つの重大バグ修正 — 85.05%
PC故障でコードを全喪失後、arXiv論文の公式実装を精査して再構築。
5つのバグを発見・修正:
| # | バグ内容 | 影響 |
|---|---|---|
| 1 | 入力の複製(torch.cat([x,x]))が欠落 |
P/N構造が機能しない |
| 2 | P半分/N半分への入力分割が不正 | 符号制約の意味がなくなる |
| 3 | sigmoid適用前の値を保存していない | 微分計算が不正確 |
| 4 | update_core の入力分割ミス | 重み更新が正しくない |
| 5 | 初期化スケールが10,000倍ずれ | 学習が不安定 |
結果: 9.80% → 85.05% — 一気に改善。
3.5 Phase 9b: NEON最適化 — 97.53%(2層ベスト)
- テンプレートフレームワーク化 + ARM NEON SIMD命令で高速化
- 2層(入力→隠れ1層→出力)、H=16、15エポック
- 結果: 97.53% — これが2層のベスト記録
3.6 Phase 13: 公平条件 — 91.04%(10層ベースライン)
10層ネットワークの評価を、2層と同じ条件(60,000枚全量、lr=1.0)に揃えて実施:
- 結果: 91.04% — 2層の97.53%に大きく劣る
- 各種手法を試すもいずれも ±0.5% の微差:
| 手法 | 精度 | 改善幅 |
|---|---|---|
| Baseline | 91.04% | — |
| Oja(Hebb則) | 90.45% | -0.59% |
| Gated(0.5) | 91.25% | +0.21% |
| Gated + Oja | 91.55% | +0.51% |
| Gated + Identity(25%) | 91.62% | +0.58% |
疑問: なぜ10層にしても2層に勝てないのか? → Phase 14で原因判明
3.7 Phase 14: 対称性の罠の発見 ★
これが本研究で最も重要な発見の一つです。
10層ネットワークの各層の重みベクトルを調べたところ:
層間のコサイン類似度:
L1-L2: 1.0000 L2-L3: 1.0000 L3-L4: 1.0000
L4-L5: 1.0000 L5-L6: 1.0000 ... L8-L9: 1.0000
各層の活性化値:
L1: 64個のニューロン全て → 出力値 0.0080(全く同じ値!)
L2: 64個のニューロン全て → 出力値 0.0080(全く同じ値!)
...
全ての隠れ層が完全に同じ重みベクトル方向 を向いていました。
つまり 「10層あるように見えて、実質1層」 という状態です。
【対称性の罠のメカニズム】
① 初期化: 全重みを同じ微小値(0.0001)で設定
↓
② ED法の性質: 全層が同じ誤差信号 d を受け取る
↓
③ 全層が同じ更新を受ける → 全層が同じ方向に動く
↓
④ 一度揃うと、永遠に同期したまま → 10層が実質1層
※ BP法ではこの問題は起きない。各層が異なる誤差を受け取るため。
※ ED法特有の問題。
3.8 Phase 15: Xavier初期化によるブレイクスルー ★
対称性の罠を破るために、Xavier初期化を導入:
$$\sigma = \sqrt{\frac{2}{n_{\text{in}}}}$$
各ニューロンの初期重みをこの標準偏差でランダムに設定することで、
初期状態から各ニューロンに「個性」を与えます。
初期化の比較:
旧方式(IS=0.0001): 全ニューロンがほぼ同じ → cos_sim = 1.0000
Xavier初期化: 各ニューロンが異なる → cos_sim = 0.65〜0.84
結果: 91.04% → 96.39%(+5.35%) — 劇的改善!
追加実験:
| 手法 | 精度 | 判定 |
|---|---|---|
| Xavier | 96.24% | ✅ |
| Xavier + NeuronMask | 96.39% | ✅ |
| Xavier + Dropout(0.3) | 86.26% | ❌ |
| Xavier + LR=0.1 | 86.92% | ❌ |
発見: Dropout・低学習率はED法に有害。signベースの更新には lr=1.0 が必須。
3.9 Phase 17: P/N分離層診断 — 新たな問題の発見
Xavier初期化後でも、深層のP型ニューロンの信号が減衰していることを発見:
深層のσ(出力値の標準偏差):
L1: 0.2400 ← 多様に発火している
L2: 0.1800
L3: 0.1200
...
L8: 0.0000 ← 全ニューロン同一値 = 事実上「死んでいる」
L9: 0.0000 ← 全ニューロン同一値
これはED版の「勾配消失問題」 です。BPの勾配消失とは原因が異なりますが、
深い層ほど信号が弱まるという現象は同じです。
3.10 Phase 18: DepthScaled Skip Connection ★
深層の信号減衰を解決するため、DepthScaled Skip Connection を開発:
通常のSkip: y = f(x) + x (ResNetのように入力をそのまま加算)
DepthScaled: y = f(x) + α(l) × x (深さに応じて加算量を調整)
α(l) = 0.2 + 0.8 × l / (L-1)
浅い層 → α ≈ 0.2 (小さい: 自力で学習させる)
深い層 → α → 1.0 (大きい: 信号を強く伝える)
なぜ一律ではダメなのか?
| 方式 | 精度 | 問題 |
|---|---|---|
| Skip なし (Baseline) | 96.46% | 深層の信号死亡 |
| Additive (α=1.0) | 95.08% | 信号が強すぎて爆発 |
| Weighted (α=0.3) | 96.09% | まだ信号不足 |
| DepthScaled | 97.16% | ✅ 深さに応じた適切な量 |
| Skip + Gated 併用 | 95.80% | 二重に信号を加えて不安定 |
深層の健全性比較:
| 指標 | Gated Baseline | DepthScaled |
|---|---|---|
| L8 の σ | 0.0000 💀 | 0.2377 ✅ |
| L9 の σ | 0.0000 💀 | 0.2166 ✅ |
| 平均 cos_sim | 0.751(同期気味) | 0.624(多様) |
3.11 Phase 20: 最終到達 — 97.48%
DepthScaled Skip + NeuronMask + 40エポックで最終最高精度:
10層: 97.48%(2層の97.53%にわずか0.05%差)
エポックと精度の関係:
ep 10: 96.5%
ep 15: 96.8%
ep 20: 97.0%
ep 25: 97.16%
ep 30: 97.3%
ep 37: 97.48% ← Best
→ エポック延長が最も安定した改善手段(+0.32%)
追加発見:
- EDLAは重みの符号を一切反転しない(反転率0%)。初期化時の符号構造を完全に保存する
- DepthScaledのα範囲は全パターンで精度差0.21%以内 → パラメータに対してロバスト
- 深層重みは ep15 で収束するが、出力層はまだ学習を続けている → 長期学習が有効
4. DynamicEDLA実験(Phase 01〜11)— 構造そのものを学習する
4.1 着想
静的EDLA(第3章)では、ネットワークの「形」は人間が事前に決めていました。
DynamicEDLAでは、ネットワークの構造自体を学習によって自動構築 させます。
静的EDLA: 人間が「10層、各64ニューロン」と決めてから学習
Dynamic: 空のグラフから始めて、必要に応じてノード・エッジを追加
→ 「形」が学習結果そのものになる
4.2 全体の精度推移
精度 %
96 ┤ ★95.97
95 ┤
94 ┤ ★94.61
93 ┤
92 ┤ ★92.60
91 ┤
90 ┤ ★90.61
89 ┤ ★89.14─────★89.22
88 ┤
87 ┤
86 ┤
85 ┤
84 ┤ ★84.72
83 ┤ ★83.29
│
0 ├───┬───┬───┬───┬───┬───┬───┬───┬───┬───┬──→ Phase
01 02 03 04 05 06 07 08 09 10
│← 基礎 →│← 刈込 →│← 受容野 →│←STDP→│← Grid →│
4.3 Phase 01〜02: 初期プロトタイプ — 89%の壁
-
Phase 01 v2: 入力→出力の直結パスだけで89.14%
- 中間ノード200個は全て死亡(一切使われない)
- → 直結パスの線形分類限界が89% という発見
-
Phase 02: 側方抑制(WTA)で中間ノードの多様性を確保
- 多様性は54倍改善(分散: 0.002 → 0.108)
- だが精度は83.29%(多様性が精度に直結しない)
4.4 Phase 03〜05: Weight Decay と刈り込み
「弱いエッジを刈り取る」ことで、重要な接続だけを残す実験:
| 方式 | 精度 | 発見 |
|---|---|---|
| 一律 decay | 83.38% | 直結パスまで刈り取ってしまう |
| 直結保護 + 中間 decay | 89.18% | 直結の89%に回復するだけ |
| 閾値ベース(弱いものだけ刈る) | 89.22% | ✅ 脳のシナプス刈り込みと同じ原理 |
| 漸減 decay(連続関数) | 83.98% | 強いエッジも弱化してしまう |
教訓: 「弱いものだけ刈る」が正解。一律 decay は有害。
4.5 Phase 06: 局所受容野 — 89%の壁を突破 ★
「目の網膜細胞が近くのピクセルだけ見る」ように、
7×7ピクセルの局所受容野を導入:
ランダム接続(旧): 局所受容野(新):
┌─────────────┐ ┌─────────────┐
│ ● ● ● │ │ │
│ ● ● │ │ ■■■ │
│ ● ● ● │ │ ■■■ │ ← 7×7パッチ
│ ● ● │ │ ■■■ │
│ ● ● │ │ │
└─────────────┘ └─────────────┘
画像全体からバラバラに取得 近くのピクセルをまとめて見る
結果: 90.61%(89%の壁を初めて突破)
- 空間的に近いピクセルをまとめて見ることで、エッジ(輪郭線)等の特徴を検出可能に
- 中間ノードが初めて「分類に実質的に貢献」した瞬間
4.6 Phase 07〜09: STDP — 自動階層構築 ★
STDP(Spike-Timing-Dependent Plasticity) は脳の学習則の一つです。
「ニューロンAが発火した直後にBが発火する」パターンが繰り返されると、
AからBへの接続が自動的に強化されます。
STDPの原理:
時間 →
A: ──■────────── (先に発火)
B: ────────■──── (直後に発火)
→ A→B のエッジを自動生成(因果関係を学習)
これを使って、隠れノード間に自動的にエッジを追加:
| Phase | 手法 | 精度 | 改善幅 |
|---|---|---|---|
| 07a | 基本STDP(H→Hエッジ追加) | 89.95% | +0.3% |
| 07b | 空間STDP(近いノード同士だけ) | 90.36% | +0.7% |
| 07c | 空間STDP + Skip + H=500 + 30ep | 92.60% | +2.0% |
| 08 | アブレーション(要因分析) | 92.60% | — |
| 09 | sparsity=0.40 に最適化 | 94.61% | +2.0% |
Phase 08(アブレーション)の発見: STDPが精度向上の支配的要因(+1.9〜3.0%)。
ノード数やエポック数より、STDPの有無が精度を決定的に左右する。
4.7 Phase 10: グリッド配置 + ニューロジェネシス — 95.97% ★
グリッド配置: 隠れノードを28×28の格子状に均等配置(網膜の光受容体のモデル):
ランダム配置(旧): グリッド配置(新):
● ● ● ● ● ● ● ● ● ● ●
● ● ● ● ● ● ● ● ● ●
● ● ● ● ● ● ● ● ● ●
● ● ● ● ● ● ● ● ● ● ●
● ● ● ● ● ● ● ● ● ●
疎密にムラがある 均一に全領域をカバー
ニューロジェネシス(神経新生): 全ノードを最初から作るのではなく、
必要に応じて段階的にノードを追加:
ep 1: ○ ○ ○ ○ ○ ○ ○ ○ (スロットだけ用意)
● ○ ○ ○ ○ ○ ● ○ (需要のある場所にだけノード生成)
ep 5: ● ● ○ ● ○ ● ● ● (学習が進むにつれ増える)
ep15: ● ● ● ● ● ● ● ● (最終的にほぼ充填)
○ = 空きスロット(受容体) ● = 実体化したノード
結果: 95.97%(DynamicEDLAの最高精度)
- 全ノード一括配置(90.79%)より +5.18%
- ニューロジェネシスにより、「必要な場所に必要なだけ」ノードが生える
4.8 Phase 11: 深層受容体グリッド(進行中)
Phase 10 は実質3層(入力→隠れ1層→出力)。
これを10層に拡張する試みが Phase 11:
Phase 10 (3層):
入力(28×28) → 隠れ(28×28) → 出力(10)
Phase 11 (深層):
入力(28×28) → L1(14×14) → L2(14×14) → ... → L10(14×14) → 出力(10)
課題と対策:
| 課題 | 原因 | 対策 |
|---|---|---|
| 全スロットが一瞬で埋まる | 成長条件がゆるい |
max_growth_per_epoch 導入 |
| L1だけ成長し深層が空 | 層間制約のデッドロック | デッドロック回避ロジック |
| 精度崩壊 | 重み爆発 |
grad_clip, weight_clip
|
| 名ばかり深層(接続が浅い) | depth制約バグ | 前層接続のみ許可 |
5. PRELLM — 言語モデルへの挑戦
5.1 MNIST から言語モデルへ
MNISTでの成功(97.48%)を受けて、EDLAで次の文字を予測する言語モデルに挑戦。
MNIST分類: 画像(784次元) → K=10 EDLA → 数字(0-9)
文字予測: 文字列(32文字×32dim) → K=66 EDLA → 次の文字(a-z, A-Z, ...)
5.2 設計
- 入力: 直近32文字をそれぞれ32次元の埋め込みベクトルに変換し、連結 → 1024次元
- モデル: $K \approx 70$(ユニーク文字数)の独立EDLAネットワーク並列
- 訓練データ: Tiny Shakespeare(約110万文字)
- 成功基準: ランダム(1.5%)を大幅に超え、"th", "he", "in" 等の文字パターンが出現
5.3 なぜワードベクトルを使わないか
Word2Vec等の埋め込みは BPで学習されたもの です。
「BPなし」の思想を貫くため、EDLAの更新則で埋め込み自体も学習させる方針です。
5.4 計算量の課題
| 語彙 | K | MNISTの何倍? | 1ep所要時間 |
|---|---|---|---|
| 文字 | ~70 | 7倍 | 数分 |
| サブワード(BPE) | ~8,000 | 800倍 | 数時間 |
| 単語 | ~30,000 | 3,000倍 | 非現実的 |
→ 文字レベルから段階的に検証する方針。
6. 手法の体系的評価 — 何が効いて何が効かなかったか
6.1 一覧表: 全手法の成否
✅ 効果あり ⚠️ 条件付き ❌ 効果なし/有害
| 手法 | 判定 | 効果 | Phase | 備考 |
|---|---|---|---|---|
| sign(w) 更新 | ✅ | 必須 | 2 | ED法の核心 |
| K=10 並列 | ✅ | 必須 | 9a | 多クラスの唯一解 |
| tanh(a/5) | ✅ | +数% | 3 | sigmoidの2.3倍の勾配 |
| Xavier初期化 | ✅ | +5.3% | 15 | 対称性破壊の核心 |
| DepthScaled Skip | ✅ | +0.7% | 18 | 深層信号の唯一解 |
| NeuronMask | ✅ | +0.15% | 15 | 対称性の再収束防止 |
| エポック延長 | ✅ | +0.3〜0.7% | 16,20 | 最も安定した改善 |
| BLAS バッチ化 | ✅ | 速度×3.5 | FW | 精度劣化なし |
| STDP | ✅ | +2〜3% | 07-09 | Dynamic系の支配的要因 |
| Grid配置 | ✅ | +5% | 10 | 均一カバレッジ |
| Neurogenesis | ✅ | +5% | 10 | 需要駆動の構造構築 |
| 局所受容野 | ✅ | +1.4% | 06 | 89%の壁を突破 |
| 閾値decay | ✅ | +0.04% | 04 | 「弱いもの刈り」 |
| Gated skip | ⚠️ | +0.2% | 11,16 | 信号維持するが同期を招く |
| Identity 経路 | ⚠️ | ±0.5% | 13 | 旧バグ時代の劇的効果は虚偽 |
| Hebb (Oja/BCM) | ❌ | -7〜-85% | 12 | P/N構造と根本的に非互換 |
| Dropout | ❌ | -10% | 15 | sign更新に攻撃的すぎる |
| LayerNorm | ❌ | -7% | 19 | 均一化がsign信号を消す |
| softmax出力 | ❌ | -9% | 3 | P/N構造と相性が悪い |
| ED+BPハイブリッド | ❌ | 破綻 | 8 | パラメータの意味が違う |
| Metal GPU | ❌ | なし | 10 | 行列が小さすぎて恩恵なし |
6.2 なぜ効かなかったか — 根本原因の分析
Dropout がEDLAに有害な理由
BP法: Dropout → ランダムにニューロンをオフ → 汎化向上 ✅
ED法: Dropout → 発火数が減る → 誤差信号が乱れる
→ sign(w)の更新方向が不安定に → 精度低下 ❌
補足: ED法ではDropout時に0ではなく0.5(中立値)を使用するが、
それでも信号の質が劣化してしまう
LayerNorm がEDLAに有害な理由
LayerNorm は「全ニューロンの出力を揃える」操作。
しかしED法は「ニューロン間の違い」を利用して学習する。
LayerNorm適用後:
全ニューロンの出力 → 平均0, 分散1 に正規化
→ 個性が消える → sign(w)の方向が均一化
→ 全層の重みが同じ方向に更新 → cos_sim > 0.96
→ 実質1層に退化(対称性の罠の再発)
Hebb則 がEDLAに有害な理由
Hebb則: 「一緒に発火するニューロンの接続を強化」
EDLA: sigmoid活性化(出力は0〜1) + 初期化0.0001
Ojaの更新: Δw = η × y × (x - y × w)
→ 重みが一方的に増大 → sigmoid飽和 → 学習信号消滅
さらに:
Hebb則はP/Nの符号制約を無視して重みを変えるため、
P型の重みが負、N型の重みが正になる → ED法の前提が崩壊
6.3 効いた手法の成功理由
Xavier初期化がEDLAに効く理由
ED法の問題: 全層に同じ誤差信号 d が届く
→ 初期重みが揃っていると、全ニューロンが同じ更新を受ける
→ 永遠に同期(対称性の罠)
Xavier: 各重みを σ = √(2/fan_in) のランダム値で初期化
→ 初期状態で各ニューロンが異なる「個性」を持つ
→ 同じ d を受けても、異なる更新量になる(sign(w)が違うため)
→ 対称性が破壊される
DepthScaled Skip がEDLAに効く理由
ED法の深層問題: 深い層は入力から遠く、信号が減衰して死ぬ
浅い層(L1-L3):
入力信号が直接届く → 強い学習信号 → α は小さくてよい(0.2)
α が大きいとSkip信号に頼りすぎて自力学習できない
深い層(L8-L10):
入力信号がほとんど届かない → 弱い学習信号 → α を大きくする(→1.0)
Skip接続で前層の信号を直接受け取り、信号死を回避
α(l) = 0.2 + 0.8 × l/(L-1) ← 浅いほど小、深いほど大
7. ノード状態診断ガイド — 学習の「健康診断」の方法
7.1 なぜ診断が重要か
学習中に精度が上がらない時、原因は大きく分けて3つあります:
- 構造の問題 — ネットワークの形が不適切
- 最適化の問題 — 重みの更新がうまくいっていない
- 両方
これを見分けるために、学習中のログから計算される値を読みます。
7.2 見るべき値と意味
① acc(精度)— 最も基本
健全: 10% → 50% → 80% → 90% (徐々に上昇)
異常1: 10% → 10% → 10% (全く学習していない)
異常2: 10% → 85% → 60% → 40% (一度上がって崩壊)
精度だけでは原因がわからないので、以下の値と合わせて判断します。
② layer_summary(層ごとのノード情報)— 構造の健全性
各層について「何個のノードが作られたか」「何個が発火したか」を表示:
正常: L1: 120/196 L2: 80/196 L3: 45/196 (段階的に増加)
異常1: L1: 196/196 L2: 196/196 L3: 196/196 (全スロット即埋まり)
異常2: L1: 120/196 L2: 0/196 L3: 0/196 (浅層で成長停止)
| パターン | 意味 | 対策 |
|---|---|---|
| 全層すぐ埋まる | 成長条件がゆるすぎる |
max_growth を下げる |
| L1だけ増えてL2以降が0 | デッドロック |
min_prev_fill を下げる |
| 段階的に深層が増える | ✅ 正常 | — |
③ max|wp|、max|wn|(重みの最大絶対値)— 安定性の指標
正常: ep1: 0.5 → ep5: 1.2 → ep10: 2.0 (ゆるやかに増加)
異常: ep1: 0.5 → ep3: 10 → ep5: 100 (急増 = 重み爆発)
異常: ep1: 0.5 → ep5: 0.5 → ep10: 0.5 (変化なし = 学習していない)
重みが急増している場合、grad_clip(更新量の上限)を下げるか、
weight_clip(重みの絶対値上限)を導入します。
④ fired_hidden / hidden(発火率)— ネットワークの活用度
適正: 30〜60% (スパースだが活発)
低すぎ: 5%以下 (ほとんどのノードが無効 = もったいない)
高すぎ: 95%以上 (全ノード発火 = 選択性がない)
⑤ cos_sim(層間コサイン類似度)— 対称性の監視
cos_sim = 1.0 → 2つの層が完全に同じ(対称性の罠!)
cos_sim = 0.6〜0.8 → 適度に異なる(正常)
cos_sim = 0.0 → 完全に無関係(正常だがまれ)
7.3 診断フローチャート
精度が上がらない
│
├── layer_summary を確認
│ ├── 全スロット即埋まり → 成長条件を厳しく
│ ├── L1だけ → デッドロック解消
│ └── 段階的に成長 → 構造は正常 → ②へ
│
├── max|wp| を確認
│ ├── 急増 → grad_clip / weight_clip 導入
│ ├── 変化なし → lr が低すぎる?
│ └── ゆるやかに増加 → 正常 → ③へ
│
└── cos_sim を確認
├── > 0.95 → 対称性の罠 → Xavier / Mask 導入
└── < 0.85 → 正常 → 他の原因を調査
7.4 具体例: よくある症状と処方箋
症例1: 精度が最初から10%台(ランダム同等)
チェック: layer_summary → 構造は正常
チェック: max|wp| → 0.0001のまま(学習していない)
チェック: cos_sim → 1.0000(全層同じ)
診断: 対称性の罠
処方: Xavier初期化に変更
症例2: 精度が85%まで上がって崩壊
チェック: max|wp| → ep5: 2.0 → ep8: 50 → ep10: 500(爆発!)
チェック: layer_summary → 全スロットが ep3 で埋まっている
診断: 成長過多 + 重み爆発
処方: max_growth を下げる、grad_clip = 5.0, weight_clip = 10.0
症例3: 精度が88%で停滞
チェック: layer_summary → L1のみ120/196、L2以降 0
チェック: max|wp| → 安定
チェック: cos_sim → 0.7(正常)
診断: 深層未活用(成長デッドロック)
処方: min_prev_fill を0.5→0.25 に緩和
8. 結論と今後の展望
8.1 本研究で得られた知見
- ED法は MNIST 97.48% を達成できる(BPの98-99%には及ばないが、実用的な水準)
- ED法特有の罠が存在する: 対称性の罠(全層同期)、ED版勾配消失(深層信号死)
- BP法の常識がED法に通用しない: Dropout、LayerNorm、Hebb則、softmax は全て有害
- ED法に効く手法は限定的: Xavier初期化、DepthScaled Skip、NeuronMask、エポック延長
- 構造学習(DynamicEDLA)はED法と好相性: STDP、Grid配置、Neurogenesis で95.97%を達成
- K=独立並列が ED法の多クラス化の唯一安定解
8.2 BP法との根本的な違い
| 特性 | BP法 | ED法 |
|---|---|---|
| 誤差伝播 | 重みの値を使って精密に逆伝播 | 符号だけで全層に一括拡散 |
| 層の個性 | 各層が異なる勾配を受ける | 全層が同じ diff を受ける |
| 初期化 | ある程度自由 | Xavier必須(でないと対称性の罠) |
| Dropout | 汎化に有効 | 有害(-10%) |
| LayerNorm | ほぼ必須 | 有害(-7%) |
| 学習率 | 0.001〜0.01 が一般的 | 1.0 が最適 |
| 符号 | 自由に反転 | 一切反転しない(反転率0%) |
| 多クラス | softmax + cross-entropy | K個の独立ネットワーク並列 |
8.3 精度の到達点まとめ
| 系列 | 構成 | Best Acc |
|---|---|---|
| 静的EDLA 2層 | H=16, 15ep | 97.53% |
| 静的EDLA 10層 | DepthSkip+Mask, 40ep | 97.48% |
| DynamicEDLA | Grid+Neurogenesis, sp=0.60 | 95.97% |
| DynamicEDLA Deep | 10層受容体スロット | 87〜88% (進行中) |
8.4 今後の方向性
- DynamicEDLA深層: 深層受容体グリッドの成長制御を最適化し、静的EDLA 97%に迫る
- PRELLM: 文字レベル言語モデルで「EDLAでテキスト予測ができるか」を検証
- スケーリング: BLAS/Metal活用でより大きな問題(CIFAR-10等)への適用
- 理論的分析: ED法の収束条件・表現力の数学的な理解
9. 付録: 数式・コードリファレンス
A. ED法の更新式(C++実装)
// d = target - output
float d = target - output;
if (d > 0) {
// 出力を増やしたい → P系の重みを更新
for (int j = 0; j < n; j++) {
float grad = lr * d * g_prime * x[j] * sign(wp[j]);
wp[j] += clamp(grad, -grad_clip, grad_clip);
}
} else {
// 出力を減らしたい → N系の重みを更新
for (int j = 0; j < n; j++) {
float grad = lr * fabs(d) * g_prime * x[j] * sign(wn[j]);
wn[j] += clamp(grad, -grad_clip, grad_clip);
}
}
B. Xavier初期化(P/N符号制約あり)
float sigma = sqrtf(2.0f / fan_in);
for (int i = 0; i < size; i++) {
wp[i] = fabsf(normal(0, sigma)); // P重み → 正値を保証
wn[i] = -fabsf(normal(0, sigma)); // N重み → 負値を保証
}
C. DepthScaled Skip Connection
// 層 l のSkip比率
float alpha = 0.2f + 0.8f * (float)l / (float)(num_layers - 1);
// 適用
for (int j = 0; j < size; j++) {
output[j] = activation(pre_activation[j]) + alpha * prev_layer[j];
}
D. 対称性の診断(コサイン類似度)
float cos_sim(const float* a, const float* b, int n) {
float dot = 0, na = 0, nb = 0;
for (int i = 0; i < n; i++) {
dot += a[i] * b[i];
na += a[i] * a[i];
nb += b[i] * b[i];
}
return dot / (sqrtf(na) * sqrtf(nb) + 1e-8f);
}
// 使い方: 隣接層の重みベクトルに対して計算
// cos_sim > 0.95 なら対称性の罠の可能性大
E. ニューロジェネシス(DynamicEDLA)
void neurogenesis(float residual_thresh, int max_growth) {
int grown = 0;
for (auto& slot : empty_slots) {
if (grown >= max_growth) break;
if (residual_at(slot) > residual_thresh) {
create_node_at(slot); // ノードを実体化
connect_to_receptive_field(); // 局所受容野に接続
grown++;
}
}
}
F. STDP(自動エッジ追加)
// A→B: Aが先に発火し、Bが直後に発火するパターンを検出
if (cofire_count(A, B) >= min_cofire
&& causal_ratio(A, B) >= threshold) {
add_edge(A, B, initial_weight);
}