Notebookでも公開しています。この投稿では、1から3階層のシンプルなニューラルネットワークを構築します。出てくる全ての数学の解説はしませんが、可能な限り必要な部分は、わかりやすく説明したいと思います。数学の詳細が気になる方は、英語が多いですが参考になるリンクを下記で記載します。※この投稿の読者は最低限、微分と機械学習の基礎(クラシフィケーションや正則化など)を知っていると仮定します。Descent(勾配降下法)のような最適化技術を知っていれば、なお良しです。上記を知らなくても、ニューラルネットワークに興味のある方なら楽しめる内容だと思います。それではまず、なぜライブラリーを使わずに一からニューラルネットワークを構築する必要があるのでしょうか?後の投稿でPyBrainやTensorflowのようなニューラルネットワーク・ライブラリーを使う予定ですが、その理由としては、1度でも一からニューラルネットワークを構築するという経験はすごく価値があるからです。どのようにしてニューラルネットワークは動くのか・構築されているのかを知ることによって、いざモデルをデザインするぞ!という時に役立ちます。1つ注意点として、この投稿では理解しやすさに重きをおいているため、下記のコードは効率的に書かれていません。効率的なコードの書き方は後の投稿で解説します。その時は、Theanoを使います。データを生成するさて、まずはデータを生成します。ラッキーな事にScikit-learnは使えるデータセットの生成キットがあるので、わざわざ自分たちでコードを書く必要がありません。今回は、make_moons機能を使って月型のデータを作ってみましょう。(グラフ上の赤と青の点)。青い点を男性、赤い点を女性の患者データサンプルとして、XとY軸を特定の測定数値と考えてみてください。私達の目標は分類モデルを機械学習させて、サンプルポイント毎に正しいクラスを予測して与えることです。注意しないといけないのは、このデータは直線では分類が不可能であるという点です。(非線形特性)を自分で作るなどしない限り、良いモデルを作ることはできません。今回のデータに関しては、多項式特性を率いれば良いモデルを作ることは可能です。ニューラルネットワークを率いれば、この問題を解決できます。(特性エンジニアリング)をする必要がないからです。ニューラルネットワークの隠れ層が特性を探しだしてくれます。ロジスティック回帰ニューラルネットワークの説明をする前にまず、ロジスティック回帰モデルを学習させてみましょう。ここでは下記のニューラルネットワークの解説の下準備なのでschikit-learnを使ってロジスティック回帰モデルを構築してみましょう。(決定境界)を境にクラスの分類をしています。この境界線は直線を率いて可能な限りクラス分けをしていますが、データの「月型」を認識することはできていません。(1インプット層、1隠れ層、1アウトプット層)を構築してみましょう。(ちなみに2つのクラスなので1か0の1つをアウトプット・ノードにすることも可能ですが、後で複数のクラスを扱うのを考慮して今回は2つのノードを使います)。(男性)のどちらかになる確率です。下記の図を参照してみてください。(ノードの数)を決めます。隠れ層ノードの数が増えれば増えるほど複雑なモデル構築が可能です。一方で、ノードの数が増えるほど、パラメーターの学習と予測にコンピューティングパワーが必要になります。パラメーターの数が増えるほどオーバーフィットのリスクが増してしまうため注意する必要があります。隠れ層の数はどうやって選べば良いでしょうか。一般的なガイドラインはあるものの、選び方はケースバイケースで、サイエンスというよりもアートに近いと考えてください。下記では、いくつか違う隠れ層のノード数を試してみて、どのようにアウトプットに影響をあたえるのかを見てみます。一つ決めないといけないのが、隠れ層のアクティベーション関数です。(transform)させてアウトプットするための関数です。非線形アクティベーション関数を率いることで非線形データを学習させることができます。アクティベーション関数の一般的な例として、Tanh、シグモイド関数、そしてReLUsがあります。今回は様々なケースで比較的よい成果を出せるtanhを使ってみます。この関数の便利な特性として元の値を率いて微分した値を計算できる点です。tanh^2x$です。そのため、$tanhx$を一度計算すると後で再利用が可能です。今回は、アウトプットに確率を与えたいので、アウトプット層のアクティベーション関数にSoftmax関数を使います。この関数を率いることで非確率な数値から確率に変換できます。ロジスティック回帰モデルに詳しい方は、Softmax関数を複数クラスの汎化版として考えてみてください。propagationという一種の行列乗算と上記で定義したアクティベーション関数の応用を使います。$\hat{y}$(こちらも2次元)は下記のように計算します。$z_i$はインプット層i、$a_i$はアクティベーション関数で変換後のアウトプット層iです。$b_2$はネットワークのパラメターで、学習用データから学ぶ必要があります。ネットワーク層間の行列変換と考えてよいでしょう。上記の行列乗算を見てみると行列の次元数が見て取れます。\mathbb{R}^{2}$となります。そのため、隠れ層のサイズを増やすとパラメーターも増える理由がわかりますね。$b_2$)を探す、ということです。エラー値はどうやって定義するのでしょう?エラー値を測る関数をLoss関数と言います。likelihoodとも呼ばれています)を率います。N学習用データがありCクラスがある時の正解値yに対して予測値$\hat{y}$のLoss関数は下記のように書くことができます。この方式は複雑なように見えますが、その役割は、学習用データを足し合わせ間違えてクラスを予測した時に、その値をLossに足す、というシンプルなものです。そのため予測値$\hat{y}$と正解値yの2つの確率分布が遠く離れていればいるほど、Lossは大きくなります。そのため、Lossを最小化するパラメーターを探すということは、学習用データの尤度を最大化させることと同じことです。(勾配降下)を使います。(学習率は定数)を率いますが、確率的勾配降下やミニバッチ勾配降下がより実用的でしょう。学習率も徐々に小さくしていく方がより実践的です。(ベクトルの微分値)を計算する必要があります。この傾斜を計算するためにback-propagationアルゴリズムを使います。このアルゴリズムは、アウトプットから傾斜を効率的に計算する方法です。back-propagationを使うと下記が成り立ちます。実際にコードを書いてみるこれまでの学問的な知識はおしまいにして、実際にコードを書いてみましょう!まずは勾配降下のための変数とパラメーターを設定してみましょう。regularizationの強さ上記で定義したLoss関数を書いてみます。これを率いてモデルの性能をチェックできます。data_lossアウトプット層を算出するためのHelper関数を書きます。propagationを率いて、一番高い確率を返します。axis=1)最後に、ニューラルネットワークを生成するコードを書きます。上記で解説したbackpropagationの微分値を使ってバッチ勾配降下を書きます。model隠れ層が3つのニューラルネットワークそれでは、隠れ層が3つの場合のネットワークを生成します。3")うまく月形を認識しました!ニューラルネットワークによってクラスを程よく分けることができていますね。隠れ層の適合サイズをチェック上記では隠れ層3つを選びました。下記では隠れ層の数を変えながら比較してみましょう。(3,4あたり)データのパターンをうまくつかめています。一方で、高次元だとオーバーフィットの恐れがあるようです。なってしまえば、データの真の形を捉えるのではなくデータの丸暗記をしているようなものです。テストデータを率いてモデルをチェックする場合、低次元の隠れ層だとより正確に予測できるはずです。オーバーフィットを強めに正則化するよりも、ちょうど良いサイズの隠れ層を選んだ方がより(コンピューター的に)「経済的」でしょう。今回は一からライブラリーを使わずにネットワークを作ってみました。次はニューラルネットワーク・ライブラリーを使って更に深くディープラーニングを解説してみます。upLoginユーザーは見つかりませんでした。