概要
多層パーセプトロン記事の補足。下の記事の最後で、入力されたデータを隠れ層で線形分離しやすい形に変換している、ということを確かめたかったが、MNIST データでは次元が高すぎてよくわからなかった。ということで、もうちょっとわかりやすい例を考える。
可視化シリーズとしては以下の記事のつづき。
ロジスティック回帰 (勾配降下法 / 確率的勾配降下法) を可視化する - StatsFragments
多層パーセプトロンとは
詳細は上記の記事参照。この記事では、以下のような多層パーセプトロンを例とする。
- 入力層のユニット数が 2
- 隠れ層のユニット数が 3
- 出力層のユニット数が 2
つまり、入力層として 2 次元のデータを受けとり、隠れ層で 3 次元空間へ写像してロジスティック回帰 ( 出力は2クラス ) を行う。
サンプルデータ
2 次元で線形分離不可能なデータでないとサンプルの意味がない。ここでは以下のように生成したXOR 型のデータを使うことにする。
# 集団内の要素数 (散布図の通り、同じ色の2集団で 1クラスを形成) N = 100 # 説明変数 x = numpy.matrix([[0] * N + [1] * N + [0] * N + [1] * N, [0] * N + [1] * N + [1] * N + [0] * N], dtype=numpy.float64).T x += numpy.random.rand(N * 4, 2) / 2 # 目的変数 y = numpy.array([0] * N * 2 + [1] * N * 2, dtype=numpy.int32)
散布図が示すとおり、各クラス ( 赤 / 青の 2 クラス ) は 1本の直線で分割することはできない。そのため、このままではロジスティック回帰の判別率は低くなる。
隠れ層からの出力結果と分離平面の可視化
上で記載した通り、隠れ層のユニット数が 3 のときには出力も 3 次元データとなる。多層パーセプトロンは この 3 次元データが線形分離できるように各係数行列 / バイアスベクトルの学習を行う。
3 次元データであればグラフに描けるため、多層パーセプトロンの学習ステップをアニメーションさせてみた。灰色の面はロジスティック回帰での分離平面である。
補足 名義上 x0
, x1
が入力データに対応する次元 / z
が隠れ層で新たに追加された次元だが、係数行列を乱数で初期化しているため 直接的な対応関係はない。
補足 一瞬 分離平面が消えるのは傾きが急すぎて描画範囲を超えたため;;
多層パーセプトロンでは、ロジスティック回帰では分離できないデータをうまく分離できている。また、各集団の分布具合から 隠れ層の活性化関数 tanh
によって非線形変換が行われていることもわかる。
500 エポック学習後の隠れ層出力 / 分離平面を別の角度から。いい感じに分割してますな。
プログラム
gist においた。補足として、分離平面の座標は を解けば求められる。今回の場合、
は 次元が 3 のベクトル。うち 2 次元の値を決めれば、残る 1 次元の座標は一意に決まる。具体的な計算式は以下。
# 座標 x0, x1 について 分離平面の z 座標を計算 def calc_z(classifier, x0, x1): w = classifier.logRegressionLayer.W.get_value() b = classifier.logRegressionLayer.b.get_value() z = ((w[0, 0] - w[0, 1]) * x0 + (w[1, 0] - w[1, 1]) * x1 + b[0] - b[1]) / (w[2, 1] - w[2, 0]) return z
補足 こちら で作った MLP
クラスをロードするため、実行する場合は 同じディレクトリに置くこと。
Animate Multilayer Perceptron using 2D XOR Data
まとめ
多層パーセプトロンにおいて、線形分離できない入力が隠れ層での変換により線形分離できるようになっていく過程が確かめられた。この変換により、多層パーセプトロンでは ロジスティック回帰では判別が難しいデータも扱うことができる。