Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
学ぶ バックプロパゲーション実装 | ニューラルネットワークをゼロから構築
Pythonによるニューラルネットワーク入門

バックプロパゲーション実装

メニューを表示するにはスワイプしてください

一般的なアプローチ

順伝播では、各層 ll が前の層の出力 al1a^{l-1} を入力として受け取り、自身の出力を計算。したがって、forward() クラスの Layer メソッドは、前の出力ベクトルのみをパラメータとして受け取り、その他の必要な情報はクラス内に保持。

逆伝播では、各層 lldalda^l のみを使って勾配を計算し、dal1da^{l-1} を返す。そのため、backward() メソッドは dalda^l ベクトルをパラメータとして受け取り、その他の必要な情報は Layer クラス内にすでに保存されている。

順伝播と逆伝播

活性化関数の導関数

活性化関数の導関数は逆伝播で必要となるため、ReLUsigmoid などの活性化関数は、単独の関数ではなくクラスとして実装することが推奨。この構造により、両方の要素を明確に定義可能:

  1. 活性化関数本体__call__() メソッドで実装し、Layer クラス内で self.activation(z) のように直接適用可能;
  2. その導関数derivative() メソッドで実装し、逆伝播時に self.activation.derivative(z) で効率的に計算可能。

活性化関数をオブジェクトとして表現することで、異なる層への受け渡しや、順伝播・逆伝播の両方で動的に適用しやすくなる。

ReLu

ReLU活性化関数の導関数は以下の通りであり、ziz_iは事前活性化ベクトルzzの要素を表します:

f(zi)={1,zi>00,zi0f'(z_i) = \begin{cases} 1, z_i > 0\\ 0, z_i \le 0 \end{cases}
class ReLU:
    def __call__(self, z):
        return np.maximum(0, z)

    def derivative(self, z):
        return (z > 0).astype(float)

シグモイド

シグモイド活性化関数の導関数は以下の通りです:

f(zi)=f(zi)(1f(zi))f'(z_i) = f(z_i) \cdot (1 - f(z_i))
class Sigmoid:
    def __call__(self, x):
        return 1 / (1 + np.exp(-z))

    def derivative(self, z):
        sig = self(z)
        return sig * (1 - sig)

両方の活性化関数において、演算はベクトル全体zzおよびその導関数に適用されます。NumPyは自動的に要素ごとに計算を行い、ベクトルの各要素が独立して処理されます。

例えば、ベクトルzz3つの要素を含む場合、導関数は次のように計算されます:

f(z)=f([z1z2z3])=[f(z1)f(z2)f(z3)]f'(z) = f'\left( \begin{bmatrix} z_1\\ z_2\\ z_3 \end{bmatrix} \right) = \begin{bmatrix} f'(z_1)\\ f'(z_2)\\ f'(z_3) \end{bmatrix}

backward() メソッド

backward()メソッドは、以下の式を用いて勾配を計算します:

dzl=dalfl(zl)dWl=dzl(al1)Tdbl=dzldal1=(Wl)Tdzl\begin{aligned} dz^l &= da^l \odot f'^l(z^l)\\ dW^l &= dz^l \cdot (a^{l-1})^T\\ db^l &= dz^l\\ da^{l-1} &= (W^l)^T \cdot dz^l \end{aligned}

a^{l-1}およびzlz^lは、それぞれinputsクラスのoutputs属性とLayer属性として保存されます。活性化関数ffactivation属性として保存されます。

必要なすべての勾配が計算された後、重みバイアスは、これ以上計算に必要ないため更新できます:

Wl=WlαdWlbl=blαdbl\begin{aligned} W^l &= W^l - \alpha \cdot dW^l\\ b^l &= b^l - \alpha \cdot db^l \end{aligned}

したがって、learning_rateα\alpha)はこの手法のもう一つのパラメータ。

def backward(self, da, learning_rate):
    dz = ...
    d_weights = ...
    d_biases = ...
    da_prev = ...

    self.weights -= learning_rate * d_weights
    self.biases -= learning_rate * d_biases

    return da_prev
Note
ノート

* 演算子は要素ごとの乗算を行い、np.dot() 関数は NumPyドット積を計算。.T 属性は配列の転置。

question mark

backward() クラスの Layer メソッドがバックプロパゲーション中に果たす役割として最も適切な説明はどれか?

正しい答えを選んでください

すべて明確でしたか?

どのように改善できますか?

フィードバックありがとうございます!

セクション 2.  8

AIに質問する

expand

AIに質問する

ChatGPT

何でも質問するか、提案された質問の1つを試してチャットを始めてください

セクション 2.  8
some-alt