human
5.5.2 Sigmoidレイヤ
シグモイド関数は次式で表される。
$$
y=\frac{1}{1+exp(-x)}
$$
計算グラフでは「×」「exp」「+」「/」の順でのノードが連結する。
逆伝播の流れを順に沿って見ていく。

ステップ1
「/」ノードは$y=\frac{1}{x}$を表す(上記式で「1+exp(-x)」を分母にするところから分かる)が、この微分は解析的に次式のようになる。
$$
\frac{\delta y}{\delta x} = -\frac{1}{x^{2}} \
= -y^{2}
$$

ステップ2
「+」ノードは上流の値を下流にそのまま流すだけ。

ステップ3
「exp」ノードは$y=exp(x)$であり、微分は以下式で表される。
$$
\frac{\delta y}{\delta x}= exp(x)
$$
計算グラフでは順伝播時の出力を乗算して下流へ伝搬する。($exp(-x)$)

ステップ4
「×」ノードは順伝播時の値をひっくり返して乗算する。(-1)

以上によりSigmoidの逆伝播の出力は以下となる。
$$
\frac{\delta L}{\delta y}y^{2}exp(-x) \
=\frac{\delta L}{\delta y}\frac{1}{(1+exp(-x))^{2}}exp(-x) \
=\frac{\delta L}{\delta y}\frac{1}{1+exp(-x)} \frac{exp(-x)}{1+exp(-x)} \
=\frac{\delta L}{\delta y}y(1-y)
$$
これによりSigmoidレイヤの逆伝播は順伝播の出力だけから求めることが出来る。
実装は以下となる。"
Please write code following the instructions in jupyter notebook style.
assistant
#Here is code to 5.

class Sigmoid:
    def __init__(self):
        self.out = None

    def forward(self, x):
        out = 1 / (1 + np.exp(-x))
        self.out = out
        return out

    def backward(self, dout):
        dx = dout * (1.0 - self.out) * self.out

        return dx