"機械学習","信号解析","ディープラーニング"の勉強

HELLO CYBERNETICS

深層学習、機械学習、強化学習、信号処理、制御工学などをテーマに扱っていきます

現代のニューラルネットワーク描像

 

 

ニューラルネットワークは深層学習(ディープラーニング)によって復活し、多層化されるにつれ、ネットワークのユニット1つ1つに関して注目する機会はさほど多くなくなりました。

元々はニューロン同士の結合を表現したモデルであったため、その繋がりを意識してユニット毎の記述が多かったのですが、現代ではこれを1層をベクトルと捉えたほうが都合がいいです。

 

 

 

 ニューラルネットワークとは

古典的な描像

下記の図で行くと中間層(hidden layer)のj番目のユニットは活性化関数f(・)により、

 

z_j = f \left( \sum_{i=1} ^3 w_{ji}x_i +w_0 \right)

 

を出力すると表現します。

 

f:id:s0sem0y:20160314093558p:plain

 

同様に、出力層(output layer)のk番目のユニットは

 

y_k = g \left( \sum_{j=1} ^3 v_{kj} x_j +v_0 \right)

 

を出力することとなります。このy_kは、入力xに応じてそれぞれどういう出力をして欲しいかが決まっているため、上手く出力を表現できるようにw,vを調整していくのが学習ということになります。

各ユニットはニューロンを表現しており、ニューロン同士の繋がりをw,vで表現しているというのが本来のニューラルネットワークの表現になります。従って上記のように各ユニットを明示的に書いて導出されるのが基本となっています。

 

深層学習の到来による現代的な描像

高精度な情報処理が可能となったディープラーニングでは、ユニットも層の数も桁違いです。また、情報処理はコンピュータによって行われるのでプログラミングとの親和性も要求されます。従って、例外的な表現がされているもの(ここで言うとw_0)は都合がよくありません。

 

z_j = f \left( \sum_{i=1} ^3 w_{ji} x_i +w_0 \right)

 

これはダミー変数x_0=1を導入しておくことで

 

z_j = f \left( \sum_{i=0} ^3 w_{ji}x_i \right)

 

とまとめてしまうことができます。しかもこれはベクトル{\bf x} =(x_0,x_1,x_2,x_3)^Tとベクトル{\bf w_j}=(w_{j0},w_{j1},w_{j2},w_{j3})^Tとの内積であると表現できますから

 

z_j = f \left( {\bf w_j^Tx} \right)

 

と表現することができます。これが、j=1,2,3とあるわけですから、

 

z_1 = f \left( {\bf w_1^Tx} \right)

z_2 = f \left( {\bf w_2^Tx} \right)

z_3 = f \left( {\bf w_3^Tx} \right)

 

それぞれ{\bf z}=\left(z_1,z_2,z_3 \right)とし、関数{\bf f}は各成分ごとに作用するとして

 

\bf z = f(Wx)

 

と非常に単純な形で表すことができます。すなわち、各層から各層へが「ベクトル」が渡される際に、線形変換を受け、更に各成分毎に活性化関数の作用を受けるということです。ここではもはやユニットという個々のことはほとんど意識せず、ベクトルというデータが変換されていく様のみが思い浮かびます。

f:id:s0sem0y:20161031001929p:plain

 

各層のユニットの数は行列Wのサイズを指定し、層は何個の行列Wと活性化関数fを準備するのかということに相当します。現代のニューラルネットワークは、データの次元を線形変換で調整しながら、活性化関数により適当な非線形変換を行い、入力に対する望んだ出力を行う合成関数を獲得しようというものだと理解できます。

 

ニューラルネットワークの課題

活性化関数をどうするか

出力層の活性化関数に関しては解きたい問題に応じて基本的には決まっています。

分類問題ならば、クラスの数だけの次元を持ったベクトルを出力として、ソフトマックス関数により最も大きな成分のクラスに割り振るというのが常套手段です。回帰問題ならば恒等関数で大体良いでしょう。

 

