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

bookBackpropagationの実装

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

一般的なアプローチ

順伝播では、各層 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