0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

FORCE学習を簡単にまとめる

0
Posted at

はじめに

リザバーコンピューティングを調べていたら FORCE学習という名前が出てきたので、ついでにまとめておきます。

ひとことで言うと

カオス的に動く再帰型ネットワークの出力を、ネットワークに戻しながら、読み出しの重みをオンラインで少しずつ直して、狙った出力を出させる学習方法です。
Sussillo と Abbott が 2009 年に提案しました。名前は First-Order Reduced and Controlled Error の略です。

仕組み

ネットワークの形は、リザバーコンピューティングとほぼ同じです。まずはざっくりした全体像から。

FORCE学習の概念図
図1:FORCE学習の全体像。ネットワークは出力をフィードバックしながら動き、学習中だけ、誤差を使って読み出し $w$ を直すループが回る

中身をもう少し細かく描くと、こうなります。

FORCE学習のアーキテクチャ
図2:FORCE学習の構成。再帰結合 $J$ と出力フィードバック $w_f$ は固定で、読み出し $w$ だけを、誤差 $e(t)$ を使って RLS で毎ステップ直す

  • 中の再帰結合 $J$ はランダムで固定する(ネットワークはカオス的に動く)
  • 出力 $z(t) = w^\top r(t)$ を作る読み出しの重み $w$ だけを学習する
  • 出力 $z(t)$ を、ネットワークへの入力として戻す(フィードバック)

ここで問題になるのが、フィードバックです。
出力が間違っていると、その間違いがネットワークに戻って、動きがどんどんずれてしまいます。

FORCE学習では、学習の最初から誤差を小さく抑え続けることで、この問題を避けます。

  1. 毎ステップ、出力と目標の誤差 $e(t) = z(t) - f(t)$ を計算する
  2. 再帰最小二乗法(RLS)で、$w$ を大きめに直して、誤差をすぐ小さくする
  3. 誤差が小さいまま学習を続けると、そのうち $w$ がほとんど変わらなくなる
  4. 学習を止めても、ネットワークは目標の出力を出し続ける

RLS の更新は、次のようになります。

P(t) = P(t - \Delta t) - \frac{P(t - \Delta t)\, r(t)\, r(t)^\top P(t - \Delta t)}{1 + r(t)^\top P(t - \Delta t)\, r(t)}
w(t) = w(t - \Delta t) - e(t)\, P(t)\, r(t)

$e(t)$ は、重みを直す前の $w(t - \Delta t)$ で計算した誤差です。$P$ は、リザバーの状態 $r$ の相関行列の逆行列を、逐次的に推定したものです。

NumPy で書いてみる

RLS の更新を、そのまま NumPy で書くとこうなります。目標は 2 つのサイン波を足した波形です。

import numpy as np

rng = np.random.default_rng(0)
N, g, dt, tau = 500, 1.5, 0.1, 1.0      # ニューロン数、結合の強さ、時間刻み、時定数
T_train, T_test = 3000, 1000             # 学習・テストのステップ数

J = g * rng.standard_normal((N, N)) / np.sqrt(N)   # 再帰結合(固定)
w_f = rng.uniform(-1, 1, N)                        # 出力フィードバック(固定)
w = np.zeros(N)                                    # 読み出し(これだけ学習)
P = np.eye(N)                                      # 相関行列の逆行列の推定値

t = np.arange(T_train + T_test) * dt
f = np.sin(t / 4) + 0.5 * np.sin(t / 2)              # 目標の出力

x = 0.5 * rng.standard_normal(N)
r = np.tanh(x)
z = w @ r
out = []
for i in range(len(t)):
    x += dt / tau * (-x + J @ r + w_f * z)
    r = np.tanh(x)
    z = w @ r
    if i < T_train:
        e = z - f[i]                               # 直す前の w での誤差
        Pr = P @ r
        P -= np.outer(Pr, Pr) / (1 + r @ Pr)
        w -= e * (P @ r)
    out.append(z)

out = np.array(out)
print("テスト区間の誤差 (RMSE):", np.sqrt(np.mean((out[T_train:] - f[T_train:]) ** 2)))

手元で動かすと、学習を止めたあとのテスト区間でも RMSE が 0.003 くらいで、目標の波形を出し続けてくれました。
パラメータは原論文($N=1000$、$g=1.5$ など)より小さくして、すぐ動くようにしています。

学習の過程を見てみる

上のコードとほぼ同じ設定(目標も同じ波形)で、学習前 → 学習中 → 学習後と続けて動かしたときの様子を図にしました。

FORCE学習の学習過程
図3:学習の過程。上から、出力 $z(t)$ と目標 $f(t)$、リザバーの中のニューロン 3 個の活動 $r_i(t)$、1ステップあたりの重みの変化量 $\|\Delta w\|$(対数軸、移動平均)

  1. 学習前:読み出し $w$ は小さなランダム値です。ニューロンの活動は不規則(カオス的)で、出力も目標とはまったく合いません
  2. 学習中:RLS を動かすと、出力はほぼ一瞬で目標に重なります。誤差が小さいままなので、フィードバックで戻ってくる信号もほぼ「正しい出力」になり、ニューロンの活動も目標と同じリズムにそろっていきます。重みの変化量は、時間がたつにつれてだんだん小さくなります
  3. 学習後:RLS を止めて $w$ を固定しても、ネットワークは目標の波形を出し続けます

「最初から誤差を小さく抑える」→「そのうち $w$ が落ち着く」→「止めても大丈夫」という流れが、そのまま見えるのがおもしろいところです。
図は $N=500$、学習前に少し空回しして初期状態の影響を消してから描いています。

基本的なリザバーコンピューティングとの違い

基本的なESN FORCE学習
学習のタイミング データを全部集めてから一度に解く 1ステップごとにオンラインで直す
出力のフィードバック なくてもよい あり(これを安定させるのが目的)
誤差の扱い 最後に最小化する 最初から小さく抑え続ける

どこで使われているか

  • 脳の神経回路が、どうやって複雑な時系列(運動のパターンなど)を作っているのかを調べるモデル
  • スパイキングニューロンのネットワークにも応用されている(Nicola と Clopath, 2017)

まとめ

「誤差を最初から小さく保つことで、カオスを手なずける」のが FORCE学習のミソです。
理解が浅いところがあれば、有識者の方教えて欲しいです!

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?