中間層で用いる活性化関数は線形正規化関数が最も良いとされ、実際のプログラムでは以下の式が用いられています。

 

max(0,{\bf x})

 

入力されたベクトルの、正の成分のみを残し、他は全て0にするという単純な関数です。この関数は、正の領域において微分が1、負の領域においては0であり、勾配の計算も楽であることから最適化で有利なことがわかります。

ニューラルネットが登場した当初はシグモイド関数が用いられ、特に以下の

 

sigm({\bf x})=\frac{1}{1+\exp ({\bf x})}

 

ロジスティックシグモイド関数が代表的です。他にもtanh(・)を用いることもできます。

 

線形変換Wの学習に関して

この手法を考えるのがニューラルネットワークにおいて最も重要な課題です。

逆誤差伝播法が登場してから、ニューラルネットワークの全ての層を計算できるようになりましたが、収束の遅さや勾配消失の問題があり実用化は困難を極めました。

全ての層を学習するのではなく、一層一層貪欲学習を行う事前学習が、ディープラーニングの契機となり、学習次第で多層のニューラルネットが高い処理能力を示すことが発見されました。

 

今では、多層化によって表現力が増すと信じられ、その膨大な計算量を持つ学習を如何に効率よく行うかが課題となっています。GPGPUなどの利用によりハード面から計算を強化していく方法や、パラメータの更新を並列処理してしまう(パラメータの値をロックしない)方法などが提案されています。

 

中でもアルゴリズムの立場からは、最適化手法を改善することが注目されており、下記に有用なものを載せておきます。

 

s0sem0y.hatenablog.com

 

 

学習を行う際のハイパーパラメータ

行列Wのサイズは予め決めておき、その成分を計算するのが学習です。行列のサイズは変換されたベクトルの次元を指定することになり、古典的描像ではユニットの数に相当します。これをどのように設定しておくかによって学習の精度は変わるかもしれません。

 

予め行列のサイズはかなり大きめに取っておくことで、ベクトルの次元を膨大にしておきながらも、実際にはベクトルの殆どの成分が0であるように学習を行う方法があります。どの程度の成分が0でどの程度の成分が実際に値を持つかは不明ですが、これもスパース性として予め設定しなければならないハイパーパラメータとなります。またスパース性を満たさない場合に、学習の損失関数にペナルティーを与えなければならず、その大きさも設定が必要です。

 

また、行列の成分の値がヤケに大きくならないよう、各行ベクトルのノルムにペナルティーを設ける場合もあります。通常2ノルム正則化と呼ばれる方法ですが、これは過学習を防ぐ有名な手法です。このペナルティーに関しても設定しなければなりません。

 

当然損失関数を減少させる勾配方向に、どれだけの大きさ更新させるかを決めるのも非常に重容な課題です。この学習率の決定則が最適化の大きな研究課題でもあります。

 

まとめ

現代のニューラルネットワークは、高階の合成関数です。

高階の合成関数はあらゆる問題に対する表現が可能だと信じられています(理論上は)。

高階の合成関数が持っているべき性質をハイパーパラメータで指定します(現状、勘)。

設定が上手ければ、自動的に問題を解く表現に落ち着くでしょう。

 

これが現在のニューラルネットワークへの解釈です。そう考えると、深層学習は使って見るぶんにはそう難しいものではありません。むしろ、誰でもこれを試してみることができます。対象に対する専門知識なしに、上手くネットワーク設計ができれば問題が解けてしまうのです。

(問題に応じてネットワークの構成自体も変えることがあります。RNNは時系列(発生順序に意味があるデータ)に対して、CNNは画像データに対して特に有効であることが知られています。)

 

幾つかのIT企業が、人工知能と称してこのデータ解析ツールを提供し始めています。誰もがExcelをある程度使えるように、誰もがニューラルネットを使って何かを解析するようになるかもしれません。そういう生活に身近なレベルにまで浸透していくことが、現代のニューラルネットには期待できそうです。