Coursera MachineLearning 4,5週目 まとめ

MachineLearning

機械学習界隈で評判高いCourseraのMachineLearningを受講したので、講義内容を個人的にまとめてみたいと思います。
4,5週目はニューラルネットワーク(Neural Networks)についてです。


ニューラルネットワーク(Neural Networks)

「ニューラルネットワーク」とは、脳を真似た学習アルゴリズムの一種です。

脳は、脳細胞と呼ばれる細胞によって構成されています。数にして千数百億個、もうよくわからない量です。
細胞の種類としては、一般的に「神経細胞(Neuron)」と「グリア細胞」の2種類に分けられます。
神経細胞は情報伝達を、グリア細胞は神経細胞の補助をそれぞれ担当していますが、今回着目すべきは神経細胞(Neuron)ですね。
ニューロンは脳のいたるとことろに存在し、外部からの刺激を電子信号として伝えています。

(出典:Andrew Ng, Coursera Machine Learning Week 4)

ニューロンの特徴的な構造として、以下が挙げられます。

  • 樹状突起(Dendte) : 他の神経細胞からの電子信号を受け取る部分(input)
  • 軸索(axon):他の神経細胞へ電子信号を伝える部分(output)
  • シナプス(Synapse):他の神経細胞との接合部分(樹状突起と軸索のつなぎ目。シナプス間隙と呼ばれる数万分の1mm程の隙間があり、信号の伝達効率はそれぞれ異なっている)

Input部である樹状突起から入ってきた電気信号が閾値以上になると、神経細胞の電位が突発的に高くなります。この現象を発火といい、発火した電気信号はoutput部の軸索を通じて、次の神経細胞へと送られます。
このような仕組みでニューロンに電気信号が常時駆け巡ることで、脳の高度な機能は実現されています。

人間の脳では、画像処理や音の分類、感覚の分類など、様々な処理を行なっています。皆さんの脳が平然と日常的に行なっていることを模倣するモデルを作成することができれば、様々な問題を処理することができそうですよね。
ニューラルネットワークでは、ニューロンのネットワークをシミュレーションしていきます。

脳の模倣なんてとんでもない数のアルゴリズムが組み合わさってそうで半端なく難しそう…と最初は思ってしまいますが、
ニューラルネットワークは1つの学習アルゴリズムによって機能しているという仮定のもと、仮説関数を作成していきます。

(出典:Andrew Ng, Coursera Machine Learning Week 4)

先ほど説明したニューロンの電子信号伝達のモデル図です。
◯で示した部分はノード(node)と呼ばれ、それぞれのニューロンの本体をイメージしています。

  • Layer1:input layer と呼ばれる入力層です。ここに特徴量(feature)をinputします。
  • Layer2:hidden layer と呼ばれる層です。(このモデル図では1層ですが、複数の層の場合もあります)
  • Layer3:output layer と呼ばれる出力層です。ここが最終的な計算結果を返します。

hidden layer に新たな変数が登場しました。
\(a{_i}^{(j)}\)は activation unit を表しています。あるノードからの計算結果・出力値を示します。
また、\(i\) は ユニット番号、\(j\) は層の番号を意味しており、今回のモデル図では\(( i = 1,2,3 / j = 2 )\) ということになります。

それぞれの activation unit の式は、以下のようになります。

Uppercase \(Θ\) という新しいパラメータもしれっと登場してますね。
この\(Θ\)は、シナプスでの重みを表します。 lowercase \(θ\) は特徴量に重みを付加するパラメーターでしたが、\(Θ\)も同じ働きをします。この重みに応じて、信号を増幅・減衰させた後に、次のノードへと伝えます。

また、それぞれの式でロジスティック関数が使われています。
ニューロンは、ある一定値以上の電気信号がインプットされることで発火を起こし、次のニューロンに信号を送るのでした。受け取った電子信号によって発火するかしないか(1 or 0)を、ロジスティック関数で示しているというわけです。

文字について、もう少し詳しく見ていきましょう。
\(Θ\)には色々とインデックスが付いています。

\(Θ^{(j)}\) の j は、activation unit と同様に、Layer(層)の番号を意味します。
2つの下付き文字は、ユニットの番号を表します。activation unit では1つだけでしたが、シナプスでの重みを表す\(Θ\)では、移動先と移動元のユニットをそれぞれ示す必要があります。左側の数字が Layer \((j + 1)\) のユニット番号で、右側の数字が Layer \(j\) のユニット番号を示しています。

