- AI ⚙️
- 技術 💻
ニューラルネットワークとは|仕組み・学習・AttentionをNumPyで実演
結論
ニューラルネットワークは、重み付きの足し算と変換を層に重ね、誤差から重みを直して学ぶ計算の仕組みです。Attentionは、その中で「どこを見るか」の重みを毎回計算する部品です。
この記事でわかること
- NumPyで学習させ損失が0.67→0.0009に下がる実物
- CNN・RNN・Transformer・GANの違い表4種
- Q・K・Vから重みの行列3×3を手計算した全過程
入力に重みを掛けて足し、活性化関数で変換して出力します。正解とのずれ(誤差)を出力側から逆にたどり、重みを少しずつ直すのが「学習」です。
flowchart TD
A[入力<br>数値の並び] --> B[層<br>重み付きの和と活性化関数]
B --> C[出力<br>予測]
C --> D[正解との誤差<br>損失]
D -.->|誤差逆伝播で<br>重みを直す| B
この記事に出てくる言葉と、手元で動かして確かめた実物の早見表です。
| 言葉 | ひとことで | この記事の実物 |
|---|---|---|
| ニューラルネットワーク | ニューロンを層につないだ計算の網 | XORと手書き数字を学習 |
| 重み・バイアス | 入力ごとの効き具合と底上げ | AND回路になる重み |
| 活性化関数 | 直線でない変換(ReLUなど) | 無いと損失0.6931のまま |
| 誤差逆伝播法 | 誤差から各重みの直し方を求める | 数値微分との差 3.49e-08 |
| Attention | どの単語を見るかの重み付け | 重みの行列を手計算 |
| Self-Attention | 同じ文の単語同士のAttention | Transformer・LLMの中心 |
確認環境:Ubuntu 24.04.4・Python 3.11.15・NumPy 2.4.6・scikit-learn 1.9.1(同梱の手書き数字データ load_digits と MLPClassifier)。ニューロン1個の計算、XOR を学習する 2-4-1 のネットワーク、手書き数字を学習する 64-32-10 のネットワーク、Attention(Query・Key・Value・マスク・Multi-Head)をすべて NumPy で書いて実行し、出力・損失・正解率をそのまま載せています。乱数の種は固定しているので、同じ版なら同じ数値が出ます。Attention の式と Transformer の構造は論文「Attention Is All You Need」、Attention の始まりは Bahdanau 氏らの論文、誤差逆伝播法は Rumelhart 氏らの論文、GPT・BERT・ViT・Whisper・GAN・Mixture-of-Experts・FlashAttention・GQA は各論文と公式リポジトリ、PyTorch・Keras の関数は公式ドキュメント、用途の例は Google Cloud と AWS の解説ページ、英単語の意味は Weblio 辞書で確かめました(確認日 2026年10月22日)。
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「ニューラルネットワークとは|仕組み・学習・AttentionをNumPyで実演」
ニューラルネットワークとは
この節では、ニューラルネットワークが何で、どんな問題に強いのかが分かります。
ニューラルネットワーク(neural network)は、脳の神経細胞(ニューロン)のつながりにヒントを得た計算の仕組みです。 「ニューロン」と呼ぶ小さな計算の単位をたくさん並べて層にし、層と層をつなぎます。つながりにはそれぞれ「重み」という数値があり、この重みを大量のデータから自動で調整します。
Google Cloud の解説は、ニューラルネットワークを「人間の脳にヒントを得た機械学習のアルゴリズム」とし、画像認識や自然言語処理のように、従来の方法では扱いにくい問題に強いと説明しています。AWS の解説も、入力と出力の間の複雑で直線的でない関係を学べることを重要な点に挙げています。
ただし、中身は生物の脳とは別物です。やっていることは掛け算・足し算・簡単な関数の組み合わせで、この記事のコードもすべて NumPy の行列計算だけで書けています。
| 脳の言葉 | ニューラルネットワークでの意味 | 中身 |
|---|---|---|
| ニューロン(神経細胞) | 1つの計算の単位(ノード) | 重み付きの和+活性化関数 |
| シナプスの強さ | 重み(weight) | 1つの実数 |
| 発火のしやすさ | バイアス(bias) | 1つの実数 |
| 発火する・しない | 活性化関数の出力 | 0〜1 や 0以上の値 |
| 経験から学ぶ | 学習(訓練) | 誤差が小さくなるよう重みを更新 |
なぜ必要か:ルールを書けない問題を、データから解く
「メールが迷惑メールか」「写真に猫が写っているか」は、if 文のルールで書き切れません。ニューラルネットワークは、入力と正解の組(例:画像と「猫」)をたくさん見せると、その対応を表す重みを自分で見つけます。人が書くのはネットワークの形と学習の手順で、判定のルールそのものは重みとして学習されます。
ニューロン1個の計算:重み・バイアス・活性化関数
この節では、ニューロン1個が何を計算しているかが、AND 回路の実物で分かります。
ニューロン1個の計算は「入力×重みを全部足し、バイアスを足し、活性化関数に通す」だけです。 式で書くと、出力 = f(x₁w₁ + x₂w₂ + … + b) です。f が活性化関数です。
flowchart TD
X1[入力 x1] -->|重み w1| S[足し算<br>+バイアス b]
X2[入力 x2] -->|重み w2| S
S --> F[活性化関数 f]
F --> Y[出力]
重みを w₁ = 1、w₂ = 1、バイアスを b = -1.5 にし、活性化関数を「0より大きければ1、それ以外は0」(ステップ関数)にすると、2つとも1のときだけ1を出す AND 回路になります。
import numpy as np
def neuron(x, w, b, f):
z = np.dot(x, w) + b
return z, f(z)
step = lambda z: (z > 0).astype(int)
w = np.array([1.0, 1.0]); b = -1.5 # AND になる重みとバイアス
for x in [(0, 0), (0, 1), (1, 0), (1, 1)]:
z, y = neuron(np.array(x), w, b, step)
print(x, z, y)
x1 x2 | z=x1*1+x2*1-1.5 | 出力
0 0 | -1.5 | 0
0 1 | -0.5 | 0
1 0 | -0.5 | 0
1 1 | +0.5 | 1
ステップ関数を使うこの形のニューロンを、パーセプトロン(単純パーセプトロン) と呼びます。ここでは重みを人が決めましたが、ニューラルネットワークでは重みを学習で決めます。
層を重ねる意味:入力層・隠れ層・出力層とXOR
この節では、なぜニューロンを層に重ねるのかが、XOR の例で分かります。
ニューロンを横に並べたものが「層」です。データを受け取る入力層、途中の隠れ層(中間層)、答えを出す出力層に分かれます。隠れ層を2つ以上持つものを、深い(deep)ネットワークと呼びます。
flowchart LR
X1((x1)) --> H1((h1)) & H2((h2)) & H3((h3)) & H4((h4))
X2((x2)) --> H1 & H2 & H3 & H4
H1 & H2 & H3 & H4 --> Y((出力))
この図は、この記事で XOR を学習させる 2-4-1 のネットワーク(入力2・隠れ4・出力1)です。重みは 2×4+4×1 = 12 個、バイアスは 4+1 = 5 個で、合わせて 17 個の数値を学習します。
ニューロン1個(隠れ層なし)では XOR が解けない
XOR は「どちらか片方だけ1なら1」です。(0,1) と (1,0) を1、(0,0) と (1,1) を0に分ける1本の直線は引けません。隠れ層の無いネットワークに XOR を5,000回学習させた結果です。
(a) 隠れ層なし : 損失 0.6931 出力 [0.5 0.5 0.5 0.5]
4つの入力すべてに 0.5(どちらとも言えない)を出したまま止まりました。 損失 0.6931 は、毎回 0.5 と答えたときの値(ln 2)です。隠れ層を1つ足すと解けることを、後の節で実際に学習させて確かめます。
XOR を5,000回学習させた結果
層を重ね、間に活性化関数を挟むと、直線1本では分けられない形も表せる
活性化関数の種類と値の早見表
この節では、活性化関数がなぜ必要で、どんな種類があるかが、実際の値で分かります。
活性化関数は、重み付きの和を「直線でない形」に変える関数です。 これが無いと、層を何枚重ねても、全体が1つの直線の計算(行列1つ)にまとまってしまいます。隠れ層4個を持ちながら活性化関数を外して XOR を学習させると、隠れ層なしと同じ結果になりました。
(b) 活性化関数なし: 損失 0.6931 出力 [0.5 0.5 0.5 0.5]
主な活性化関数に、同じ入力 z = -2〜2 を入れた値です。
z : [-2. -1. 0. 1. 2.]
sigmoid : [0.1192 0.2689 0.5 0.7311 0.8808]
tanh : [-0.964 -0.7616 0. 0.7616 0.964 ]
ReLU : [0. 0. 0. 1. 2.]
GELU : [-0.0455 -0.1587 0. 0.8413 1.9545]
softmax([2.0, 1.0, 0.1]) = [0.659 0.2424 0.0986] 合計 1.0
| 関数 | 式(考え方) | 出力の範囲 | 主な使い道 |
|---|---|---|---|
| シグモイド | 1 / (1 + e^-z) | 0〜1 | 2値分類の出力(確率) |
| tanh | (e^z - e^-z) / (e^z + e^-z) | -1〜1 | 隠れ層、RNN |
| ReLU | max(0, z) | 0以上 | 隠れ層の標準的な選択 |
| GELU | z × 標準正規分布の累積確率 | 約 -0.17 以上 | Transformer(GPT は GELU を採用) |
| ソフトマックス | e^zi ÷ Σe^zj | 0〜1、合計1 | 多クラス分類の出力、Attention の重み |
| ステップ関数 | 0より大きければ1 | 0か1 | パーセプトロン(学習には使いにくい) |
ステップ関数は、ほとんどの場所で傾き(微分)が0になるため、次の節の「勾配で重みを直す」学習が使えません。そのため学習させるネットワークでは、シグモイド・tanh・ReLU のような、傾きが求められる関数を使います。ソフトマックスは、後半の Attention で「どこを見るか」の重みを作る関数としても使います。
ニューラルネットワークの学習の仕組み:損失・勾配降下法・誤差逆伝播
この節では、「学習する」とは具体的に何をしているのかが、4つの手順で分かります。
学習とは、損失(予測と正解のずれ)が小さくなる方向へ、すべての重みを少しずつ動かすことです。 どの重みをどちらへどれだけ動かすかは「勾配」(損失をその重みで微分した値)で決まり、その勾配を出力側から順に効率よく求める方法が誤差逆伝播法(バックプロパゲーション) です。Rumelhart 氏・Hinton 氏・Williams 氏が 1986 年に Nature で発表した論文「Learning representations by back-propagating errors」で広く知られるようになりました。
順伝播:入力から出力を計算する
入力に重みを掛けて足し、活性化関数に通す計算を、層の順に繰り返して予測を出します。
損失を計算する
予測と正解のずれを1つの数値にします。分類では交差エントロピー、数値の予測では二乗誤差がよく使われます。
逆伝播:各重みの勾配を求める
微分の連鎖律を使い、出力層から入力層へ向かって、損失を各重みで微分した値を順に求めます。
重みを更新する
重み ← 重み − 学習率 × 勾配。勾配の逆向き(損失が減る向き)へ少し動かします。これを何千回も繰り返します。
用語の早見表
| 用語 | 意味 | この記事での値 |
|---|---|---|
| 損失関数 | 予測と正解のずれを数値にする関数 | 交差エントロピー |
| 勾配 | 損失を重みで微分した値。増える向きを指す | 誤差逆伝播で計算 |
| 学習率 | 1回に重みを動かす幅 | 0.5(XOR)、0.1(手書き数字) |
| エポック | 学習データを一通り使う回数 | 5,000(XOR)、30(手書き数字) |
| ミニバッチ | 一度に勾配を計算するデータのまとまり | 32枚 |
| 連鎖律 | 合成関数の微分は、各段の微分の掛け算 | tanh の微分 = 1 − tanh² |
誤差逆伝播の勾配は正しいか(数値微分と比べる)
誤差逆伝播で求めた勾配が正しいかは、重みをほんの少し(±0.000001)動かして損失の変化を見る「数値微分」と比べると確かめられます。後の節の XOR のネットワークで比べた結果です。
(c) W1[0,0] の勾配: 誤差逆伝播 -0.0292825938
W1[0,0] の勾配: 数値微分 -0.0292825938
全17個の重みでの相対誤差の最大: 3.49e-08
小数第10位まで一致し、17個すべての重みで相対誤差は 3.49e-08 以下でした。 数値微分は重み1個ごとに損失を2回計算するため、重みが何億個もある実際のモデルでは遅すぎます。誤差逆伝播は、順伝播とほぼ同じ手間で全部の勾配を一度に求められるのが利点です。
NumPyでニューラルネットワークを学習させる(損失が下がる様子)
この節では、XOR を学習させるコードの全文と、損失が下がっていく実際の数値が分かります。
隠れ層4個・活性化関数 tanh・出力シグモイドの 2-4-1 のネットワークです。NumPy だけで、順伝播・損失・誤差逆伝播・勾配降下法をすべて書いています。
import numpy as np
# XOR:どちらか片方だけ1なら1
X = np.array([[0, 0], [0, 1], [1, 0], [1, 1]], dtype=float)
y = np.array([[0], [1], [1], [0]], dtype=float)
def sigmoid(z):
return 1 / (1 + np.exp(-z))
def init(hidden, seed=0):
rng = np.random.default_rng(seed)
return {"W1": rng.normal(0, 1, (2, hidden)), "b1": np.zeros(hidden),
"W2": rng.normal(0, 1, (hidden, 1)), "b2": np.zeros(1)}
def forward(p, X):
h = np.tanh(X @ p["W1"] + p["b1"]) # 隠れ層(活性化関数 tanh)
out = sigmoid(h @ p["W2"] + p["b2"]) # 出力層(0〜1の確率)
return h, out
def loss_fn(out, y): # 2値の交差エントロピー
return float(-np.mean(y * np.log(out) + (1 - y) * np.log(1 - out)))
def backward(p, X, y, h, out): # 誤差逆伝播:出力側から順に勾配を求める
n = len(X)
d_out = (out - y) / n # 損失を出力層の入力で微分した値
g = {"W2": h.T @ d_out, "b2": d_out.sum(0)}
d_h = (d_out @ p["W2"].T) * (1 - h ** 2) # tanh の微分 = 1 - tanh^2
g["W1"] = X.T @ d_h
g["b1"] = d_h.sum(0)
return g
def train(hidden=4, lr=0.5, epochs=5000, seed=1, log=()):
p = init(hidden, seed)
for epoch in range(epochs + 1):
h, out = forward(p, X)
if epoch in log:
acc = np.mean((out > 0.5) == y) * 100
print(f"{epoch:>5} | {loss_fn(out, y):.4f} | {acc:5.1f}% | {np.round(out.ravel(), 3)}")
g = backward(p, X, y, h, out)
for k in p: # 勾配降下法:勾配の逆向きに少し動かす
p[k] -= lr * g[k]
return p
if __name__ == "__main__":
print("epoch | 損失 | 正解率 | 4つの入力への出力")
p = train(log=(0, 100, 300, 500, 1000, 2000, 5000))
epoch | 損失 | 正解率 | 4つの入力への出力
0 | 0.6712 | 50.0% | [0.5 0.659 0.464 0.554]
100 | 0.1231 | 100.0% | [0.048 0.896 0.862 0.168]
300 | 0.0215 | 100.0% | [0.005 0.977 0.976 0.033]
500 | 0.0114 | 100.0% | [0.002 0.988 0.987 0.018]
1000 | 0.0051 | 100.0% | [0.001 0.994 0.994 0.008]
2000 | 0.0024 | 100.0% | [0. 0.997 0.997 0.004]
5000 | 0.0009 | 100.0% | [0. 0.999 0.999 0.002]
学習前はでたらめ(正解率 50%)だった出力が、100回で正解率 100% になり、5,000回で正解 [0, 1, 1, 0] にほぼ一致しました。 損失は 0.6712 から 0.0009 まで下がっています。
NumPy の配列・行列の掛け算(@)・sum(0) などの書き方は、関連記事「NumPyの使い方 基本一覧|配列の作成・演算・形状変更」で扱っています。
手書き数字でテスト正解率98.6%まで学習させる
この節では、同じ仕組みが実際の画像データでも働くことが、学習に使っていないテスト画像の正解率で分かります。
scikit-learn に同梱されている手書き数字のデータ(8×8 ピクセル・1,797枚・0〜9 の10種類)を使います。1,437枚で学習し、残りの360枚は学習に使わずテストに回します。ネットワークは 64-32-10(入力64・隠れ32・出力10)で、隠れ層は ReLU、出力はソフトマックスで「0〜9 それぞれである確率」を出します。
import numpy as np
from sklearn.datasets import load_digits # 8x8ピクセルの手書き数字 1,797枚(同梱データ)
d = load_digits()
X = d.data / 16.0 # 0〜16 を 0〜1 に
Y = np.eye(10)[d.target] # 正解を one-hot に(3 → [0,0,0,1,0,...])
rng = np.random.default_rng(0)
idx = rng.permutation(len(X)); tr, te = idx[:1437], idx[1437:] # 8:2 に分ける
print("学習", len(tr), "枚 / テスト", len(te), "枚 / 入力", X.shape[1], "次元")
W1 = rng.normal(0, np.sqrt(2 / 64), (64, 32)); b1 = np.zeros(32)
W2 = rng.normal(0, np.sqrt(1 / 32), (32, 10)); b2 = np.zeros(10)
print("重みとバイアスの数:", W1.size + b1.size + W2.size + b2.size)
def forward(X):
h = np.maximum(0, X @ W1 + b1) # ReLU
z = h @ W2 + b2
e = np.exp(z - z.max(1, keepdims=True))
return h, e / e.sum(1, keepdims=True) # softmax:10クラスの確率
def evaluate(ix):
_, P = forward(X[ix])
loss = -np.mean(np.sum(Y[ix] * np.log(P + 1e-12), 1))
return loss, np.mean(P.argmax(1) == d.target[ix]) * 100
lr, batch = 0.1, 32
print("epoch | 学習の損失 | 学習の正解率 | テストの正解率")
for epoch in range(0, 31):
if epoch in (0, 1, 2, 5, 10, 20, 30):
l, a = evaluate(tr); _, ta = evaluate(te)
print(f"{epoch:>5} | {l:.4f} | {a:6.2f}% | {ta:6.2f}%")
perm = tr[rng.permutation(len(tr))] # 毎回まぜて
for s in range(0, len(perm), batch): # 32枚ずつ更新(ミニバッチ勾配降下法)
bi = perm[s:s + batch]
h, P = forward(X[bi])
dz = (P - Y[bi]) / len(bi) # softmax+交差エントロピーの勾配
gW2 = h.T @ dz; gb2 = dz.sum(0)
dh = (dz @ W2.T) * (h > 0) # ReLU の微分は 0 か 1
gW1 = X[bi].T @ dh; gb1 = dh.sum(0)
W1 -= lr * gW1; b1 -= lr * gb1; W2 -= lr * gW2; b2 -= lr * gb2
学習 1437 枚 / テスト 360 枚 / 入力 64 次元
重みとバイアスの数: 2410
epoch | 学習の損失 | 学習の正解率 | テストの正解率
0 | 2.3576 | 6.82% | 7.50%
1 | 1.5878 | 68.82% | 66.67%
2 | 0.9016 | 86.22% | 86.94%
5 | 0.3538 | 92.00% | 92.50%
10 | 0.1984 | 95.55% | 97.78%
20 | 0.1152 | 97.56% | 98.33%
30 | 0.0849 | 98.19% | 98.61%
テストで間違えた枚数: 7 / 360
学習前の損失 2.3576 は、10種類を当てずっぽうで答えたときの値(ln 10 ≒ 2.303)に近い数です。30エポックで、学習に使っていない360枚のうち353枚(98.61%)を正しく当てました。 1回の実行は約4秒でした。
間違えた1枚を、文字で描いてみました(# が濃い所)。正解は 9 ですが、ネットワークは 5 である確率を 0.62 と答えています。
間違いの例: 正解 9 → 予測 5 確率 [0. 0.2 0.01 0. 0.01 0.62 0. 0.09 0.03 0.03]
..+###..
.#####..
.####+..
.+##....
...#+...
...+#...
...#+...
..+#....
同じことを scikit-learn で書くと
ライブラリを使うと、同じ形(64-32-10・ReLU・ソフトマックス)のネットワークは数行で書けます。同じ分け方で学習させると、テストの正解率は同じく 98.61% でした(300回で打ち切ったため、収束していないという警告 ConvergenceWarning が出ます)。
from sklearn.neural_network import MLPClassifier
clf = MLPClassifier(hidden_layer_sizes=(32,), max_iter=300, random_state=0)
clf.fit(X[tr], d.target[tr])
print(clf.score(X[te], d.target[te]))
scikit-learn 1.9.1 | 反復 300 回 | テスト正解率 98.61%
層ごとの重みの形: [(64, 32), (32, 10)] | 活性化関数: relu | 出力: softmax
学習がうまくいかないとき:学習率・初期値・過学習
この節では、損失が下がらない・テストだけ悪いときに何が起きているかが、失敗させた実物で分かります。
学習率が大きすぎると発散する
XOR のネットワークで、学習率だけを変えた結果です。
| 学習率 | 100回後の損失 | 5,000回後の損失 | 正解率 |
|---|---|---|---|
| 0.01 | 0.6634 | 0.1222 | 100% |
| 0.1 | 0.5978 | 0.0052 | 100% |
| 0.5 | 0.1231 | 0.0009 | 100% |
| 2.0 | 0.0148 | 0.0002 | 100% |
| 10.0 | 1.5372 | 1.5572 | 75% |
| 50.0 | 4.9564 | 6.6798 | 50% |
学習率が小さいと遅く、大きすぎると損失がかえって増えて学習が壊れます。 10.0 と 50.0 では、重みが動きすぎて谷を飛び越え続けました。実際のモデルでは、Adam のような学習率を自動で調整する手法がよく使われます。
初期値しだいで、途中で止まることがある
最初の重み(乱数)だけを変えて、20回ずつ XOR を学習させました。
hidden=2: 20回中 9 回で正解率100%
hidden=4: 20回中 19 回で正解率100%
hidden=8: 20回中 20 回で正解率100%
失敗した回は、損失 0.347 付近で止まり、2つの入力に 0.5 前後を出し続けました(局所解)。隠れ層のニューロンを増やすと、止まりにくくなりました。
過学習:学習データだけ覚えてしまう
手書き数字を、学習に使う枚数だけ変えて試しました(隠れ層256個・300エポック)。
| 学習に使った枚数 | 学習データの正解率 | テストの正解率 |
|---|---|---|
| 50枚 | 100.0% | 83.9% |
| 1,437枚 | 100.0% | 98.9% |
50枚では学習データを100%当てるのに、テストは83.9%にとどまりました。 学習データにだけ合わせ込み、新しいデータに通用しない状態を過学習(オーバーフィッティング)と呼びます。データを増やすと、テストの正解率は98.9%まで上がりました。
- 1損失が増えていく・NaN になる学習率を1/10にする。入力を0〜1などにそろえる(この記事では ÷16)
- 2損失が途中で止まって下がらない乱数の種を変える。隠れ層のニューロンを増やす。活性化関数が入っているか確かめる
- 3学習データは高いのにテストだけ低い過学習。データを増やす、ドロップアウト・正則化を使う、テストが最も良い所で止める
- 4自分で書いた逆伝播が正しいか不安小さなネットワークで数値微分と比べる(この記事では差 3.49e-08)
- 5テスト用のデータを学習に混ぜていない最初に分けて、学習中はテストを見ない
ニューラルネットワークと機械学習・ディープラーニング・AIの違い
この節では、よく混同される4つの言葉の関係が分かります。
AI(人工知能)の中に機械学習があり、機械学習の手法の1つがニューラルネットワーク、層を深く重ねたニューラルネットワークを使うのがディープラーニング(深層学習)です。
flowchart TD
A[AI 人工知能] --> B[機械学習<br>データから規則を学ぶ]
B --> C[ニューラルネットワーク]
C --> D[ディープラーニング<br>層が深いもの]
D --> E[生成AI・LLM<br>Transformer など]
| 言葉 | 範囲 | 例 |
|---|---|---|
| AI(人工知能) | 人の知的な作業をコンピュータで行う技術全体 | ルールで動く仕組み、機械学習 |
| 機械学習 | データから規則を学ぶ方法 | 決定木、線形回帰、ニューラルネットワーク |
| ニューラルネットワーク | ニューロンを層につなぎ、重みを学習するモデル | この記事の 2-4-1、64-32-10 |
| ディープラーニング | 隠れ層を何層も重ねたニューラルネットワーク | CNN、Transformer |
| 生成AI・LLM | 文章・画像などを作り出すモデル | GPT、Claude、Gemini |
従来の機械学習
何に注目するか(特徴量)を人が選んで与える
少ないデータ・表のデータでよく使われる
ディープラーニング
画素や文字などの生データから、特徴も自分で学ぶ
大量のデータと計算資源が要る
AWS の解説は、従来の機械学習では人が分析する特徴を選ぶ必要があるのに対し、深層学習は生のデータから特徴を自ら取り出すと説明しています。Google Cloud の解説も、両者の主な違いを層の深さとしています。
ニューラルネットワークの種類:CNN・RNN・Transformer・GANの違い
この節では、代表的なネットワークの種類と、得意なデータの違いが1つの表で分かります。
| 種類 | 仕組みのひとこと | 得意なデータ | 代表例 |
|---|---|---|---|
| 全結合(フィードフォワード) | 前の層の全部と次の層の全部をつなぐ | 表のデータ、小さな分類 | この記事の XOR・手書き数字 |
| CNN(畳み込み) | 小さなフィルターを画像の上でずらして特徴を拾う | 画像、動画 | 画像分類、物体検出 |
| RNN(再帰型) | 1つ前の状態を次の計算に渡し、順番に処理 | 時系列、文章 | LSTM、GRU |
| Transformer | Attention で全部の位置を一度に見比べる | 文章、画像、音声 | GPT、BERT、ViT、Whisper |
| GAN(敵対的生成) | 生成器と識別器を競わせて学ぶ | 画像の生成 | 画像・音声の生成 |
GAN は Goodfellow 氏らが 2014 年に提案した、生成するモデルと本物かを見分けるモデルを同時に訓練する枠組みです。
CNN の畳み込みを1回だけ計算する
CNN の「フィルター」は、小さな重みの表です。真ん中に縦線がある 5×5 の画像に、縦線に反応する 3×3 のフィルターを重ねてずらし、掛けて足した結果です。
img = np.array([[0,0,1,0,0]]*5, dtype=float) # 真ん中に縦の線がある 5x5 の画像
kernel = np.array([[-1,2,-1]]*3, dtype=float) # 縦線に反応する 3x3 のフィルター
out = np.array([[np.sum(img[i:i+3, j:j+3] * kernel) for j in range(3)] for i in range(3)])
畳み込みの結果 (3x3) =
[[-3. 6. -3.]
[-3. 6. -3.]
[-3. 6. -3.]]
縦線の位置だけが 6 と大きくなりました。 CNN はこのフィルターの重みを学習で決め、層を重ねて「線 → 角 → 目や耳 → 顔」のように、より大きな形を拾っていきます。
RNN の限界と、Transformer が解いたこと
RNN は単語を1つずつ順に読むため、長い文では計算を並べて速くすることができず、遠く離れた単語の関係も途中の状態を何度も通らないと伝わりません。論文「Attention Is All You Need」の比較(Table 1、n は文の長さ、d は表現の次元)は次のとおりです。
| 層の種類 | 1層の計算量 | 順番に行う計算 | 離れた2語をつなぐ道のり |
|---|---|---|---|
| Self-Attention | O(n²・d) | O(1) | O(1) |
| 再帰(RNN) | O(n・d²) | O(n) | O(n) |
| 畳み込み(CNN) | O(k・n・d²) | O(1) | O(log_k(n)) |
Self-Attention は、どの2語も1回の計算で直接つながり、全部の位置を同時に計算できます。 代わりに、計算量が文の長さの2乗(n²)で増えます。この2乗は、後の生成AIの節で実際のサイズに直して確かめます。
ニューラルネットワークの用途・利点・課題
この節では、ニューラルネットワークが何に使われ、どんな弱点があるかが分かります。
Google Cloud と AWS の解説に挙がっている主な用途です。
| 分野 | 例 | よく使われる種類 |
|---|---|---|
| 画像認識(コンピュータビジョン) | 製品の外観検査、医用画像の解析、顔認識 | CNN、Transformer(ViT) |
| 自然言語処理 | 機械翻訳、要約、感情分析、チャット | Transformer |
| 音声認識 | 文字起こし、音声アシスタント | Transformer(Whisper など) |
| レコメンド | 閲覧・購買履歴からのおすすめ | 全結合、Transformer |
| 金融・不正検知 | 不正な取引の検出、需要の予測 | 全結合、RNN |
| 自動運転・ロボット | 周りの物体の認識、動きの制御 | CNN、Transformer |
利点
直線でない複雑な関係を学べる
画像・文章・音声の生データをそのまま扱える
データと計算を増やすほど性能が伸びやすい
課題
大量のデータと計算資源(GPU)が要る
なぜその答えになったか説明しにくい
過学習・学習データの偏りをそのまま覚える
文章をベクトル(数値の並び)にして検索に使う仕組みや、手元の文書を答えに使わせる方法は、関連記事「RAGとファインチューニングの違いと使い分け判断基準の早見表」で扱っています。
Attentionとは(英単語attentionとの見分け)
この節では、「attention」という言葉が、英単語としてと AI の用語としてで何を指すかが分かります。
AI の Attention(注意機構)は、入力のうち「どこにどれだけ注目するか」の重みを毎回計算し、その重みで情報を混ぜ合わせる仕組みです。 人が文を読むとき、「それ」が何を指すかを前の単語を見返して決めるのに似ています。
「attention」の2つの意味
AI の Attention は英単語の「注意を向ける」から名付けられた。日本語では「注意機構」「アテンション機構」と訳される
Weblio 辞書では、英単語の attention は「注意、注目、関心」で、発音は「アテンション」、pay attention to(〜に注意を払う)などの形で使われます。この記事で以下に扱うのは、AI の用語のほうです。
Attention はなぜ生まれたか
Attention は、機械翻訳の改良として広まりました。Bahdanau 氏らの論文(2014年)は、それまでの翻訳モデルが原文全体を「決まった長さの1つのベクトル」に詰め込んでいたことが性能の壁になっていると指摘し、訳語を出すたびに原文の関係する部分を探して使う仕組みを提案しました。2017年の論文「Attention Is All You Need」は、RNN も CNN も使わず Attention だけで組んだ Transformer を発表しました。
| 年 | 出来事 | 出典 |
|---|---|---|
| 1986 | 誤差逆伝播法の論文が Nature に掲載 | Rumelhart 氏ら |
| 2014 | 翻訳に Attention を導入 | Bahdanau 氏ら |
| 2017 | Transformer(Attention だけのモデル) | Vaswani 氏ら |
| 2018 | GPT(Transformer のデコーダだけ)、BERT(双方向のエンコーダ) | Radford 氏ら、Devlin 氏ら |
| 2020 | ViT(画像をパッチに分けて Transformer へ) | Dosovitskiy 氏ら |
| 2022 | FlashAttention(Attention の計算を速く)、Whisper(音声認識) | Dao 氏ら、Radford 氏ら |
| 2023 | GQA(Key・Value のヘッドを共有) | Ainslie 氏ら |
Attentionの計算:Query・Key・ValueをNumPyで手計算
この節では、Attention の式を、3単語の例で1行ずつ計算し、重みの行列を実際に見ることができます。
Attention の計算は「Query と Key の似ている度合いを測り、ソフトマックスで重みにし、その重みで Value を混ぜる」の3段です。 論文の式を文字で書くと、Attention(Q, K, V) = softmax(QKᵀ ÷ √d_k) × V です。
| 記号 | 名前 | たとえ(図書館で本を探す) |
|---|---|---|
| Q | Query(クエリ) | 探している内容のメモ |
| K | Key(キー) | 各本の背表紙のラベル |
| V | Value(バリュー) | 本の中身 |
| QKᵀ | 似ている度合い(内積) | メモとラベルがどれだけ合うか |
| softmax | 重み(合計1) | どの本をどれだけ読むかの割合 |
| d_k | Key の次元数 | √d_k で割って値の大きさをそろえる |
flowchart TD
X[単語のベクトル X] --> Q[Query<br>X × W_Q]
X --> K[Key<br>X × W_K]
X --> V[Value<br>X × W_V]
Q --> S[スコア<br>QKの内積 ÷ √d_k]
K --> S
S --> W[重み<br>softmax]
W --> O[出力<br>重み × V]
V --> O
3単語で計算する
「猫」「魚」「食べた」の3単語を、4次元のベクトル(埋め込み)で表します。W_Q・W_K・W_V は、実際のモデルでは学習で決まる重みですが、ここでは手で計算しやすい 0 と 1 で作りました。
import numpy as np
np.set_printoptions(precision=4, suppress=True)
def softmax(z, axis=-1):
e = np.exp(z - z.max(axis=axis, keepdims=True))
return e / e.sum(axis=axis, keepdims=True)
def attention(Q, K, V, mask=None):
d_k = Q.shape[-1]
scores = Q @ K.T / np.sqrt(d_k) # 似ている度合い(内積)÷ √d_k
if mask is not None:
scores = np.where(mask, scores, -np.inf) # 見てはいけない所を -∞ に
weights = softmax(scores) # 各行の合計が1になる重み
return weights @ V, weights, scores
X = np.array([[1, 0, 1, 0], # 猫 の埋め込み(4次元)
[0, 1, 0, 1], # 魚
[1, 1, 0, 0]], dtype=float) # 食べた
W_Q = np.array([[1, 0], [0, 1], [1, 0], [0, 1]], dtype=float)
W_K = np.array([[0, 1], [1, 0], [0, 1], [1, 0]], dtype=float)
W_V = np.array([[1, 0], [0, 1], [0, 0], [0, 0]], dtype=float)
Q, K, V = X @ W_Q, X @ W_K, X @ W_V
out, w, s = attention(Q, K, V)
1. Q・K・V を作る(X に重みを掛ける)
Q =
[[2. 0.]
[0. 2.]
[1. 1.]]
K =
[[0. 2.]
[2. 0.]
[1. 1.]]
V =
[[1. 0.]
[0. 1.]
[1. 1.]]
2. Q と K の内積(行が見る側、列が見られる側)
Q K^T =
[[0. 4. 2.]
[4. 0. 2.]
[2. 2. 2.]]
1行目(猫の Query)と2列目(魚の Key)は、2×2 + 0×0 = 4 です。
3. √d_k(ここでは √2 ≒ 1.4142)で割る
÷√2 =
[[0. 2.8284 1.4142]
[2.8284 0. 1.4142]
[1.4142 1.4142 1.4142]]
4. 行ごとにソフトマックスをとる(これが Attention の重み)
重み softmax =
[[0.0454 0.7679 0.1867]
[0.7679 0.0454 0.1867]
[0.3333 0.3333 0.3333]]
行の合計 = [1. 1. 1.]
1行目を手で確かめます。e⁰ = 1、e^2.8284 ≒ 16.92、e^1.4142 ≒ 4.11、合計 22.03 です。1 ÷ 22.03 ≒ 0.0454、16.92 ÷ 22.03 ≒ 0.7679、4.11 ÷ 22.03 ≒ 0.1867 となり、NumPy の値と一致します。
5. 重みで V を混ぜる(出力)
出力 =
[[0.2321 0.9546]
[0.9546 0.2321]
[0.6667 0.6667]]
猫の出力は 0.0454×[1,0] + 0.7679×[0,1] + 0.1867×[1,1] = [0.2321, 0.9546] です。「猫」の新しいベクトルに、魚の情報が 77% 混ざりました。 こうして各単語のベクトルが、文の中の関係する単語の情報を取り込んだものに置き換わります。実際のモデルでは、どの単語を見るべきかを W_Q・W_K・W_V の学習で身につけます。
| 段 | 計算 | 形(この例) |
|---|---|---|
| 1 | Q = XW_Q、K = XW_K、V = XW_V | 3×4 → 3×2 |
| 2 | スコア = QKᵀ | 3×3(単語数×単語数) |
| 3 | ÷ √d_k | 3×3 |
| 4 | 重み = softmax(行ごと) | 3×3、各行の合計1 |
| 5 | 出力 = 重み × V | 3×2 |
なぜ√d_kで割るのか(実測)
この節では、式の「√d_k で割る」が何のためにあるのかが、実際の数値で分かります。
論文は、d_k が大きいと内積の値が大きくなり、ソフトマックスが「勾配がとても小さい領域」に押しやられるため、1/√d_k を掛けて打ち消す、と説明しています。乱数の Query と10個の Key で、1,000回ずつ確かめました。
d_k | 内積の標準偏差 | 最大の重み 割らない→÷√d_k | 勾配の大きさ 割らない→÷√d_k
4 | 1.74 | 0.493 → 0.306 | 0.336 → 0.340
64 | 7.40 | 0.861 → 0.323 | 0.163 → 0.347
512 | 20.89 | 0.951 → 0.319 | 0.066 → 0.349
割らないと、d_k = 512 では10個のうち1つに平均 0.951 の重みが集中し、勾配の大きさ(ソフトマックスの微分の大きさ)は 0.066 まで小さくなりました。 √d_k で割ると、次元数によらず最大の重みは約 0.32、勾配は約 0.35 でそろいます。勾配が小さいと重みがほとんど更新されず、学習が進みません。
Self-Attention・Multi-Head Attention・マスク・位置エンコーディング
この節では、Transformer の中で Attention がどう使われているかを、4つの部品に分けて実物で見ます。
| 部品 | 何をするか | 実物で確かめたこと |
|---|---|---|
| Self-Attention | Q・K・V を同じ文から作り、文の中の単語同士で見合う | 前の節の計算そのもの |
| エンコーダ・デコーダ Attention | Q はデコーダ、K・V はエンコーダの出力から作る | 論文の翻訳モデル |
| マスク(因果マスク) | 後ろの単語を見えなくする | 右上が 0 になった重み |
| Multi-Head Attention | 小さな Attention を並列に複数回行い、結果をつなぐ | 512次元・8ヘッドの形 |
| 位置エンコーディング | 単語の位置の情報を足す | 足さないと語順が出力に効かない |
Self-Attention と Attention の違い
前の節の例は、Q・K・V をすべて同じ X(同じ文)から作っています。これが Self-Attention(自己注意) です。翻訳のように、Query をデコーダ(訳文を作る側)、Key・Value をエンコーダ(原文を読んだ側)の出力から作る形は、論文では「encoder-decoder attention」と呼ばれ、一般に Cross-Attention とも呼ばれます。
マスク:GPT は後ろの単語を見ない
文章を前から1語ずつ作るモデルは、まだ作っていない後ろの単語を見てはいけません。論文は、見てはいけない位置のソフトマックスへの入力を -∞ にして消す方法を示しています。下三角のマスクをかけた結果です。
因果マスク =
[[1 0 0]
[1 1 0]
[1 1 1]]
マスク後の重み =
[[1. 0. 0. ]
[0.9442 0.0558 0. ]
[0.3333 0.3333 0.3333]]
1語目の「猫」は自分しか見られないので重み 1、2語目の「魚」は「猫」と自分だけを見ています。 e^-∞ = 0 なので、マスクした所の重みはちょうど 0 になります。
Multi-Head Attention:複数の見方を同時に
論文の Transformer は、512次元のベクトルを8つのヘッドに分け、各ヘッドで64次元の Attention を行い、結果をつないで戻します。長さ10の文で、同じ形を NumPy で作りました。
入力 (10, 512) → 1ヘッドの Q (10, 64) → 1ヘッドの重み (10, 10) → 1ヘッドの出力 (10, 64) → 結合 (10, 512) → 出力 (10, 512)
重みの数(W_Q・W_K・W_V・W_O): 1048576
ヘッドごとに別の W_Q・W_K・W_V を持つので、あるヘッドは「主語と述語」、別のヘッドは「代名詞と指す先」のように、違う関係を見られます。1層の Multi-Head Attention の重みは 512×512 の行列4つで、1,048,576 個でした。PyTorch では torch.nn.functional.scaled_dot_product_attention、Keras では keras.layers.MultiHeadAttention(num_heads, key_dim) として用意されています。PyTorch のドキュメントにある参考実装も、query @ key.transpose(-2, -1) * scale_factor にマスクを足し、ソフトマックスをとって @ value する、この記事と同じ手順です(scale を省くと 1/√E)。
位置エンコーディング:Attention だけでは語順が分からない
Attention は単語を「集合」として扱います。単語の順番を入れ替えると、出力も同じように入れ替わるだけでした。
順番を 食べた・猫・魚 にした出力 =
[[0.6667 0.6667]
[0.2321 0.9546]
[0.9546 0.2321]]
元の出力を同じ順に並べたものと一致: True
そこで Transformer は、位置ごとに決まった sin・cos の値(位置エンコーディング)を単語のベクトルに足します。「猫・魚・食べた」と「魚・猫・食べた」で、「食べた」の出力を比べました。
PEなし 猫・魚・食べた → 「食べた」の出力 [0.7259 0.7259 0.2741 0.2741]
PEなし 魚・猫・食べた → 「食べた」の出力 [0.7259 0.7259 0.2741 0.2741]
PEあり 猫・魚・食べた → 「食べた」の出力 [1.3464 1.0039 0.2236 1.3471]
PEあり 魚・猫・食べた → 「食べた」の出力 [1.5532 0.8104 0.4124 1.1722]
位置エンコーディングが無いと、「猫が魚を」と「魚が猫を」の区別がつきません。 足すと、語順で出力が変わりました。
Transformerの構造とAttentionの計算量
この節では、Attention が Transformer の中のどこにあり、文が長くなると何が重くなるかが分かります。
Transformer の1層は、Multi-Head Attention と、単語ごとの全結合のネットワーク(Feed-Forward)の2つでできていて、それぞれに残差接続(入力を出力に足し戻す)と正規化が付きます。この層を何段も重ねます。論文の Transformer は、エンコーダとデコーダをそれぞれ6層重ねていました。
flowchart TD
T[トークン] --> E[埋め込み+位置エンコーディング]
E --> A[Multi-Head Self-Attention<br>単語同士で情報を混ぜる]
A --> F[Feed-Forward<br>単語ごとに変換]
F -->|これを N 層くり返す| A
F --> P[次のトークンの確率<br>softmax]
| 部分 | 役割 | 構造の違いの例 |
|---|---|---|
| エンコーダ | 入力の文全体を読んで表現にする | BERT(エンコーダだけ・左右両方を見る) |
| デコーダ | マスク付きで前から順に出力を作る | GPT(デコーダだけ) |
| エンコーダ+デコーダ | 読んだ内容を見ながら別の系列を作る | 論文の翻訳モデル、Whisper |
計算量:文の長さの2乗で増える
Attention の重みの行列は「トークン数 × トークン数」です。1ヘッド・1層分を16ビットの数値でそのまま持つとした場合のサイズを計算しました。
トークン数 | 重みの行列の要素数 | 16ビットでのサイズ
512 | 262,144 | 0.5 MiB
4,096 | 16,777,216 | 32.0 MiB
32,768 | 1,073,741,824 | 2 GiB
131,072 | 17,179,869,184 | 32 GiB
文の長さが8倍になると、重みの行列は64倍になります。 そのため長い文脈を扱うモデルでは、計算の工夫が使われています。FlashAttention は、行列を小分けにして GPU の高速なメモリ(SRAM)の中で計算し、遅いメモリ(HBM)との読み書きを減らす方法で、近似ではなく同じ結果を出します。
Self-Attentionと生成AI(LLM)の関係
この節では、ChatGPT や Claude などの生成AI(LLM)の中で、Self-Attention がどう働いているかが分かります。
LLM(大規模言語モデル)の多くは、Transformer のデコーダを何十層も重ねたニューラルネットワークで、「次のトークン(単語のかけら)の確率」を出すことを繰り返して文章を作ります。 OpenAI の最初の GPT の論文は、マスク付きの Self-Attention を持つ12層のデコーダだけの Transformer(768次元・12ヘッド・512トークンの系列で学習)を使ったと書いています。
flowchart TD
I[ここまでの文章<br>トークン列] --> M[Transformer<br>マスク付き Self-Attention]
M --> P[次のトークンの確率]
P --> S[1つ選ぶ]
S -->|文章の最後に足して<br>もう一度| I
この記事で動かした部品と、LLM の中身の対応です。
| この記事で動かしたもの | LLM の中での役割 |
|---|---|
| ニューロン・活性化関数(GELU など) | Feed-Forward 層の計算 |
| 誤差逆伝播・勾配降下法 | 大量の文章で、次のトークンを当てるように学習 |
| ソフトマックス | Attention の重みと、次のトークンの確率 |
| 因果マスク | 前の単語だけを見て次を予測する |
| Multi-Head Attention | 文の中の関係を複数の見方で取り込む |
| 位置エンコーディング | 語順の情報を入れる |
LLM でよく聞く Attention の工夫
| 名前 | 何をするか | 出典 |
|---|---|---|
| FlashAttention | 結果は同じまま、GPU のメモリの読み書きを減らして速くする | Dao 氏ら(2022年) |
| GQA(Grouped-Query Attention) | 複数の Query のヘッドで Key・Value のヘッドを共有し、推論を速くする | Ainslie 氏ら(2023年) |
| MQA(Multi-Query Attention) | Key・Value のヘッドを1つだけにする(GQA の特別な場合) | GQA の論文 |
| Mixture-of-Experts(MoE) | Feed-Forward 側を多数の「専門家」に分け、入力ごとに一部だけ使う | Shazeer 氏ら(2017年) |
PyTorch の scaled_dot_product_attention にも、is_causal(因果マスク)と enable_gqa(GQA)の引数があります。
LLM が一度に読める長さ(コンテキスト)とトークンの関係は、関連記事「コンテキストとは|IT・プログラミング・AIでの意味を分野別に実演」で扱っています。手元の PC で LLM を動かす方法は、関連記事「Ollamaの使い方|ローカルLLMのコマンド一覧とAPIの呼び方」で扱っています。LLM に道具を使わせて作業させる仕組みは、関連記事「AIエージェントとは|仕組みとワークフローとの違い・作り方入門」で扱っています。
ニューラルネットワークとAttentionを学ぶ順番
この節では、この記事の次に何を学ぶとよいかが、順番で分かります。
NumPy で行列の計算に慣れる
この記事のコードは、ほぼ @(行列の掛け算)と sum・exp だけです。形(shape)を print しながら追うと理解が早まります。
小さなネットワークを手で書く
XOR と手書き数字のコードを、隠れ層の数・学習率・活性化関数を変えて動かし、損失の変わり方を見ます。
PyTorch などのライブラリに移る
自動微分があるので、逆伝播を手で書かずに済みます。手で書いた計算と同じになるかを比べると、ライブラリの中身が見えます。
Attention と Transformer を読む
この記事の手計算を、論文の図と式に重ねて読みます。マスク・Multi-Head・位置エンコーディングの順がつかみやすい順番です。
LLM を API やローカルで使う
中身の仕組みが分かると、トークン数・コンテキストの長さ・料金の関係が理解しやすくなります。
損失や正解率をグラフにして見るときは、関連記事「matplotlibの使い方と日本語文字化け対策|OS別・Colab・3.12対応」で扱っています。
よくある質問
Q. ニューラルネットワークとは、簡単に言うと何ですか? A. 入力に重みを掛けて足し、関数で変換する計算を層に重ねたもので、正解とのずれから重みを自動で直して学ぶ仕組みです。この記事では、17個の数値を学習するネットワークが XOR を、2,410個のネットワークが手書き数字を学びました。
Q. ニューラルネットワークとディープラーニングの違いは? A. ディープラーニングは、隠れ層を何層も重ねた(深い)ニューラルネットワークを使う方法です。ニューラルネットワークの中に、層の深いものとしてディープラーニングがある、という関係です。
Q. ニューラルネットワークと機械学習の違いは? A. 機械学習は「データから規則を学ぶ方法」の総称で、ニューラルネットワークはその手法の1つです。決定木や線形回帰も機械学習ですが、ニューラルネットワークではありません。
Q. パーセプトロンとは何ですか?
A. 入力に重みを掛けて足し、ステップ関数で0か1を出すニューロン1個のモデルです。AND は表せますが、XOR のように直線1本で分けられない問題は表せません。隠れ層を足した多層のものは多層パーセプトロン(MLP)と呼ばれ、scikit-learn の MLPClassifier もこの名前です。
Q. 活性化関数はなぜ必要ですか? A. 活性化関数が無いと、層を何枚重ねても全体が1つの直線の計算になり、複雑な形を表せないためです。活性化関数を外したネットワークは、隠れ層があっても XOR の損失が 0.6931 から下がりませんでした。
Q. 誤差逆伝播法(バックプロパゲーション)とは? A. 出力の誤差を、微分の連鎖律を使って出力層から入力層へさかのぼり、すべての重みの勾配を一度に求める方法です。この記事では、手で書いた逆伝播の勾配が数値微分と小数第10位まで一致しました。
Q. ニューラルネットワークは Python で作れますか?
A. 作れます。この記事のように NumPy だけでも書けますし、scikit-learn の MLPClassifier、深いモデルなら PyTorch や Keras がよく使われます。同じ形のネットワークを NumPy と scikit-learn で作ると、どちらもテスト正解率 98.61% でした。
Q. attention の意味は? A. 英単語としては「注意・注目・関心」です。AI の用語としては、入力のどこにどれだけ注目するかの重みを計算し、その重みで情報を混ぜる仕組み(注意機構)を指します。
Q. Attention 機構の Query・Key・Value とは? A. Query は「探している内容」、Key は「各単語の見出し」、Value は「各単語の中身」です。Query と Key の内積で似ている度合いを測り、ソフトマックスで重みにして、Value を混ぜます。
Q. Self-Attention と Attention の違いは? A. Self-Attention は、Query・Key・Value をすべて同じ文から作る Attention です。翻訳で訳文側から原文側を見るように、別の系列を見るものはエンコーダ・デコーダ Attention(Cross-Attention)と呼ばれます。
Q. Multi-Head Attention とは? A. Attention を小さく分けて複数(論文では8つ)並べ、それぞれ別の重みで計算してから結果をつなぐ仕組みです。ヘッドごとに違う関係を見られます。
Q. Transformer と ChatGPT などの生成AIの関係は? A. GPT 系のモデルは、Transformer のデコーダ(マスク付きの Self-Attention を持つ部分)を重ねたもので、次のトークンの確率を出すことを繰り返して文章を作ります。
Q. 「Attention Is All You Need」とは? A. 2017年に発表された、Transformer を提案した論文の題名です。RNN や CNN を使わず、Attention だけで翻訳の性能を上げられることを示しました。
Q. LLM が間違ったことを言うのはなぜですか? A. LLM は「次に来そうなトークン」の確率を出すモデルで、本体には事実を確かめる仕組みがないためです。手元の資料を検索して答えに使わせる RAG などで補います。
まとめ
- ニューラルネットワークは、重み付きの和と活性化関数を層に重ね、誤差逆伝播と勾配降下法で重みを直して学ぶ。
- 隠れ層も活性化関数も無いと XOR は解けず、損失は 0.6931 のまま。2-4-1 のネットワークでは損失が 0.6712 → 0.0009 まで下がった。
- 64-32-10 のネットワークは、手書き数字のテスト画像で 98.61% を当てた。学習率が大きすぎると発散し、データが少ないと過学習した。
- CNN は画像、RNN は順番のあるデータ、Transformer は Attention で全部の位置を同時に見比べる。
- Attention は softmax(QKᵀ/√d_k)V。√d_k で割らないと、d_k = 512 で重みが1か所に偏り、勾配が約5分の1になった。
- Self-Attention にマスク・Multi-Head・位置エンコーディングを組み合わせたものが Transformer で、LLM はそのデコーダを重ねて次のトークンを予測している。
参考・出典
確認日はいずれも 2026年10月22日です。
- Vaswani et al.「Attention Is All You Need」(arXiv:1706.03762):https://arxiv.org/abs/1706.03762
- Bahdanau et al.「Neural Machine Translation by Jointly Learning to Align and Translate」(arXiv:1409.0473):https://arxiv.org/abs/1409.0473
- Rumelhart, Hinton, Williams「Learning representations by back-propagating errors」(Nature 323, 1986。NASA ADS):https://ui.adsabs.harvard.edu/abs/1986Natur.323..533R/abstract
- Radford et al.「Improving Language Understanding by Generative Pre-Training」(OpenAI):https://cdn.openai.com/research-covers/language-unsupervised/language_understanding_paper.pdf
- Devlin et al.「BERT: Pre-training of Deep Bidirectional Transformers for Language Understanding」(arXiv:1810.04805):https://arxiv.org/abs/1810.04805
- Dosovitskiy et al.「An Image is Worth 16x16 Words」(arXiv:2010.11929):https://arxiv.org/abs/2010.11929
- openai/whisper(GitHub):https://github.com/openai/whisper
- Goodfellow et al.「Generative Adversarial Networks」(arXiv:1406.2661):https://arxiv.org/abs/1406.2661
- Shazeer et al.「Outrageously Large Neural Networks: The Sparsely-Gated Mixture-of-Experts Layer」(arXiv:1701.06538):https://arxiv.org/abs/1701.06538
- Dao et al.「FlashAttention: Fast and Memory-Efficient Exact Attention with IO-Awareness」(arXiv:2205.14135):https://arxiv.org/abs/2205.14135
- Ainslie et al.「GQA: Training Generalized Multi-Query Transformer Models from Multi-Head Checkpoints」(arXiv:2305.13245):https://arxiv.org/abs/2305.13245
- PyTorch 2.14 documentation「torch.nn.functional.scaled_dot_product_attention」:https://docs.pytorch.org/docs/2.14/generated/torch.nn.functional.scaled_dot_product_attention.html
- Keras「MultiHeadAttention layer」:https://keras.io/api/layers/attention_layers/multi_head_attention/
- scikit-learn「load_digits」:https://scikit-learn.org/stable/modules/generated/sklearn.datasets.load_digits.html
- Google Cloud「ニューラル ネットワークとは」:https://cloud.google.com/discover/what-is-a-neural-network?hl=ja
- AWS「ニューラルネットワークとは何ですか?」:https://aws.amazon.com/jp/what-is/neural-network/
- Weblio 辞書「Attention」:https://www.weblio.jp/content/Attention
本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。
(記載例)出典:株式会社RJC「ニューラルネットワークとは|仕組み・学習・AttentionをNumPyで実演」
株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。
WE ARE HIRING
RJCで一緒に開発しながら、
成長を楽しみませんか?
RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!
- 127日年間休日
- 12時間平均残業時間
- 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!
ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。