MLP – 多層パーセプトロン

線形モデルの多層化

“Pythonではじめる機械学習”の写経。多層パーセプトロン(Multilayer perceptron : MLP)はフィードフォワード・ニューラルネットワークとも呼ばれる。

まず、線形モデルを以下の式で表す。

(1)    \begin{equation*} b + w_0 x_0 + \cdots + w_n x_n \end{equation*}

n = 3の場合について図示すると、以下のように表せる。左側のノードの特徴量xiに対して、wiによる重み付き和を計算している。

MLPは、この構造に中間層を導入し、中間層に隠れユニット(hidden units)を配置する。特徴量入力はまず隠れユニットに対して重み付き線形和を計算し、その後に隠れユニットの出力の重み付き線形和を出力とする。

特徴量xi (i = 0~n)の隠れユニットhj (j = 0~m)に対する重みをwij、切片をbjとすると、hjへの入力となる重み付き線形和は以下のようになる。

(2)    \begin{equation*} h_j = \sum_{i=0}^n (b_j + w_{ij} x_i) \end{equation*}

また、隠れユニットhjの出力\hat{y}に対する重みをvj、切片をcとすると、出力への重み付き線形和は以下のようになる。

(3)    \begin{equation*} \hat{y} = c + \sum_{j=0}^m v_j h_j = c + \sum_{j=0}^m v_j \sum_{i=0}^n (b_{ij} + w_{0ij} x_i) \end{equation*}

これは結局、xiに対する重み付き線形和となる。たとえば特徴量0~3、隠れユニット0~2の場合は以下のとおり。

(4)    \begin{align*} \hat{y} &= c + v_0 h_0 + v_1 h_1 + v_2 h_2 \\ &= c + v_0 (b_0 + w_{00} x_0 + w_{10} x_1 + w_{20} x_2) \\ &\phantom{=c+}v_1 (b_1 + w_{01} x_0 + w_{11} x_1 + w_{21} x_2) \\ &\phantom{=c+}v_2 (b_2 + w_{02} x_0 + w_{12} x_1 + w_{22} x_2) \\ &= c + v_0 b_0 + v_1 b_1 + v_2 b_2 \\ &\phantom{=}+ (v_0 w_{00} + v_1 w_{01} + v_2 w_{02}) x_0 \\ &\phantom{=}+ (v_0 w_{10} + v_1 w_{11} + v_2 w_{12}) x_1 \\ &\phantom{=}+ (v_0 w_{20} + v_1 w_{21} + v_2 w_{22}) x_2 \end{align*}

非線形活性化関数

単純な線形和をいくら多層化しても、結果は特徴量の線形和にしかならない。そこで、隠れユニットの入力に対して非線形関数を適用して出力とし、複雑・柔軟な動作を可能とする。

このような関数を活性化関数(activation function)あるいは伝達関数(transfer function)と呼び、様々な種類がある。書籍では、このうちReLU (Rectified linear unit)とtanh (hyperbolic tangent)が紹介されている。ReLUは以下の式で表され、負の値が採用しえない(計算過程での)ノイズであるような場合に好都合らしい。tanhは(−∞, +∞)の入力に対して(−1, +1)の出力を返す。

(5)    \begin{equation*} h(x) = \max (0, x) = \left\{ \begin{align} x \quad (x \ge 0) \\ 0 \quad(x < 0) \end{aling} \right. \end{equation*}

ニューラルネットワークのチューニング

two moonsデータでの確認

two moonsデータセットに対してMLPを適用する。隠れユニットの数はデフォルトの100としている。

隠れユニット数と決定境界

隠れユニット数を10とした場合の結果は数の通り。先のユニット数100の場合に比べて、決定境界が折れ線になっている。

隠れユニット数の指定はhidden_layer_sizes=[10]のように指定する。複数の隠れ層を表現するためにリストとなっていて、1層の場合でも1要素のリストとする。また、収束計算回数の最大値がデフォルトのmax_iter=200では収束しきれないという警告が出るため、この値を1000に引き上げている。

結果は書籍のものと少し異なっていて、上方の▲の点より上に鋭く境界が突き抜けている。いくつかパラメーターを変えてみたが、書籍のような境界の形状は再現できなかった。

隠れユニットの数を[1]~[4]と変化させたときの決定境界の様子は以下の通りで、ユニット数が増えるにしたがって決定境界を構成する線分の数が増えている。

隠れ層の数

隠れユニット数が10程度でも、隠れ層の数を増やすと決定境界は滑らかになる。

隠れ層が2層の場合に、各層のユニット数を変化させたときの決定境界の変化を見てみる。1層目のユニット数が大まかな形に影響し、2層目のユニットは決定境界の滑らかさに影響していると言えそうだ。

活性化関数tanh

デフォルトでは非線形活性化関数にReLUが用いられるが、これをtanhとすることで下図のように決定境界が滑らかになる。デフォルトのまま(右)だと書籍のような形にならないが、最大計算回数max_iter=115と制限すると大体似たような形になる。

ここでも2つの隠れ層のユニット数を変化させてみると、第1層が大まかな形、第2層が細部の表現に影響していると言えそうだ。

正則化

MLPClassifierはL2正則化が可能で、パラメーターalphaに大きな値を設定すると正則化を強くできる。デフォルトはalpha=0.0001で正則化が効いていない状態。

以下に、2層のユニット数[10, 10]と[100, 100]に対してalphaをデフォルトの0.0001から1.0まで変化させたときの様子を示す。ただしmax_iter=500として未収束の警告が出ないようにしている。alphaを大きくするにしたがって正則化が強くなり、決定境界がシンプルなものになっていく様子が見られる。

ランダムな重みづけの影響

ニューラルネットワークでは、学習開始前に各重み係数がランダムに割り当てられるため、その初期値がモデルに影響を与える。以下は同じパラメーター設定に対してrandom_stateのみを変化させたもので、決定境界の形が異なっている。

データの前処理等

MLPのBreast cancerデータセットへの適用例で、データの標準化や重み係数の分布の確認等を行っている。

今後の課題

  • 総数・ユニット数と計算量の関係
  • パラメーター調整のパターン
  • scikit-learn以外のライブラリー(keras, lasagna, tensor-flow)
  • GPUのサポート
  • 収束計算のアルゴリズム(lbfgs, adam, sgd)

 

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です