\(x_0\)という、モデル図には描かれていない文字も式の中に含まれています。
ここでのインデックス0の特徴量は、切片項(intercept)を示し、常に1となります。(後に、インデックス0の activation unit も登場しますが、同様に1を示します)

今回のモデル図では、Layer1の入力層から activation unit に伸びている矢印9本と、切片項(バイアス項)\(x_0\)から伸びる矢印3本 があることから、\(Θ\)は合計で12個あるということになります。
\(Θ\)が何次元になるのかは、[Layer (j+1) のユニット数] × [Layer j のユニット数] という式で表されます。(今回の例では、3×4次元です)

諸々をまとめて、仮定関数は以下のようになります。

機械学習は、各特徴量に対する重みをどれくらいにすべきか? lowercase \(θ\) や Uppercase \(Θ\) をどのような値にすべきか?を検討するものであり、それは線形回帰でも、ロジスティック回帰でも、ニューラルネットワークでも変わらない。ということですね。
ニューラルネットワークのアルゴリズムは、出力の正解率が上がるようなシナプスへの重み付けパラメーター\(Θ\)を学習していくことになります。

非線形分類の例

ここで簡単にニューラルネットワークを使用した分類例を見てみましょう。

(出典:Andrew Ng, Coursera Machine Learning Week 4)

2つの特徴量で、0か1を分類するバイナリーな問題があるとします。
この場合の「XOR回路」と「XNOR回路」について考えてみます。

(論理回路について復習)

「AND(論理積)」

A B 出力C
0 0 0
1 0 0
0 1 0
1 1 1

 

「OR (論理和)」

A B 出力C
0 0 0
1 0 1
0 1 1
1 1 1

 

「XOR(排他的論理和)」
OR集合に対して、両方1の場合だけ排他的(exclusive)に0にする。

A B 出力C
0 0 0
1 0 1
0 1 1
1 1 0

 

「XNOR(排他的論理和の否定)」

A B 出力C
0 0 1
1 0 0
0 1 0
1 1 1

 

今回は「XOR回路」と「XNOR回路」を作成して、2つの特徴量の値が揃っている時と揃っていない時で分類するということですね。

「AND(論理積)」と「OR (論理和)」を、hidden layerなしの2層構造で示すと以下のようになります。(矢印上の数字は、Θの値を示しています)

(出典:Andrew Ng, Coursera Machine Learning Week 4)

(NOT は特徴量を否定しているので、\(x=1\)の時には 0 になり、反対に\(x=0\)の時には 1 となります。よって、NOT(A) AND NOT(B) は以下のようになります)

NOT(A) NOT(B) 出力C
0 0 1
1 0 0
0 1 0
1 1 0

 

仮定関数は、以下のようになります。

この3つを組み合わせて、まずは「XNOR回路」を作っていきましょう。

2種類の理論演算AND(理論積)を行なった後、得られた出力結果を用いて理論演算OR(理論和)を行なっています。

「XOR回路」は「XNOR回路」の否定なので、上記のモデル図で得られた出力結果を用いて理論演算NOTを行うことで、「XOR回路」を得ることができます。

複数クラス分類の例

2択の分類問題(binary classification)を見てきましたが、\(y = 0, 1, 2, 3\) のように複数に分類したい場合についても考えてみましょう。図で示すと以下のようになりますが、第3週で学習した「one vs all」 という方法がここでも使われるようです。

数字①、②、③、④の様々なフォントの画像データがあり、それらの分類を行いたいとします。
ニューラルネットワークでは、それぞれの結果を\(y = 0, 1, 2, 3 \)のようにラベル付けをするのではなく、以下のように表現します。

仮定関数の値が、以上のどれかになるように設定します。
今回は数字①、②、③、④の分類なので4次元のベクトルとし、0と1のみで表現します。
これで複数の分類問題にも対応できそうですね。

いくつか例を見てきましたが、これまでは\(Θ\)の値が既に設定してあるものとして話を進めてきました。
では、この\(Θ\)はどのように求めたら良いのでしょうか?

目的関数

例のごとく、目的関数(Cost function)\(J\)が最小になるようなパラメーター\(Θ\)を求めていきます。

