技術をかじる猫

適当に気になった技術や言語、思ったこと考えた事など。

RNN を考える

RNN って何かというと Recurrent Neural Network 再起構造型ニューラルネットワークの意味。
再帰構造型の意味って何かというと、前回のニューロンの出力と現在の入力を引数にして「前回の状態を含めて判断する」ニューラルネットのこと。

普通、ニューラルネットを扱うとき、活性関数を  f 学習データを  X とし、重み  W バイアス  B とすると ニューロンの作りは


U = XW + B \\
Y = f(U)

ということになる。
ただしこれはその時点でのデータとしたときの問題で、前の状態が次の状態に影響するようなデータには正常に適用できない。

そこで、RNN ではデータ  X のある時点のデータを  X^{(t)} と仮定して


U^{(t)} = X^{(t)}W + Y^{(t - 1)}V + B \\
Y^{(t)} = f(U^{(t)})

こんな感じに前回のニューロン応答に追加の重み  V を加えて取り込む動作をする。

少し展開するとこんな感じ


U^{(t)} = X^{(t)}W + Y^{(t - 1)}V + B \\
= \left(\begin{array}{xxxx}
    x^{(t)}_{11} & x^{(t)}_{12} & ... & x^{(t)}_{1m} \\
    x^{(t)}_{21} & x^{(t)}_{22} & ... & x^{(t)}_{2m} \\
    ...          & ...          & ... & ...          \\
    x^{(t)}_{h1} & x^{(t)}_{h2} & ... & x^{(t)}_{hm}
  \end{array}\right)
  \left(\begin{array}{xxxx}
    w_{11} & w_{12} & ... & w_{1m} \\
    w_{21} & w_{22} & ... & w_{2m} \\
    ...    & ...    & ... & ...    \\
    w_{n1} & w_{n2} & ... & w_{nm}
  \end{array}\right) + 
  \left(\begin{array}{xxxx}
    y^{(t-1)}_{11} & y^{(t-1)}_{12} & ... & y^{(t-1)}_{1n} \\
    y^{(t-1)}_{21} & y^{(t-1)}_{22} & ... & y^{(t-1)}_{2n} \\
    ...            & ...            & ... & ...            \\
    y^{(t-1)}_{h1} & y^{(t-1)}_{h2} & ... & y^{(t-1)}_{hn}
  \end{array}\right)
  \left(\begin{array}{xxxx}
    v_{11} & v_{12} & ... & v_{1n} \\
    v_{21} & v_{22} & ... & v_{2n} \\
    ...    & ...    & ... & ...    \\
    v_{n1} & v_{n2} & ... & v_{nn}
  \end{array}\right) +
  \left(\begin{array}{xxxx}
    b_1 & b_2 & ... & b_n \\
    b_1 & b_2 & ... & b_n \\
    ... & ... & ... & ... \\
    b_1 & b_2 & ... & b_n \\
  \end{array}\right) \\
= \left(\begin{array}{xxxx}
    \sum^m_{k=1} x^{(t)}_{1k} w_{k1} + \sum^m_{k=1} y^{(t-1)}_{1k} v_{k1} +b_1 & \sum^m_{k=1} x^{(t)}_{1k} w_{k2} + \sum^m_{k=1} y^{(t-1)}_{1k} v_{k2} +b_2 & ... & \sum^m_{k=1} x^{(t)}_{1k} w_{kn} + \sum^m_{k=1} y^{(t-1)}_{1k} v_{kn} + b_n \\
    \sum^m_{k=1} x^{(t)}_{2k} w_{k1} + \sum^m_{k=1} y^{(t-1)}_{2k} v_{k1} +b_1 & \sum^m_{k=1} x^{(t)}_{2k} w_{k2} + \sum^m_{k=1} y^{(t-1)}_{2k} v_{k2} +b_2 & ... & \sum^m_{k=1} x^{(t)}_{2k} w_{kn} + \sum^m_{k=1} y^{(t-1)}_{2k} v_{kn} + b_n \\
    ...          & ...          & ... & ...          \\
    \sum^m_{k=1} x^{(t)}_{hk} w_{k1} + \sum^m_{k=1} y^{(t-1)}_{hk} v_{k1} +b_1 & \sum^m_{k=1} x^{(t)}_{hk} w_{k2} + \sum^m_{k=1} y^{(t-1)}_{hk} v_{k2} +b_2 & ... & \sum^m_{k=1} x^{(t)}_{hk} w_{kn} + \sum^m_{k=1} y^{(t-1)}_{hk} v_{kn} + b_n \\
  \end{array}\right)

