本文へスキップ
hdknr blog

ニューラルネットワークの基礎

パーセプトロンの限界(XOR)から、多層化と誤差逆伝播法による突破、フレームワークの自動微分と過学習までを 1 本の流れで整理する

概要

脳の構造をまねるボトムアップのアプローチ。1 つのニューロンがするのは、入力に重みを掛けて足し、活性化関数に通すだけ(Y = f(Σ xᵢwᵢ))。その単純な素子を層にして大量のデータで訓練する。

歴史は「限界があった → 乗り越えた → 道具で手軽になったが、注意点もある」という 1 本の話として読める。1 層のパーセプトロンは直線 1 本でしか分けられず XOR が解けない。層を重ねて非線形の活性化関数をはさみ、誤差逆伝播法で学習させるとそれを越えられる。PyTorch や TensorFlow が勾配計算を自動化し、強いモデルが手軽に作れるようになった代わりに、過学習に注意が要る。

詳細

パーセプトロンとその限界

資料による表記の違い(パーセプトロン)

日本語の入門記事を読み比べると、本質は同じでも約束事が違う。別の資料に移るときに戸惑いやすい。

項目よくある書き方別の書き方
出力の値0 と 1−1 と +1(AI-For-Beginners など)
バイアス常に 1 の入力に掛かる重み w₀しきい値 θ(常に −1 の入力の重み)
発火の条件z ≥ 0 で 1z > 0 で 1
層の数え方入力層と出力層で「2 層」重みを持つ層だけで「1 層」(英語の single-layer perceptron)

0/1 表記の学習則は w ← w + η(t − y)x で、間違えたときだけ重みを正解の方向へ動かす。線形分離可能なデータなら有限回で必ず収束する(パーセプトロンの収束定理)。NumPy だけの実装では AND は 6 エポック、OR は 4 エポックで収束し、XOR は何エポック回しても 4 件中 2 件しか合わない。隠れ層 4 個・シグモイド・誤差逆伝播で学習させると XOR の出力は [0.007, 0.981, 0.981, 0.024] になる。

年代は資料によって揺れる(パーセプトロンは 1957 年の提案書か 1958 年の論文か、Mark I は 1958 年試作か 1959 年か)。多層ネットワークの学習法として誤差逆伝播法を広めたのは 1986 年のラメルハート、ヒントン、ウィリアムズの論文で、「1990 年代に考案」とする記述は誤り。

MLP の位置づけ

多層化と誤差逆伝播法

各レイヤーを forward / backward / update を持つクラスとして NumPy だけで書くと、Linear → tanh → Linear → Softmax の 2 層で XOR の 4 点を確率 0.999 / 0.001 で正しく分類できた(1 層では全点 0.5 で判断できない)。十分なニューロンがあれば 2 層で任意の凸集合、3 層でほぼ任意の集合を分類できる。

フレームワーク: 自動微分と GPU

NumPy はテンソル演算はできるが勾配は計算できない。フレームワークに求めるのは任意の式の勾配の自動計算と GPU / TPU での並列化。

TensorFlowPyTorch
低レベル APITensorFlow(tf.GradientTape)PyTorch(requires_grad=True → backward())
高レベル APIKeras(compile → fit)PyTorch Lightning(LightningModule → Trainer)

PyTorch の学習ループの optim.zero_grad() → loss.backward() → optim.step() の 3 行は、手書きした「勾配リセット → 逆伝播 → 更新」にそのまま対応する。PyTorch は勾配を加算して蓄積するので、ステップごとのリセットを忘れない。Keras は 2023 年の Keras 3 から TensorFlow・JAX・PyTorch のどれでも動くマルチバックエンドになった。

過学習とバイアス・バリアンス

5 点をパラメータ 7 個のモデルで近似すると学習誤差 0・検証誤差 20、直線(パラメータ 2 個)なら 5.3 / 5.1。表現力が高いモデルほど汎化に多くのデータを要する。

これは統計学のバイアス(未学習)とバリアンス(過学習)のトレードオフの一例である。

教材の Notebook を 2026 年の環境で動かす

症状原因対処
TypeError: tuple indices must be integersdata/mnist.pkl.gz が 2025 年に (学習, 検証, テスト) のタプル形式へ差し替わったタプルとして読み、(tr_x * 256).round().astype(np.int32) で辞書に詰め直す
module 'numpy' has no attribute 'NAN'NumPy 2.0 で別名が削除np.nan
'ArtistList' object has no attribute 'pop'Matplotlib の ax.lines がリストでなくなったax.lines[-1].remove()
dtype='string' is not a valid dtypeKeras 3 で compile の 3 番目の位置引数が loss_weights にmetrics=['accuracy'] をキーワードで渡す
MisconfigurationExceptionMac で accelerator='cuda'accelerator='auto'

教材のコード自体の誤りもある。PyTorch 版の手書き Network クラスは zero_grad で勾配ではなく重みを 0 にし、バイアスを勾配でなく値で更新しているが、修正前も後も正解率 0.8 で結果からは気づけない。TensorFlow 版は binary_crossentropy(z, y) と引数が逆で、残された出力でも損失が 4.78 → 8.43 と増えている。

関連ページ

ソース記事