深層学習ことはじめ その7

これから数回にわたって深層学習についての記事を書きます.ひとまとめに長文としたものを数回に分けて紹介していきます.初学者向けです,何かの参考になれば.前回の記事を読んでいない方は先にそちらを見てください.

******

バックプロパゲーションによるニューラルネットワークの訓練

閉じた形で「WとVを解く」という方法はありません。微積分学から、これを行う典型的な方法は導関数を見つけてそれを0に設定することであることを思い出してください。代わりに勾配降下と呼ばれる方法を使って目的関数を「最適化」しなければなりません。使用する目的関数は何ですか?

J = -sum [n = 1..N] {sum [k = 1..K] {T [n、k] * logY [n、k]}}

これは単なる負の対数尤度です(マルチクラスクロスエントロピーコスト関数とも呼ばれます)。あなたがどのようにしてダイスロールのデータセットを与えられたダイスの面の可能性を計算するかについて考え、そしてそれの負の対数を取る、そしてあなたは同様の形で結果を得るべきである。すなわち、
Likelihood= prod [n = 1..N] {prod [k = 1..K] {Y [n、k] ^ T [n、k]}}

そして、あなたが自分のラベル/ターゲット変数(今ではT)が前述したような指標マトリックスになると、マトリックスは2次元なので、上記のように2つのインデックスnとkを持つ必要があります。 Numpyでは、これは次のように計算できます。

def cost(T, Y):
return -(T*np.log(Y)).sum()

では、目的関数ができたので、それをどのように最適化すればよいのでしょうか。 「勾配降下」と呼ばれる方法を使用します。ここでは、最小値に達するまで、WとVを基準にしてJの勾配に沿って「移動」します。グラデーションの方向に沿って進むことによって、私たちが始めた場所よりも常に「低い」Jで終わることを自分自身を納得させてください。一般に、私たちがhttps://udemy.com/data-science-deep-learning-in-python のコースで行っているように、Numpyでニューラルネットワークを自分でコーディングする方法を知りたいのでない限り、勾配の計算方法を知ることは必要ありません。eBookフォーマットを使用して数式(LaTeXなど)を含めるのは自明ではないので、ここでコースにリンクします。d = 1..D、m = 1..Mとすると、W(隠れ重みへの入力)、b(隠れバイアスへの入力)、V(出力重みへの隠れ)、およびc(出力バイアスには隠れています),

dJ/dV(m,k) = sum[n=1..N]{ (Y[n,k] – T[n,k])*Z[n,m] }
dJ/dc(k) = sum[n=1..N]{ Y[n,k] – T[n,k] }
dJ/dW(d,m) = sum[n=1..N]{ sum[k=1..K]{ (Y[n,k] – T[n,k])*V[m,k]*Z[n,m]*(1 – Z[n,m])*X[n,d] }}
dJ/db(m) = sum[n=1..N]{ sum[k=1..K]{ (Y[n,k] – T[n,k])*V[m,k]*Z[n,m]*(1 – Z[n,m]) }}

隠れ層でシグモイド活性化関数を使用していると仮定したので、Z = sigmoid(a)、dZ / da = Z(1 – Z)の場合:Z = tanh(a)、dZ / da =(1 – Z2)Z = relu(a)であれば、dZ / da = u(Z)となります。ここで、u()は単位ステップ関数です。あなたは自分自身で勾配を導き出そうとするべきです。それは微積分法の連鎖則といくつかの一般的な微分則を必要とするだけです。グラデーションを見つけたら、その方向に小さなステップを踏みます。あなたのステップが大きすぎると、前後に跳ね返って峡谷の「反対側」にたどり着くことになるでしょう!したがって、重みの更新は次のようになります。
weight = weight – learning_rate * gradient_of_J_wrt_weight
より「数学的」な形式です。w = w – learning_rate * dJ / dwここで、学習率は非常に小さい数、つまり0.00001です。注:数値が小さすぎると、勾配降下に非常に長い時間がかかります。学習率を選択するための「経験則」はほとんどありません。経験があなたの最善の策です(すなわちちょうどそれを試してください)。それだけです。

もしこれがうまくいくことをあなた自身に納得させたいのであれば、すでに解き方を知っている関数、例えば二次関数を最適化することを試みることをお勧めします。たとえば、目的はJ = x ** 2 + xとなり、Jの勾配は2x + 1なので、最小値は-1/2になります。この更新式はニューラルネットワークに関するものであるため、わずかな問題が1つあります。つまり、グローバルミニマムを持つロジスティック回帰とは異なり、ニューラルネットワークではローカルミニマムの影響を受けやすくなります。だからあなたはあなたのエラーカーブが落ちて、そして結局フラットになるのを見るかもしれません、しかしそれが到達しようとしている最終的なエラーは可能な限り最良の最終的なエラーではありません。運動量のようないくつかのより高度な方法は、この問題を軽減するのを助けることができます。これらについては後で簡単に説明しますが、この記事の焦点では​​ありません。なぜ「バックプロパゲーション」と呼ばれるのですか。ニューラルネットワークを考えてみましょう。ここで、x、y、およびzの通常の「マルチノード」ベクトル表現を、それらのベクトルを表す単一ノードに置き換えました。より深いネットワークを検討すると、これはより便利になります。もしあなたが多変数微積分学に精通していて、あなたが自分自身でJの勾配を導き出そうとしたいのであれば、いくつかのパターンに気づき始めるでしょう。まず、「y」の誤差は常に「y – t」であることです。ここで、tはターゲット変数です。重みVは、「y – t」 – yにおける誤差 – に依存します。

Wの勾配を導き出すと、それはzの誤差に依存することがわかります。このネットワークを1つ以上の隠れ層を持つように拡張した場合、同じパターンに気付くでしょう。これは再帰的な構造であり、次のセクションのコードで直接見ることができます。重みの誤差は、すぐ右側のノードでの誤差に常に依存します(それ自体が右側の誤差などに依存します)。このグラフィカル/再帰的な構造により、TheanoやTensorFlowのようなライブラリは自動的に勾配を計算できます。

コメント

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