RNN の活性関数には  tanh をよく使われてる。
これはこんな関数らしい


y = f(u) = \frac{ exp(u) - exp(-u) }{ exp(u) + exp(-u) }

もう少しシンプルな書き方で一般化して


u^{(t)} = \sum^m_{k=1} x^{(t)}_{k} w_{k} + \sum^m_{k=1} y^{(t-1)}_{k} v_{k} + b \\
y^{(t)} = f(u^{(t)})

逆伝播

これを微分するのかー(汗
連鎖律(下式)使って


\frac{\partial E}{\partial w_i} = \sum^r_{t=1} \frac{\partial E}{\partial u^{(t)}} \frac{\partial u^{(t)}}{\partial w_i}

で、次の様に定義して


\delta^{(t)} = \frac{\partial E}{\partial u^{(t)}} \\
= \frac{\partial E}{\partial y^{(t)}} \frac{\partial y^{(t)}}{\partial u^{(t)}}

 \frac{\partial E}{\partial y^{(t)}} は一つ前の出力層から拾ってこれて、  \frac{\partial y^{(t)} }{\partial u^{(t)} } は活性関数の偏微分

 w から偏微分するとした場合


u^{(t)} = \sum^m_{k=1} x^{(t)}_{k} w_{k} + \sum^m_{k=1} y^{(t-1)}_{k} v_{k} + b

これを偏微分すれば $w$ の無い項は消失するので


\frac{\partial u^{(t)}}{\partial w_i} = \frac{\partial (\sum^m_{k=1} x^{(t)}_k w_k) }{\partial w_i} \\
= \frac{\partial}{\partial w_i} (x^{(t)}_1 w_1 + x^{(t)}_2 w_2 + ... x^{(t)}_m w_m)  \\
= x^{(t)}_i

置き換えすると


\frac{\partial E}{\partial w_i} = \sum^r_{t=1} \frac{\partial E}{\partial u^{(t)}} \frac{\partial u^{(t)}}{\partial w_i}
= \sum^r_{t=1} x^{(t)}_i \delta^{(t)}

 v偏微分も考えると同様な展開して


\frac{\partial E}{\partial v_i} = \sum^r_{t=1} \frac{\partial E}{\partial u^{(t)}} \frac{\partial u^{(t)}}{\partial v_i} \\
= \sum^r_{t=1} y^{(t-1)}_i \delta^{(t)}

バイアスなんかはもっと単純に


\frac{\partial E}{\partial b} = \sum^r_{t=1} \delta^{(t)}

ここから特定時刻の入力 [tex: x^{(t)}i ] の勾配を考えると、ニューロン毎の $u^{(t)}k$ を挟んだ連鎖律を使って求める。


\frac{\partial E}{\partial x^{(t)}_i} = \sum^n_{k=1} \frac{\partial E}{\partial u^{(t)}_k} \frac{\partial u^{(t)}_k}{\partial x^{(t)}_i}

ここで   \delta^{(t)} = \frac{\partial E}{\partial u^{(t)}} なので


= \sum^n_{k=1} \frac{\partial u^{(t)}_k}{\partial x^{(t)}_i} \delta^{(t)}_k

 u


u^{(t)} = \sum^m_{k=1} x^{(t)}_{k} w_{k} + \sum^m_{k=1} y^{(t-1)}_{k} v_{k} + b

なので、 \partial x 偏微分なら  x を含まない項は消えるので、


\frac{\partial u^{(t)}_k}{\partial x^{(t)}_i} = \sum^m_{k=1} w_{ik}

通して


\frac{\partial E}{\partial x^{(t)}_i} = \sum^n_{k=1} \frac{\partial E}{\partial u^{(t)}_k} \frac{\partial u^{(t)}_k}{\partial x^{(t)}_i} \\
= \sum^m_{k=1} w_{ik} \delta^{(t)}_k

前の時刻の出力の勾配を考えると


\frac{\partial E}{\partial y^{(t-1)}_i} = \sum^n_{k-1} \frac{\partial E}{\partial u^{(t)}_k} \frac{\partial u^{(t)}_k}{\partial y^{(t-1)}} = \sum^n_{k=1} v_{ik} \delta^{(t)}_k