いものやま。

雑多な知識の寄せ集め

強化学習とニューラルネットワークを組合せてみた。(その1)

昨日書いたとおり、現状ではあまり上手くいってない。

でも、とりあえず書いてみる。

関数近似としてニューラルネットワークを使う

Sarsa( \lambda)法の関数近似としてニューラルネットワークなどを使う場合、その関数のパラメータに関する勾配を求める必要がある。

以下、Sarsa( \lambda)法でのパラメータの更新を再掲すると、

 {
\begin{align}
\delta^{(t)} &= r_{t+1} + \gamma v(s_{t+1}; \boldsymbol{\theta}^{(t)}) - v(s_t; \boldsymbol{\theta}^{(t)}) \\
\boldsymbol{e}^{(t)} &= \left\{ \begin{array}{ll}
\boldsymbol{0} & (t = 0) \\
\gamma \lambda \boldsymbol{e}^{(t-1)} + \nabla_{\boldsymbol{\theta}} v(s_t; \boldsymbol{\theta}^{(t)}) & (t \ge 1)
\end{array} \right.
\end{align}
}

としたとき、

 {
\boldsymbol{\theta}^{(t+1)} = \boldsymbol{\theta}^{(t)} + \alpha \delta^{(t)} \boldsymbol{e}^{(t)}
}

とする。

見ての通り、状態価値を近似している関数  v のパラメータ  \boldsymbol{\theta} に関する勾配  \nabla_{\boldsymbol{\theta}} v が必要になっている。

ニューラルネットワークの場合、勾配が誤差逆伝播法で(比較的)簡単に計算できるというのがある。

以下、誤差逆伝播法による勾配計算を再掲すると、

  1. 入力  \boldsymbol{x} から、各層について  u^{(l)}_j z^{(l)}_j を計算する。
  2. 以下のようにして、デルタ  \delta^{(l)}_j を計算する:
    1. 出力層で、 \delta^{(L)}_j = \frac{ \partial E }{ \partial u^{(L)}_j } を計算する。
    2. 中間層で、 l = L-1, \cdots, 2 の順番で、デルタ  \delta^{(l)}_j を次のように計算する:
      •  \delta^{(l)}_j = {f^{(l)}}' ( u^{(l)}_j ) \sum_{k=1}^{J_{l+1}} \delta^{(l+1)}_k w^{(l+1)}_{k, j}
  3. 以下のようにして、重み  w^{(l)}_{j, i} とバイアス  b^{(l)}_j に対する偏微分を計算する:
    •  \frac{ \partial E }{ \partial w^{(l)}_{j, i} } = \delta^{(l)}_j z^{(l-1)}_i
    •  \frac{ \partial E }{ \partial b^{(l)}_j } = \delta^{(l)}_j

なお、出力層のデルタ  \delta^{(L)}_j は、誤差関数として二乗和誤差  \frac12 \left\| \boldsymbol{d} - \boldsymbol{y} ( \boldsymbol{x} ; \boldsymbol{w} ) \right\|^2 を使う場合、 \delta^{(L)}_j = (y_j - d_j) \: {f^{(L)}}' (u^{(L)}_j) となる。

ただ、ここでいう勾配というのは、普通は誤差関数の重みに対する勾配  \nabla_{\boldsymbol{w}} E であって、ニューラルネットワークの出力自身の重みに関する勾配  \nabla_{\boldsymbol{w}} y ではないので、ちょっと注意が必要。

といっても、中間層のデルタは誤差関数の形に依存していないので、アルゴリズム自体はそのまま使えて、出力層のデルタのみ、 E = y として計算すればいいだけ。
さらに、 y = f^{(L)}(u^{(L)})なので、出力層のデルタは単に  \delta^{(L)} = {f^{(L)}}' (u^{(L)}) となる。

今日はここまで!