StatsFragments

Python, R, Rust, 統計, 機械学習とか

Theano で Deep Learning <6>: 制約付きボルツマンマシン <前編>

DeepLearning 0.1 Documentation の第六回は 制約付きボルツマンマシン (Restricted Boltzmann Machines / 以降 RBM) 。RBM は オートエンコーダとはまた別の事前学習法。かなり分量があるので、とりあえず元文書 前半のRBM の仕組みまで。

RBM を理解しにくいポイントは 2 つあるかなと思っていて、

  1. この構造 (グラフィックモデル) であるメリットはあるのか?
  2. 学習 (Contrastive Divergence) で何をやってんのか?

というとこではないかと。最初、自分は 2 がまったくわからなかった。2 は "とりあえずできそうな構造 / 方法でやってみたらなんかうまくいった" 感があって、理由がいまいちはっきりしないところがある。

目次

DeepLearning 0.1 について、対応する記事のリンクを記載。

第一回 MNIST データをロジスティック回帰で判別する
第二回 多層パーセプトロン
第三回 畳み込みニューラルネットワーク
第四回 Denoising オートエンコーダ
第五回 多層 Denoising オートエンコーダ
第六回の準備1 networkx でマルコフ確率場 / 確率伝搬法を実装する -
第六回の準備2 ホップフィールドネットワーク -
第六回 制約付きボルツマンマシン (今回)
Deep Belief Networks
Hybrid Monte-Carlo Sampling
Recurrent Neural Networks with Word Embeddings
LSTM Networks for Sentiment Analysis
Modeling and generating sequences of polyphonic music with the RNN-RBM

制約付きボルツマンマシン (RBM) とは

まずはこちらの "RBMとは?" "RBMの学習の流れ" の 2 セクションを読むのがいい。

RBM の導出

以降、元文書 が何を言わんとしているのかを適当に抜粋。この文書、いくつか手順を追って RBM の説明・導出をしてくれているのだが、初見では何言ってんだかまったくわからない、、、。

まずはでてくる用語の概要。最初に RBM を包括するエネルギーベースモデル (以降 EBM) という概念を説明 -> その後で RBM の考え方を導入するという流れになる。

  • EBM: ネットワーク全体からエネルギーが定義されるモデル。ホップフィールドネットワーク (以降 HNN) はこれ。
  • 確率的 EBM: EBM のうち、エネルギーによって確率が定義されるモデル。RBM はこれ。

  • ボルツマンマシン: 確率的 EBM の一種。定義上、隠れ層はなくてもよい。

  • RBM: 確率的 EBM の一種。可視層 / 隠れ層をもち、その接続に一定の制限があるモデル

補足 自分が読んだ中で RBM の導出 / 説明が最もわかりやすいと思うのは、DeepLearning Documentation からもリンクされている Learning deep architectures for AI。なので正確な定義 / 説明はそちらを。

エネルギーベースモデル (Energy-Based Models / EBM)

HNN はネットワーク全体のエネルギー = グローバルエネルギーを定義していた。何らかの形で定義されたエネルギー (ここではエネルギーの具体的な式は考えない) をもつモデルを EBM という。このとき、ネットワークの確率分布を 左図 式(1) のように定義したものを確率的 EBM という。

EBM を HNN の構造と似せて図示すると以下のような感じになる。このとき、 隠れ層がないモデル (左図) と比べて 隠れ層がある場合 (右図) の考え方が難しい、というのがここで言っていること。

f:id:sinhrks:20150112182334p:plain

隠れ層なし(左図): エネルギーがモデルのパラメータ  { \theta }微分できれば 対数尤度 / 損失関数を定義して勾配降下法を使って学習できる。勾配は { grad } に示す式になる。

隠れ層あり(右図): ネットワークがある状態をとる確率は { P(v, h) } とあらわせる。これを、式 (2) のように 可視層 { v } の確率として書きたい 。このとき、式 (3) にあるような自由エネルギー (Free Energy) { F(v) } を導入する = { h } について周辺化すると、式 (2) が 式 (1) と同じように { v } の関数で書ける。勾配は 式 (4) に示す形になるが、この2項めの計算は { h } で周辺化した { v } の確率の総和、と 2重の総和になっており、その組み合わせ数から現実的には計算できない。

制約付きボルツマンマシン (Restricted Boltzmann Machines / RBM)

ここから RBM の話。RBM / ならびに制約なしのボルツマンマシンについても、HNN と同じ式でグローバルエネルギーが定義される。いずれも、入力は {0, 1} の 2値を想定。入力が 2値の RBM を Bernoulli RBM という。

f:id:sinhrks:20150111184253p:plain

ボルツマンマシン (左図)