正則化したロジスティック回帰の目的関数は以下のようになりました。

ニューラルネットワークでもロジスティック関数が用いられるので、似たような形になりそうだと予測できます。

\(m\) はdata setに含まれるデータの総数、\(K\) は仮定関数が出力するベクトルの次元数(先ほどの例では K=4)、L は層の総数、\(S_l\)は\(l\)番目の層のユニット数を示します。

  • 第1項には\(\displaystyle \sum_{k=1}^{K}\)が追加されています。これは、ニューラルネットワークの最後のLayerが持つ出力ユニットの数だけ、以下の式を足し合わせるということになります。
  • 第2項の正則化の部分では、\(\displaystyle \sum_{l=1}^{L-1} \displaystyle \sum_{i=1}^{S_l} \displaystyle \sum_{j=1}^{S_{l+1}}\)が追加されています。 Θの2つの下付き文字は、移動先と移動元のユニットの番号をそれぞれ示していたことを思い出してください。左側の数字が Layer (l+1) のユニット番号で、右側の数字が Layer l のユニット番号を示していました。

3つの合計演算子を右から見ていくと…
  \(\displaystyle \sum_{j=1}^{S_{l+1}}\):Layer \((l + 1)\) のユニット数 \(1 〜 j\) までの和
  \(\displaystyle \sum_{i=1}^{S_l}\):Layer \((l)\) のユニット数 \(1 〜 i\) までの和
  \(\displaystyle \sum_{l=1}^{L-1}\):Layer間の数 \(1 〜 Lー1\) までの和
以上のことを示しています。
ユニット数を 0〜 にしないのは、ロジスティック回帰の時と同様に、切片項(バイアス項)に対応する値を取り除いているからですね。

具体例を挙げると、
Layer1のユニット数:400、Layer2のユニット数:25、Layer3のユニット数:10、layer数:3 とすると以下のようになります。

ニューラルネットワークでも、目的関数は仮定関数が予測した値と集めてきたデータとの誤差を示すということに変わりはありません。これで、ニューラルネットワークへのフィッティングに使用する目的関数を得ることができました。

目的関数が最小になるような最適な\(Θ\)を得るために、次の工程に移ります。

バックプロパゲーション

ここでの目的関数は、ニューラルネットワーク内のすべての重み付けパラメーター\(Θ\)によって計算されることから、たくさんの\(Θ\)を変数にとります。
よって目的関数に対するネットワーク内の任意の重み\(Θ\)の偏微分を求めることができれば、最急降下法やその他の最適なアルゴリズムを用いて\(Θ\)を修正し、目的関数を最小化することができるはずです。

微分は、関数の一瞬の変化の割合(傾き)を示すもので、偏微分は、複数ある変数のうち1つの変数以外を定数とみなして微分することです。つまり、ニューラルネットワークの目的関数に対する偏微分値は、各\(Θ\)が変化した時に目的関数がどれだけ変化するかを示しています。
ここでは、バックプロパゲーション(誤差逆伝播法)と呼ばれる方法で、目的関数を各\(Θ\)で偏微分した値を求めていきます。

それでは、バックプロパゲーションを用いて、各\(Θ\)の偏微分値を求めるアルゴリズムを見ていきましょう。

① データセットが以下のように与えられた時…

\({(x^{(1)},y^{(1)}) , (x^{(2)},y^{(2)}) , … , (x^{(m)},y^{(m)})}\)

(集められたデータ数が\(m\)個で、\(i\) 番目の \(x\) が \(i\) 番目の \(y\) に対応しています)

計算結果を一時的に記憶する「\(Δ_{ij}^{(l)}\)」を定義し、0としておきます。
(目的関数\(J(Θ)\)を各Θで偏微分した値を計算するために、後ほど使用します)

\(l\) は対応する層数を示し、\(i\) は Layer \((l + 1)\) のユニット番号、\(j\) は Layer \(l\) のユニット番号を表しています。

以下の ② 〜 ⑤ の工程を、サンプル数(\(t\) = 1 to \(m\)) だけ繰り返していきます。

② フォワードプロパゲーションを行い、各層の activation unit を求める

入力層から出力層へと向かって、各層の activation unit を計算していきます。

