はじめに: ニューラル ネットワークの学習方法
線形代数と 言語 機械学習、微分積分学、 彼の 学習エンジン。モデルが予測を改善するたびに、その予測が改善されます と呼ばれるプロセスのおかげで 勾配降下法、完全にデリバティブに基づいており、 グラデーション。計算がなければ、ニューラル ネットワークは学習できません。
この記事ではその方法について説明します 偏導関数 彼らは私たちにどの方向を指しているのかを教えてくれます などの重みを変更します。 連鎖ルール バックプロパゲーションを可能にする、そしてその方法 基本的にすべては NumPy で実装されます。
何を学ぶか
- デリバティブ: 変化率の概念
- 偏導関数と勾配ベクトル
- 連鎖則: 導関数の作り方 (バックプロパゲーションの核心)
- 計算グラフ: 前方パスと後方パス
- ヤコビアンとヘシアン: 高次情報
- NumPy でのバックプロパゲーションの手動実装
デリバティブ: 変化率
La 派生関数 関数の f(x) ある時点で彼は私たちに言います 関数の値がどのくらいの速さで変化するか x の変更 無限微量:
直感: 導関数と スロープ ある点での関数の。 正の場合、関数は上昇しています。負の場合は低下しています。 if とゼロの場合、私たちは 静止点 (最小値、最大値、または鞍点)。
深層学習における一般的な活性化関数の導関数:
それは重要だから: シグモイドの導関数の最大値は 0.25 (次の場合) x = 0)。これは、各レイヤーでグラデーションが乗算されることを意味します。 最大係数 0.25 で、次のような有名な問題が発生します。 消失勾配 で 深いネットワーク。これが、ReLU (導関数 = 1 あたり 1) である理由です。 x > 0)とお気に入り。
偏導関数と勾配
関数が複数の変数に依存する場合 (すべての重みに依存する損失関数など)、 計算してみましょう 偏導関数: 各変数に関する導関数、 他は固定したままにします。
関数の場合 f(x_1, x_2, \\ldots, x_n), il 勾配 すべての偏導関数のベクトル:
重要な洞察: のグラデーションポイント 最大の成長の方向性 機能の。損失を最小限に抑えるために、次の方向に進みます。 反対 グラデーションに:
どこ \\年 そして 学習率 e L(\\シータ) 損失関数。これが基本的な式です 勾配降下法.
import numpy as np
# Esempio: f(x, y) = x^2 + 3xy + y^2
# Gradiente: [2x + 3y, 3x + 2y]
def f(x, y):
return x**2 + 3*x*y + y**2
def gradient_f(x, y):
df_dx = 2*x + 3*y
df_dy = 3*x + 2*y
return np.array([df_dx, df_dy])
# Punto di partenza
x, y = 3.0, 2.0
print(f"f({x}, {y}) = {f(x, y)}")
print(f"Gradiente: {gradient_f(x, y)}")
# Gradient descent
lr = 0.1
for step in range(20):
grad = gradient_f(x, y)
x -= lr * grad[0]
y -= lr * grad[1]
if step % 5 == 0:
print(f"Step {step}: x={x:.4f}, y={y:.4f}, f={f(x, y):.6f}")
連鎖ルール: バックプロパゲーションの核心
La 連鎖ルール (連鎖律)とそれを可能にする数学的原理 ディープニューラルネットワークのトレーニング。複合関数がある場合 y = f(g(x))、導関数は次のとおりです。
複数の複合関数を搭載 y = f_1(f_2(f_3(x))):
ニューラル ネットワークはまさに機能の組み合わせです。各層が変換を適用します。 線形の後に非線形のアクティベーションが続きます。連鎖ルールを使用すると、損失がどのように発生するかを計算できます。 は各重みに対して変化し、すべての層を逆順に通過します。
例: 単一ニューロンでのバックプロパゲーション
MSE 損失のある単一のニューロンを考えてみましょう。
に対する勾配 w 連鎖ルールを使用すると、次のようになります。
どこ z = wx + b。連鎖内の各用語には意味があります 正確: エラー、アクティベーション感度、および入力。
import numpy as np
def sigmoid(x):
return 1 / (1 + np.exp(-x))
def sigmoid_deriv(x):
s = sigmoid(x)
return s * (1 - s)
# Singolo neurone: forward e backward pass
x = 2.0 # input
y = 1.0 # target
w = 0.5 # peso
b = 0.1 # bias
lr = 0.1
for epoch in range(50):
# Forward pass
z = w * x + b
y_hat = sigmoid(z)
loss = (y - y_hat) ** 2
# Backward pass (chain rule)
dL_dyhat = 2 * (y_hat - y) # dL/d(y_hat)
dyhat_dz = sigmoid_deriv(z) # d(y_hat)/dz
dz_dw = x # dz/dw
dz_db = 1.0 # dz/db
dL_dw = dL_dyhat * dyhat_dz * dz_dw # Chain rule completa
dL_db = dL_dyhat * dyhat_dz * dz_db
# Aggiorna pesi
w -= lr * dL_dw
b -= lr * dL_db
if epoch % 10 == 0:
print(f"Epoch {epoch}: loss={loss:.6f}, w={w:.4f}, b={b:.4f}")
計算グラフ: 前方と後方の視覚化
Un 計算グラフ 関数を演算ツリーとして表します 初歩的な。各ノードは単純な演算 (和、積、アクティブ化) を実行します。 逆方向に渡す 連鎖ルールのおかげで、グラフ内を逆の順序でグラデーション フローが通過します。
考えてみましょう L = (\\sigma(w_1 x_1 + w_2 x_2 + b) - y)^2:
- フォワード: z_1 = w_1 x_1, z_2 = w_2 x_2, s = z_1 + z_2 + b, a = \\シグマ, L = (a - y)^2
- 後方へ:計算してみましょう \\frac{\\部分 L}{\\部分 a}、 それから \\frac{\\部分 L}{\\部分 s}、 それから \\frac{\\部分 L}{\\部分 w_1} e \\frac{\\部分 L}{\\部分 w_2}
これはまさに PyTorch と TensorFlow が自動的に行うことです。自動 差別化.
ヤコビアンとヘシアン
Il ヤコビアン 勾配をベクトル関数に一般化します。もし \\mathbf{f}: \\mathbb{R}^n \\to \\mathbb{R}^m、ヤコビアンと行列 m \\times n:
L'ヘッセ行列 と二次導関数の行列、およびに関する情報が得られます。 曲率 損失関数の:
ヘッセ行列の固有値によって、臨界点が臨界点であるかどうかが決まります。 最小 (すべて肯定的)、 最大 (すべて否定的)、または サドルポイント (混合)。の問題では、 ニューラル ネットワークの最適化では、鞍点は極小点よりもはるかに一般的です。
完全なバックプロパゲーション: 2 層ネットワーク
import numpy as np
np.random.seed(42)
# Dataset XOR (non-linearmente separabile)
X = np.array([[0, 0], [0, 1], [1, 0], [1, 1]])
y = np.array([[0], [1], [1], [0]])
# Inizializzazione pesi
W1 = np.random.randn(2, 4) * 0.5 # (2 input, 4 hidden)
b1 = np.zeros((1, 4))
W2 = np.random.randn(4, 1) * 0.5 # (4 hidden, 1 output)
b2 = np.zeros((1, 1))
def sigmoid(x):
return 1 / (1 + np.exp(-np.clip(x, -500, 500)))
lr = 1.0
for epoch in range(10000):
# === FORWARD PASS ===
z1 = X @ W1 + b1 # (4, 2) @ (2, 4) = (4, 4)
a1 = sigmoid(z1) # Attivazione hidden
z2 = a1 @ W2 + b2 # (4, 4) @ (4, 1) = (4, 1)
a2 = sigmoid(z2) # Output
# Loss: MSE
loss = np.mean((y - a2) ** 2)
# === BACKWARD PASS (Chain Rule) ===
m = X.shape[0]
# Gradiente output layer
dL_da2 = 2 * (a2 - y) / m
da2_dz2 = a2 * (1 - a2) # Derivata sigmoid
dz2 = dL_da2 * da2_dz2 # (4, 1)
dW2 = a1.T @ dz2 # (4, 4).T @ (4, 1) = (4, 1)
db2 = np.sum(dz2, axis=0, keepdims=True)
# Gradiente hidden layer (chain rule continua!)
da1 = dz2 @ W2.T # (4, 1) @ (1, 4) = (4, 4)
dz1 = da1 * (a1 * (1 - a1)) # Derivata sigmoid
dW1 = X.T @ dz1 # (2, 4).T @ (4, 4) = (2, 4)
db1 = np.sum(dz1, axis=0, keepdims=True)
# === AGGIORNAMENTO PESI ===
W2 -= lr * dW2
b2 -= lr * db2
W1 -= lr * dW1
b1 -= lr * db1
if epoch % 2000 == 0:
print(f"Epoch {epoch}: Loss = {loss:.6f}")
# Risultato finale
predictions = np.round(a2, 2)
print(f"\nPredizioni finali:\n{predictions.flatten()}")
print(f"Target: {y.flatten()}")
勾配のチェック: 勾配を確認する
バックプロパゲーションが正しく実装されていることを確認するために、次のように比較できます。 それらを使用した分析勾配 数値 有限差分を使用して計算されます。
con \\イプシロン \\約 10^{-7}。勾配間の相対的な差 分析的および数値的値は以下である必要があります 10^{-5}.
import numpy as np
def numerical_gradient(f, params, idx, epsilon=1e-7):
"""Calcola gradiente numerico per verifica."""
original = params[idx].copy()
params[idx] = original + epsilon
loss_plus = f()
params[idx] = original - epsilon
loss_minus = f()
params[idx] = original
return (loss_plus - loss_minus) / (2 * epsilon)
# Esempio semplice: f = (w*x - y)^2
w = np.array([0.5])
x, y_true = 2.0, 3.0
def compute_loss():
return (w[0] * x - y_true) ** 2
# Gradiente analitico
grad_analytical = 2 * (w[0] * x - y_true) * x
# Gradiente numerico
grad_numerical = numerical_gradient(compute_loss, [w], 0)
print(f"Analitico: {grad_analytical:.8f}")
print(f"Numerico: {grad_numerical:.8f}")
print(f"Diff relativa: {abs(grad_analytical - grad_numerical) / max(abs(grad_analytical), 1e-8):.2e}")
概要と ML との関係
覚えておくべき重要なポイント
- デリバティブ: 変化率を測定し、関数の傾きを示します
- 勾配 \\nabla L: 損失が最大増加する方向を指します。
- 勾配降下法: \\theta \\leftarrow \\theta - \\eta \\nabla L - 勾配とは逆に移動します
- チェーンルール: 関数合成を通じて勾配を計算できます。
- バックプロパゲーション: ネットワークの計算グラフへの連鎖規則の適用
- 消失勾配: シグモイドの最大導関数は 0.25、ReLU は導関数 1 で解決します。
次の記事で: 探索してみます 確率と統計 ML用。ベイズの定理、分布、最尤推定、およびその方法について見ていきます。 予測の不確実性を定量化します。