可視層 / 隠れ層のユニットは相互に全接続する。HNN での定義 をベクトル / 行列を使ったものに書き換えると上のようになる。

  • { E }: グローバルエネルギー
  • { s }: ユニットの状態ベクトル。長さはユニット数。i 番目の要素を  { s_{i} } とあらわす。
  • { W }: 接続重みの行列。HNNと同じく、次元は ユニット数 x ユニット数 の対象行列。(i, j) 番目の要素を  { w_{ij} } とあらわす。
  • { \theta }: バイアスベクトル。長さは ユニット数。 i 番目の要素を  { \theta_{i} } とあらわす。

参考 可視層/隠れ層を分けた場合の式は Learning deep architectures for AI の式 5.15 にある。

RBM (右図)

ボルツマンマシンに 可視層どうし / 隠れ層どうしの接続なしという制約をもたせたもの。RBM でもグローバルエネルギーの考え方は一緒だが、ユニットの接続がない = 重み行列の対応する要素が 0 のところは無視できるため、変数は増えるが 計算自体はだいぶ単純になる。

  • { E }: 同上
  • { v }: 可視層の状態ベクトル。長さは 可視層のユニット数 { D_v }
  • { h }: 隠れ層の状態ベクトル。長さは 隠れ層のユニット数 { D_h }
  • { W }: 接続重みの行列。次元は 隠れ層のユニット数 { D_h } x 可視層のユニット数 { D_v }
  • { b }: 可視層のバイアスベクトル。長さは 可視層のユニット数 { D_v }
  • { c }: 隠れ層のバイアスベクトル。長さは 隠れ層のユニット数 { D_h }

補足 HNN のエネルギー計算式と形は一緒だが、 { \theta } の符号が逆転する。これは、{ \theta } を HNN ( wikipedia ) では閾値 (threshold) として、ボルツマンマシン ( wikipedia ) ではバイアス (bias) としてみていることに起因する。 閾値 = -バイアスなので、{ \theta } に関する符号が逆になる。

一般に RBM は以下のように図示されているので、以降 それにならう。

f:id:sinhrks:20150111190122p:plain

RBM が制約を持つ理由

ネットワークを マルコフ確率場として考える。制約なしのボルツマンマシンでは、全ユニットが相互に接続している。そのため、確率伝搬を行う場合に 全ノードからの伝搬を計算する必要があり、計算量が多くなる / 収束が遅くなり、大量の学習データに対して処理を行うのは現実的でない。

一方 RBM では 可視層どうし / 隠れ層どうしは接続を持たないため、同じ層のユニットどうしの確率は独立になる。あるユニットに着目してその確率を求めると式 (7), (8) / 下図 (クリックで拡大) のようになる。

f:id:sinhrks:20150111184348p:plain

また各層の確率は同時に計算できて、層全体の確率は下図 (クリックで拡大) のようになる。

f:id:sinhrks:20150111184417p:plain

RBM の制約によって、確率伝搬を 可視層 -> 隠れ層 -> 可視層 ... と層単位で行うことができ、全接続した場合と比べるとなんかやれそうな感じがしてくる。これが "1. RBM がこの構造 (グラフィックモデル) であるメリット"。

RBM の自由エネルギーと勾配計算

ここで、隠れ層のある EBM での 式 (4) が RBM でどうあらわされるか考える。自由エネルギーは定義から以下のように書けるので、

{ F(v) = -b^{T}v - \sum_{i} \log \sum_{h_{i}} e^{h_{i} (c_{i} + W_{i} v)} }

こちらと 式 (4) でごにょごにょとやると、元文書の 式 (10) がでてくる。が、この式はわかりにくいし 2式目は間違っていると思うので、上のリンクでも引用されている以下の PDF を参照したほうがよい。

(元文書の式と形式は異なるが) この PDF の 式 (9) にあるものを求めたい。EBM の式 (4) にあった二重の総和は残っており、このままだと計算ができない。これをなんとかするための方法が Contrastive Divergence。

Contrastive Divergence

解析的に計算できないなら ギブスサンプリングして近づけよう、というのが Contrastive Divergence (以降 CD) の考え方。

CD にはいくつか種類があるのだが、まずは ふつうの CD 法である CD-1。これも言葉だけだとどこに何の値が入って / 何がサンプリングされてんだかまったくわからない。この説明も、 Learning deep architectures for AI がわかりやすいので、それにもとづいて図示する。

補足 これは Restricted Boltzmann Machine の導出に至る自分用まとめの 式 (27) (28) (29) を計算していることと同じ。

CD-1

CD-1 のアルゴリズムと更新式は以下のようになる。それぞれのステップで計算される箇所を赤字にしている。イメージしやすくなるように適当に数値を入れたが、特にこの数値にしている必然性はない。

f:id:sinhrks:20150112163435p:plain

左図のようなRBMを考える。

f:id:sinhrks:20150112163442p:plain

ひとつの入力データ { v^{(0)} } から学習を行うことを考える。このとき、可視層の値は入力を元に決まる。