簡略化のために下付き文字は省略しています。
ここでは、入力層の特徴量 x もそれぞれ activation unit \(a_{i}^{(j)}\) で表します。(1層目なので \(l = 1\) です)
\(z\) は、\(Θ\)により重み付けを受けた activation unit を表します。それを受けて、シグモイド関数で非線形変換したものを次の層の activation unit としています。
また、各層でバイアス項 \(i = 0\) のノードも追加しています。

③ 得られた出力層の activation unit \((j = L)\) と実測値のラベル \(y\) との誤差 \(δ\)を求める。

\(δ_{j}^{(l)}\)は各層での、予測値と実測値の誤差を示します。(各層 \(l\) の各ユニット \(j\) に対して誤差を求めます)

まずは、②で得られた activation unit と 集められたデータセットのラベル \(y\) を使用して、出力層での誤差 \(δ\) を求めます。ここでは、以下のようになります。

④ 各層における誤差 δ を計算する

③で求めた、予測値と実測値の差\(δ^{(L)}\)を基に、出力層から入力層に向かって1つずつ戻っていきながら各層の誤差\(δ^{(L – 1)} , δ^{(L – 2)} , … , δ^{(2)}\)を計算していきます。(1層は入力層なので、誤差の計算からは除きます)

\(δ\) は以下の式で計算します。

⑤ \(Δ\)のアップデート

④に伴なって、\(Δ\)をアップデートしていきます。(それぞれの層で計算した誤差を、\(Δ\)に追加していきます)

⑥ 偏微分値を求める

最終的な偏微分値\(D\)は、\(Δ\)の平均値(使用したdata set数 \(m\)で割る)を取って正則化したもので、以下のようになります。

(正則化では、バイアス項に対する\(Θ\)は考慮しないので、\((j = 0 / j ≠ 0)\) で場合分けをしています)

これで偏微分値を求めることができたので、最急降下法や fminunc などの高度な最適化アルゴリズムを用いて重み付けパラメーター\(Θ\)を求めることができるようになりました。

ニューラルネットワークをトレーニングする際の注意事項

・\(Θ\)の初期値を0にするとうまくいかないので、値をランダムにする必要があります。(ニューラルネットワークの構造上、すべてのユニットが全く同一の入力の関数を計算することになり、効果的ではありません)

・バックプロパゲーションにエラーがないか調べるには、gradient checkingをと呼ばれる手法が用いられます。
目的関数に対する各\(Θ\)での偏微分値を数値的に求め、\(D\)と近い値になっているかどうかを確認します。

\(ε\)はとても小さい値(\(10^{-4}\)など )を用います。
 (gradient checkingは、バックプロパゲーションと比較すると計算速度が遅いので、エラーの有無の確認のみに使用します)

(まとめ) ニューラルネットワークを実装するためには…

⓪ ニューロン同士の接続のパターン(アーキテクチャ)を決める
 インプットユニットの数:特徴量\(x\)の次元数
 アウトプットユニットの数:カテゴリーの数(例:\(y=[1,2,3,4]\))
 hidden layer は基本1層、それ以上にする場合は、各層で同じ数の hidden unit を持つことが良いとされているそうです。
 (hidden unit は多ければ多い方が良いですが、もちろん計算コストも上昇します)

① パラメーターΘを0付近のランダムな小さな値で初期化する

フォワードプロパゲーションを実装する
 (予測値と実測値の差を計算します)

③ 目的関数を導入する。

④バックプロパゲーションを実装、目的関数に対する各Θの偏微分値を計算する
(フォワードプロパゲーションからバックプロパゲージョンまで、まずは for loop での実装することをおすすめする。とのことです)

⑤ gradient checkingで、計算した偏微分の項と比較、似たような値か確認する
 (確認後はgradient checkingを使用しないようにしましょう)

⑥ 最急下降法や fminunc などの高度な最適化アルゴリズムを用いて、目的関数の最小化を試みる


4,5週目はニューラルネットワークについてでした。
最近ではよく耳にする言葉ですが、実は10年ほど前まではあまり注目されていなかったそうです。技術が進歩したおかげで、計算コストが高く有用でなかったアルゴリズムも活用できるようになってきたということでしょうか。

全体を通して、この章が最もハードだったのかなぁと思います。ここを超えたら楽になると思うので、学習中の方は頑張ってください!
6週目は、学習アルゴリズムの評価方法などについて学習していきます。

コメント

タイトルとURLをコピーしました