f:id:sinhrks:20150112163451p:plain

可視層の値から隠れ層の確率 { P(h^{(0)}=1|v^{(0)}) = sigm(c + W v^{(0)}) } を計算する。

f:id:sinhrks:20150112163458p:plain

計算した確率にもとづいて、隠れ層の実現値 { h^{(0)} \in { 0, 1 } } をサンプリングする。このとき、{ h^{(0)} } の期待値が先の確率と一致するようにサンプリングする。ランダムサンプリングなので、確率が高いものが選ばれるとは限らない。

f:id:sinhrks:20150112163510p:plain

隠れ層の実現値 { h^{(0)} } に対する可視層の確率 { P(v^{(1)}=1|h^{(0)}) = sigm(b + W^T h^{(0)}) } を計算する。

f:id:sinhrks:20150112163521p:plain

計算した確率にもとづいて、可視層の実現値 { v^{(1)} \in { 0, 1 } } をサンプリングする。このとき、{ v^{(1)} } の期待値が先の確率と一致するようにサンプリングする。ランダムサンプリングなので、確率が高いものが選ばれるとは限らない。

f:id:sinhrks:20150112163528p:plain

可視層の値から隠れ層の確率 { P(h^{(1)}=1|v^{(1)}) = sigm(c + W v^{(1)}) } を計算する。

これらを使って、{ W, b, c } を更新する。そのときの更新式は以下となる ({ \eta } は学習率)。

  • { W \leftarrow W + \eta (P(h^{(0)}=1|v^{(0)})v^{(0)T} -  P(h^{(1)}=1|v^{(1)}) v^{(1)T}) }
  • { b \leftarrow b + \eta (v^{(0)} - v^{(1)}) }
  • { c \leftarrow c + \eta (P(h^{(0)}=1|v^{(0)}) - P(h^{(1)}=1|v^{(1)})) }

このステップを全学習データについて繰り返す。

補足 亜流なのか誤植なのかわからないが、Learning deep architectures for AI のほうの更新式では隠れ層の確率 { P(h=1|v) } ではなくサンプリングされた実現値 { h^{(0)} }を使っている。また、添字はひとつずれる。

CD-k

CD-1 では 隠れ層 / 可視層について 1 回ずつサンプリングした。これを k 回繰り返せば本当の値にもう少し近づくんじゃない?というのが CD-k 法。 更新式は、上の { v^{(1)},  P(h^{(1)}=1|v^{(1)}) } のかわりに { v^{(k)},  P(h^{(k)}=1|v^{(k)}) } を使う。

f:id:sinhrks:20150112181019p:plain

Persistent CD

CD-1 / CD-k では、入力される学習データを起点として都度 サンプリングを行って { v^{(k)} } を求めていた。サンプリングした値は次の学習データがきたら破棄されていた。

Persistent CD では学習データとは無関係にサンプリングを繰り返し行い、モデルの分布を徐々に近似していく。

  1. 可視層の値の初期値 { v^{0 \star } } を適当にとる (もしくは適当な隠れ層の初期値 { h^{0 \star } } から始める)。
  2. 1つめの学習データが入力されたとき、{ v^{0 \star } } をもとに確率計算 / ランダムサンプリングによって { v^{1 \star } } を得る (サンプリングの考え方は CD 法と一緒)。1つめのデータに対する勾配計算は、学習データと { v^{1 \star } } で行う。
  3. 2つめの学習データが入力されたとき、{ v^{1 \star } } をもとに確率計算 / サンプリングによって { v^{2 \star } } を得る。2つめのデータに対する勾配計算は、学習データと { v^{2 \star } } で行う
  4. 以降、学習データが入るたびに確率計算 / サンプリングによって { v^{k \star } } を更新する。n番めのデータに対する勾配は、n番目の学習データと { v^{n \star } } で行う

f:id:sinhrks:20150112222927p:plain

{ n } 番目の学習データ { v_n } に対する更新式は以下のようになる。

  • { W \leftarrow W + \eta (P(h=1|v_n)v_n^{T} -  P(h^{n \star }=1|v^{n \star }) v^{n \star T}) }
  • { b \leftarrow b + \eta (v_n - v^{n \star }) }
  • { c \leftarrow c + \eta (P(h=1|v_n) - P(h^{n \star }=1|v^{n \star })) }

まとめ

RBM の概要について わかりにくいポイントである以下 2点について書いた (つもり)。

  1. この構造 (グラフィックモデル) であるメリット
  2. 学習 (Contrastive Divergence) のアルゴリズム

以降、 theano での実装の話だが、すこし複雑な実装になっているのでちょっとわかりにくい。参考として、scikit-learnRBM の実装 のほうがわかりやすいので一読をおすすめ。こちらは Persistent CD を使って学習している。

深層学習 (機械学習プロフェッショナルシリーズ)

深層学習 (機械学習プロフェッショナルシリーズ)