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

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

******

You know more than you think you know

デジタルフォーマットについての素晴らしいところは、望むように頻繁にこの記事を更新できることです。この記事は、最新の優れた研究ではなく、基本を説明するために作成されたものです。率直に言って、そのようなものを理解することはあなたに何ヶ月もあるいはおそらく何年もの努力を要するでしょう。基本がなければ、とにかく意味があるわけではありません。さて、あなたはこの記事を読んで、「ちょっと待って – ロジスティック回帰を積み重ねてから勾配降下を行う方法だけを教えた」と考えたかもしれません。これはロジスティック回帰の実行からすでにわかっているアルゴリズムです。これの本当の美しさ。教師としての私の仕事は、学生としてあなたにとって物事が簡単に見えるようにすることです。すべてが単純すぎると思えば、私は仕事を終えました。補足として、私は彼らが何かを懸命に学ぶ必要があるように感じさせるのは人のエゴだと思います。あなたのエゴがあなたの学習の邪魔にならないようにしてください。さて、最後の章はあなたが知らないことをあなたに見せることに基づいていましたが、この章はあなたがあなたが知っていることをあなたに見せることに専念しています。ロジスティック回帰まず、ロジスティック回帰に戻りましょう。教師付き機械学習モデルはすべて同じAPIを持っていることを忘れないでください。 (X、Y)を訓練し、(X)を予測するロジスティック回帰の場合、これは簡単です。予測は次のとおりです。
y = s(Wx)

トレーニングも同様に簡単です。コストの導関数を取り、その方向に進みます。
W = W – a * dJ / dW
それでは、ニューラルネットワークを見てみましょう。予測はほぼ同じですが、追加のステップが1つあります。
y = s(W1s(W2x))
以前と同じこと導関数を取り、その方向に移動します。
Wi = Wi – a * dJ / dWi
ニューラルネットワークは任意の深さにすることができるので、W1、W2、W3などを使用できます。畳み込みニューラルネットワークはどうですか?ここでも予測は、単に1つの新しいステップを追加するだけです。
y = s(W1s(W2 * x))
*演算子は畳み込みを意味します。これは信号処理や線形システムなどのコースで学びます。

CNNをどのように訓練するのですか?実は以前と同じです。導関数を取り、その方向に動かしてください。
Wi = Wi – a * dJ / dWi
うまくいけば、ここにパターンが見えています。リカレントニューラルネットワークはどうですか?畳み込みネットを使って1つ新しいことを紹介したのと同じように、ここで1つ新しいことを紹介します。特に、最初の計算(隠れユニットの状態)が最後の値に依存するように、2つの計算を分割します。予測は次のようになります。
h(t)= s(Wxx(t)+ Whh(t-1))y(t)= s(Woh(t))
これらを訓練する方法は、コスト、そしてその方向に動くなら、あなたは正しいでしょう!
Wi = Wi – a * dJ / dWi

さて、TheanoやTensorFlowのような自動微分が可能なツールを使えば、心配することが1つ少なくなります。
W = W – learning_rate * T.grad(cost、W)
実際、ほんの一握りのニューラルネットワークアーキテクチャが「バブルアップ」した唯一の理由はここにあります。上に移動するのは、彼らがうまく行ったからです。しかし、ベンチマークデータセットのパフォーマンスが良いからといって、有能なディープラーニング研究者になることはできません。研究者が単に新しいアイデアを試みているところで多くの論文が発表されています。それらは最先端技術と比較して優れた性能を持っていないかもしれませんが、彼らは同等の性能を発揮するかもしれません、それはまだ面白いです。成功か失敗かに関わらず、すべての研究が私たちを今日の状況に導きました。人々がニューラルネットワークを何十年もあきらめたことを忘れないでください。これは創造性とより大きく考えることについての詳細です。

 

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

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

******

教師なし学習、オートエンコーダ、制限付きボルツマンマシン、畳み込みニューラルネットワーク、およびLSTM

この時点で、あなたは私がディープラーニングの「基本」と考えるものをすでに学んでいます。これらは、より複雑なニューラルネットワークに引き継がれる基本的なスキルです。これらのトピックは、より複雑な形式ではありますが何度も繰り返されます。しかし、「あなたがあなたが知らないことを知らない」という場所にあなたを置きたくはありません。ディープラーニングについてもっと学ぶことがたくさんあります!ここからどこへ行きますか。さて、この記事は主に「教師あり学習」に焦点を当てていますが、これはほとんどの人にとってずっと理にかなっていると思います。機械に「正しく」実行する方法の例を示すことによって、その動作方法を教える一方で、何かが正しく実行されない場合は「ペナルティを課す」ことをお勧めします。しかし、ニューラルネットワークがトレーニングできる「最適化」機能は他にもあります。ラベルを必要とすることすらありません。これは「教師なし学習」と呼ばれ、k平均クラスタリング、ガウス混合モデル、主成分分析などのアルゴリズムがこのファミリに分類されます。ニューラルネットワークには、教師なし学習を実行するための2つの一般的な方法があります。それは、オートエンコーダと制限付きボルツマンマシンです。驚くべきことに、これらの教師なしの方法のいずれかを使用してニューラルネットワークを「事前トレーニング」すると、最終的な精度が向上します。ディープラーニングは強化学習(エラー関数ではなく報酬ベース)にもうまく適用されており、Flappy BirdやSuperなどのビデオゲームをプレイするのに役立つことが示されています。

特別なニューラルネットワークアーキテクチャが特定の問題に適用されてきました(この記事では抽象的な意味でデータについて話してきましたが)。画像分類については、畳み込みニューラルネットワークがうまく機能することが示されている。これらは畳み込み演算子を使ってデータを最終的なロジスティックレイヤに送る前にデータを前処理します。配列分類に関しては、LSTM、または長期短期記憶ネットワークがうまく機能することが示されている。これらは特殊なリカレントニューラルネットワークであり、最近まで研究者達は訓練するのが非常に難しいと言っていました。ディープラーニングの適用について、他にどのような分野を考えましたか?株式市場?ギャンブル?自動運転車ですか?未開発の可能性がたくさんあります。

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

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

******

正則化

L1およびL2正則化は長い間よく知られており、ニューラルネットワークが目立つようになる前に適用されてきた。 L1正則化は、単純に、重みの絶対値に定数を掛けたものに通常のコストを加えたものです。
J_L1 = J + L1_const *(| W1 | + | b1 | + | W2 | + | b2 | +…)
同様に、L2正則化は、通常、重みの2乗に定数を掛けたものに追加されます。
J_L2 = J + L2_const *(| W1 | 2 + | b1 | 2 + | W2 | 2 +…)
これは要素ごとの二乗であることに注意してください。場合によっては、L1とL2の両方の正則化を同時に使用できます。この2つの違いは何か?どちらも無限大になることから重みにペナルティを課します(シグモイド前の活性化が可能な限り無限大に近づくことを望んでいるので、それらはやるべきことです)。
違いは、平方関数の導関数が0に近づくにつれて0になることです。したがって、L2正則化は重みを小さくすることを推奨します。しかし、それらが小さくなると、ペナルティも小さくなり、ペナルティの勾配も小さくなるため、L2正則化の影響はここでは減少します。絶対値関数の導関数は0の両側で一定です。したがって、実際に0になるまで、重みが小さい場合でも勾配は同じままです。勾配は技術的に定義されていませんが、次のように扱います。 0なので、おもみは動きません。したがって、L1正則化は、重みが0になるように推奨される「希薄性」を助長します。これは、統計学者が少数の非常に影響力のある効果に関心を持つ線形回帰の一般的な手法です。

早期停止

バックプロパゲーションを早期に停止することは、別のよく知られている正則化の方法です。非常に多くのパラメータで、あなたは過剰装備に縛られています。バリデーションセットのコストが上がると、やり過ぎになる可能性があるため、早めに作業を中止するためにバリデーションセットを使用することもできます。

ノイズインジェクション

トレーニング中に入力にランダムノイズを追加することは、さらに別の正規化方法です。通常、平均が0で分散が小さいガウス分布確率変数を選択します。これは、より多くのデータを持つことをシミュレートし、より堅牢な予測子になります。

Data Augmentation

あなたの画像のラベルが “犬”だとします。あなたのイメージの中心にいる犬は犬として分類されるべきです。右上、または左上、または右下、または左下に犬がいるように。逆さまの犬はまだ犬です。色が少し違う犬はまだ犬です。独自のデータを作成し、元のデータと手作りのデータの両方についてトレーニングを行うことで、ニューラルネットワークに同じもののさまざまなバリアントを認識させることで、より堅牢な予測子が得られます。私が上述したのは並進不変性、回転不変性、そして色不変性でした。

DropOut

ドロップアウトは、その効果のためにディープラーニングコミュニティで非常にポピュラーになった新しいテクニックです。ノイズがガウス分布ではなく、2項ビットマスクになっている点を除けば、ノイズ注入と似ています。言い換えれば、ニューラルネットワークのすべてのレイヤで、そのレイヤのノードにビットマスク(レイヤと同じサイズの0と1の配列)を乗算するだけです。通常、1(これをpと呼びます)の確率を隠れ層で0.5、入力層で0.8に設定します。これが効果的に行うことは、ニューラルネットワークのアンサンブルを作成することです。すべてのノードは「オン」または「オフ」のどちらかである可能性があるため、この手法は2 ^ N個のニューラルネットワークの集合体をエミュレートします。
ノードの値を0に設定することは、ネットワークからノードを完全に「削除」することと同じであるため、この方法は「ドロップアウト」と呼ばれます。トレーニング段階では、ノードを0に設定するだけです。予測段階では、代わりにノードの発信ウェイトにそのノードのpを掛けます。これは実際に各アンサンブルの出力を計算し、結果の予測を平均化するための近似値ですが、実際にはうまく機能します。

1つの問題

これらすべての方法に共通する点は何か? うまく機能しますが、それでも大きな問題が1つあります。それらは、モデルにハイパーパラメータを追加することです。 したがって、ハイパーパラメータ検索空間はさらに大きくなる。

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

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

******

現代の手法による逆伝搬の改善 – 運動量、適応学習率、および正則化

ここで説明するテクニックはすべて簡単に説明できます。しかし、この単純さはそれらの有用性を隠し、少し誤解を招く可能性があります。しかし、私たちがここで行っているのはコンピュータサイエンス、つまりプログラミングであることを忘れないでください。

Momentum

勾配降下における運動量は、物理学における運動量のように働く。あなたがすでに特定の方向に動いていたならば、あなたはその方向に動き続け、あなたの運動量によって進められます。運動量は最後の体重変化として定義される。次の重みの変化は、重みに関するコストの勾配と運動量の両方の関数です。
w(t)= w(t-1)+ mu * v(t) – learning_rate * dJ(t)/ dw
ここで、muは運動量パラメータと呼ばれます(通常は0.99前後に設定されます)。これを次のように単純化することができます。
dw(t)= mu * dw(t-1) – learning_rate * dJ(t)/ dw
そして、
w(t)+ = dw(t)の運動量は学習プロセスを大幅にスピードアップします。適応学習率適応学習率には多くの種類がありますが、それらはすべて1つの共通のテーマを持っています – 時間とともに減少します。たとえば、10エポックごとに学習率を半分にすることができます。例えば
if epoch%10 == 0
:learning_rate / = 2

inverse decay

learning_rate = A /(1 + kt)もう1つの方法は指数関数的減衰です。learning_rate = A * exp(-kt)より現代的な適応方法はAdaGradです。これは重みの変化のキャッシュをこれまでのところ保持することを含みます。各重みの各次元には独自のキャッシュがあります。 cache = cache + gradient * gradient Numpyの規約に従って、要素ごとの乗算があることに注意してください。
w -= learning_rate * gradient /(sqrt(cache)+ epsilon)
ここで、epsilonは0で割ることを避けるために10 ^ -10のような小さな数です。研究者達はAdaGradがしばしば勾配が大きくなりすぎることを発見しました。 RMSpropはAdaGradに似たもう1つの方法で、キャッシュが「リーク」しています(つまり、以前の値のほんの一部しか保持していません)。この場合、cache = decay_rate * cache +(1 – decay_rate)* grad ^ 2そして、重み更新の公式は変わりません。

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

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

******

TensorFlow

TensorFlowは、Googleが開発したTheanoよりも新しいライブラリです。それは、勾配を計算することのように、私達にとってTheanoのような多くの素晴らしいことをします。この最初のセクションでは、Theanoで行ったような基本的な機能、つまり変数、関数、および式について説明します。 TensorFlowのWebサイトには、ライブラリをインストールするために使用できるコマンドがあります。バージョン番号は変更される可能性があるので、ここには含めません。 TensorFlowをインストールしたら、Theanoと同じように単純な行列乗算の例を行います。いつものようにインポートする:
import tensorflow as tf

TensorFlowでは、タイプを指定する必要があります(Theanoのvariablesが TensorFlowのplaceholderに対応します):
A = tf.placeholder(tf.float32, shape=(5, 5), name=’A’)
ただし、shapeとnameはオプションです。
v = tf.placeholder(tf.float32)
TensorFlowでは ‘matmul’関数を使います。私はこの名前が ‘dot’よりも適切であると思います。
u = tf.matmul(A、v)
Theanoと同様に、変数の値を「フィード」する必要があります。 TensorFlowでは、「セッション」で「実際の作業」を行います。

output = session.run(w, feed_dict={A: np.random.randn(5, 5), v: np.random.randn(5, 1)}) print output, type(output)

Tensorflowにおける最適化

TensorFlowの2次式を最適化します。答えを手で計算する方法をすでに知っているはずなので、これはTensorFlowコーディングを強化し、ニューラルネットワークをより快適にコーディングするのに役立ちます。 TensorFlow変数を作成することから始めます(Theanoではこれは共有になります)。
u = tf.Variable(20.0)
次に、コスト関数/式を作成します。cost = u * u + u + 1.0オプティマイザを作成します。
train_op = tf.train.GradientDescentOptimizer(0.3).minimize(cost)
これはTheanoと大きく異なる部分です。 TensorFlowは勾配を計算するだけでなく、パラメータの更新を指定しなくても全体の最適化を行います。これのマイナス面は、あなたがグーグルが実行した最適化方法にこだわっていることです。 RMSProp(適応学習率法)やMomentumOptimizer(過去の体重変化の速度を使って極小値から抜け出すことができる)など、純粋な勾配降下法の他にもさまざまな種類があります。フォーラムの投稿でNesterovの勢いが現在進行中であることが示されているので、私はその全リストが近い将来更新されると思う。次に、変数を初期化するためのopを作成します(この問題では、単に「u」です)。

init = tf.initialize_all_variables()
with tf.Session() as session:
session.run(init)
for i in xrange(12):
session.run(train_op)
print “i = %d, cost = %.3f, u = %.3f” % (i, cost.eval(), u.eval())

TensorFlowにおけるニューラルネットワーク

入力変数、ターゲット変数、重み変数を作成しましょう。バイアス条件は省略しました。また、Theano shared = TensorFlow変数に注意してください。X = tf.placeholder(tf.float32、shape =(None、D)、name = ‘X’)T = tf.placeholder(tf.float32、shape =(None、K) )、name = ‘T’)W1 = tf.Variable(W1_init.astype(np.float32))W2 = tf.Variable(W2_init.astype(np.float32))混乱のようなので繰り返しましょう – A Theano variable!= TensorFlow変数。可変サイズ、つまりバッチサイズ、テストセットサイズなどを渡すことができるようにするために、シェイプに「None」を指定できます。では、出力を計算しましょう(隠れ層の非線形性としてReLUを使用しています。これはシグモイドやソフトマックスとは若干異なります。Z = tf.nn.relu(tf.matmul(X、W1))Yish = tf.matmul(Z、W2)最終ソフトマックスステップ。これを行わないのは、それがコスト関数の計算方法に含まれているからです(つまり、TensorFlow関数がどのように機能するのか)。この変数をsoftmaxにしたくないのは、事実上2回softmaxを実行することになるからです。次のようにコストを計算します。cost = tf.reduce_sum(tf.nn.softmax_cross_entropy_with_logits(Yish、T))
TensorFlowのドキュメンテーションを十分に参照することで、これらの関数はおそらくなじみがなく外来のものに見えるかもしれませんが、あなたはそれらに慣れていくでしょう。 Theanoの例と同様に、train関数とpredict関数も作成します。train_op = tf.train.RMSPropOptimizer(learning_rate、decay = 0.99、momentum = 0.9).minimize(cost)predict_op = tf.argmax(Yish、1) Theanoとは異なり、重み更新式を指定する必要すらありませんでした。あなたはほとんどいつもw + = learning_rate * gradientを使うつもりなので、それは一種の冗長であると言うかもしれません。ただし、適応学習率や運動量などのさまざまな手法が必要な場合は、Googleの責任になります。幸いなことに、彼らのエンジニアはすでにRMSProp(適応学習率用)と運動量を含んでいます。これらは私が上で使用したものです。それらの他の最適化機能について学ぶためには、それらのドキュメントを参照してください。 TensorFlowでは、すべての変数オブジェクトを初期化するために特別な関数を呼び出す必要があります。 init = tf.initialize_all_variables()そして、最後に、セッション内で、トレインを実行し、関数をループで予測します。tf.Session()をsession:session.run(init)として使用します。 xrange(max_iter):xrange(n_batches)内のjに対して:Xbatch = Xtrain [j * batch_sz:(j * batch_sz + batch_sz)、]

Ybatch = Ytrain_ind [j * batch_sz:(j * batch_sz + batch_sz)、] session.run(train_op、feed_dict = {X:Xbatch、T:Ybatch})、j%print_period == 0:test_cost = session.run(コスト) 、feed_dict = {X:Xtest、T:Ytest_ind})予測= session.run(predict_op、feed_dict = {X:Xtest})print error_rate(予測、Ytest)ここでもバッチグラジエントディセントを使用しています。 error_rate関数は次のように定義されています。def error_rate(p、t):return np.mean(p!= t)Ytrain_indとYtest_indは以前と同じように定義されています。

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

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

******

Theano

Theanoは、ディープラーニングで非常に人気のあるPythonライブラリです。これまで見てきたように、勾配降下はかなり時間がかかることがあるので、それはあなたがより速い浮動小数点計算のためにGPUを利用することを可能にします。この記事では、Theanoコードの書き方を説明しますが、GPU機能を備えたマシンを入手する方法、およびそれらを使用するためにTheanoコードとコマンドを調整する方法について詳しく知りたい場合は、私のWebサイトを参照してください。 https://udemy.com/data-science-deep-learning-in-theano-tensorflow .それを設定するのは自明ではなく、AWSのユーザーインターフェースは初めての人にとっては非常に困難です。小さな画面上の単純なスクリーンショットではうまくいきませんので、ここでは説明しません。

Theanoの基本

あなたがすでにPythonを知っているときにNumpyを学ぶのは簡単ですね。特別な種類の配列を操作するための新しい関数がいくつかあります。 NumpyからTheanoへの移動は他のまったくの獣です。通常のPythonのようには見えない、新しい概念がたくさんあります。それでは、まずTheano変数について説明しましょう。 Theanoには、オブジェクトの次元数に基づいてさまざまなタイプの可変オブジェクトがあります。たとえば、0次元のオブジェクトはスカラ、1次元のオブジェクトはベクトル、2次元のオブジェクトは行列、3次元のオブジェクトはテンソルです。それらはすべてtheano.tensorモジュール内にあります。それで、あなたのインポートセクションで:theano.tensorをTとしてインポートすることができる以下のようなスカラ変数を作成することができます。c = T.scalar( ‘c’)渡される文字列は変数の名前です。ベクトルは、このように作成することができます。v = T.vector( ‘v’)そして、このような行列:A = T.matrix( ‘A’)この記事ではテンソルを使って作業していないので、そうではありません。それらを見に行きます。カラー画像を使い始めるとき、これはもう一つの次元を加えるでしょう、それであなたはテンソルが必要です。 (例:28×28の画像は、3×28×28の寸法になります。なぜなら、赤、緑、青のチャンネルに別々の行列が必要だからです)。通常のPython対Theanoの奇妙な点は、作成したばかりの変数に値がないことです。 Theano変数は、グラフ内のノードに似ています。
フィードフォワードやバックプロパゲーションなどの計算を実行したいときにグラフに値を「渡す」だけです。まだ定義されています。 TensorFlowも同じように機能します。それにもかかわらず、変数に対する操作を定義できます。たとえば、行列の乗算を実行したい場合、それはNumpyに似ています。u = A.dot(v)これは、uと呼ばれるグラフに新しいノードを作成することと考えることができます。行列を掛けます。実際の値で実際に乗算するには、Theano関数を作成する必要があります。 theanoをインポートするmatrix_times_vector = theano.function(入力= [A、v]、出力= [u])numpyをnpとインポートするA_val = np.array([[1,2]、[3,4]])v_val = np。 array([5,6])u_val = matrix_times_vector(A_val、v_val)これを使って、ニューラルネットワークの「フィードフォワード」アクションをどのように実装するかを考えてみてください。 Theanoの最大の利点の1つは、これらすべての変数を1つのグラフにリンクし、前に説明した連鎖規則を使用してその構造を使用して勾配を計算できることです。 Theanoでは、通常の変数は「更新可能」ではありません。そして、更新可能な変数を作るために、シェア変数と呼ばれるものを作ります。 x = theano.shared(20.0、 ‘x’)自分自身で解くことができ、それが大域的最小値を持つことがわかっている単純な費用関数も作成しましょう。そして、Theanoに伝えましょう。更新式を与えてxを更新する方法x_update = x – 0.3 * T.grad(cost、x)grad関数は2つのパラメーターを取ります。勾配を取りたい関数と、必要な変数です。に対する勾配後でニューラルネットワークの各重みに対して行うように、複数の変数をリストとして2番目のパラメータに渡すことができます。それでは、Theanoトレイン関数を作成しましょう。 updates引数と呼ばれる新しい引数を追加します。それはタプルのリストを取り、そして各タプルはその中に2つのものを持っています。最初のものは更新する共有変数で、2番目のものは使用する更新式です。 train = theano.function(入力= []、出力=コスト、更新= [(x、x_update)])「x」は入力ではないので、更新します。後の例では、入力はデータとラベルになります。そのため、入力パラメータはデータとラベルを取り込み、更新パラメータはモデルパラメータとそれらの更新を取り込みます。今度は単純に何度も何度もtrain関数を呼び出すためのループを書いています。xrange(25)のiのために:cost_val = train()print cost_valそしてxの最適値を出力します。print x.get_value() Theanoで概念を作成し、ニューラルネットワークを構築します。

Theanoのニューラルネットワーク

まず、入力、出力、および重みを定義します(重みは共有変数になります)。thX = T.matrix( ‘X’)thT = T.matrix( ‘T’)W1 = theano.shared( np.random.randn(D、M)、 ‘W1’)W2 = theano.shared(np.random.randn(M、K)、 ‘W2’)Theano変数に「th」という接頭辞を追加したことに注意してください。実際のデータはNumpy配列のXとTです。Mは隠れ層の単位数です。次に、フィードフォワードアクションを定義します。 thZ = T.tanh(thX.dot(W1))thY = T.nnet.softmax(thZ.dot(W2))T.tanhはシグモイドに似た非線形関数ですが、範囲は-1から+です。 1。次に、コスト関数と予測関数を定義します(これは後で分類誤差を計算するために使用されます)。 cost = – (thT * T.log(thY))。sum()予測= T.argmax(thY、axis = 1)そして私は自分の更新式を定義します。 (Theanoに勾配を計算する関数があることに注意してください。)update_W1 = W1 – lr * T.grad(cost、W1)update_W2 = W2 – lr * T.grad(cost、W2)簡単な例に似たトレイン関数を作成します。
train = theano.function(入力= [thX、thT]、updates = [(W1、update_W1)、(W2、update_W2)]、)
そしてテストセットのコストと予測を通知する予測関数を作成します。エラー率と分類率は後で計算できます。 get_prediction = theano.function(入力= [thX、thT]、出力= [コスト、予測]、)そして最後のセクションと同じように、収束するまでtrain()を何度も何度も呼び出すfor-loopを行います。 (最小の微分は0になるので、その時点では重みはそれ以上変化しません)。このコードは、「バッチ勾配降下」と呼ばれる方法を使用します。これは、トレーニングセット全体ではなく、一度に1つずつトレーニングセットのバッチを反復する方法です。これは「確率論的」な方法です。つまり、同じ分布に由来する多数のサンプルにわたって、それらすべてに最適な値に収束することを願っています。
for i in xrange(max_iter):
for j in xrange(n_batches):
Xbatch = Xtrain[j*batch_sz:(j*batch_sz + batch_sz),]
Ybatch = Ytrain_ind[j*batch_sz:(j*batch_sz + batch_sz),]
train(Xbatch, Ybatch)
if j % print_period == 0:
cost_val, prediction_val = get_prediction(Xtest, Ytest_ind)

深層学習ことはじめ その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のようなライブラリは自動的に勾配を計算できます。

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

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

******

バイナリ分類

私たちの単純なシグモイドネットワークの最後の層は単なるロジスティック回帰層です。出力は、Xに対してY = 1となる確率として解釈できます。もちろん、バイナリ分類では0または1しか出力されないため、Xに対してY = 0となる確率は、P(Y = 0 | X)= 1 です。 P(Y = 1 | X)、合計すると1になるはずです。

Softmax

2つ以上のものを分類したい場合はどうしますか。たとえば、有名なMNISTデータセットには0〜9の数字が含まれているので、10個の出力クラスがあります。このシナリオでは、softmax関数を使用します。これは、次のように定義されています。
softmax(a [k])= exp(a [k])/ {exp(a [1])+ exp(a [2])+… + exp(a [k])+…+ exp(a [K])}
“ little k”と“ big K”は異なることに注意してください。これは常に1になるので、確率として考えることもできます。今すぐコードに!既にNumpy配列にデータをロードしていると仮定すると、このセクションで行うように出力yを計算できます。上の式では1つの入力サンプルの出力しか計算されないため、少し複雑さが増します。これをコード内で実行している場合、通常、この計算を多数のサンプルに対して同時に実行します(つまり、完全なN×D行列)。

def sigmoid(a):
return 1 / (1 + np.exp(-a))

def softmax(a):
expA = np.exp(a)
return expA / expA.sum(axis=1, keepdims=True)

X,Y = load_csv(“yourdata.csv”)
W = np.random.randn(D, M)
V = np.random.randn(M, K)
Z = sigmoid(X.dot(W))
p_y_given_x = softmax(Z.dot(V))

ここで「M」は隠れユニットの数です。これが「ハイパーパラメータ」と呼ばれるもので、交差検証などの方法を使用して選択できます。もちろん、ここでの出力はランダムに初期化されるのであまり役に立ちません。 P(Y | X)の予測を行ったときにそれらが実際のラベルYに非常に近くなるように、最適なWとVを決定します。WとVをランダムに初期化しますが、bとcを0に設定します。隠れ層でシグモイド活性化関数を使用します。生成した出力は、N = Kのサイズになります。ここで、K = 10です。

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

これから数回にわたって深層学習についての記事を書きます.ひとまとめに長文としたものを数回に分けて紹介していきます.初学者向けです,何かの参考になれば.前回の記事に引き続き,基礎的な計算の中身を追いかけていきます.

******

これがNumpyでこれを行う方法の例です。
def y2indicator(y):
N = len(y)
ind = np.zeros((N, 10))
for i in xrange(N):
ind[i, y[i]] = 1
return ind

この記事では、CSVをNumpy配列またはPandasデータフレームにロードする方法をすでに知っていることと、Numpy配列の乗算や加算などの基本的な操作を行うことをあなたがすでに知っていると思います。 機械学習に慣れていない人の多くは、「すべてのデータが同じ」ということを理解していません。彼らは「X」を見て、これは抽象的すぎると思います。 「X」は一連の画像とどのように関連していますか。 「X」はeコマースデータとどのように関連していますか?この記事で「X」を扱う方法、つまり各サンプルが行に沿っており、各機能が列に沿っている2次元配列としては、機械学習では標準的な方法です。 「特徴」とは、画像の1ピクセルのこともあれば、顧客の年齢のこともあります。それはどうでもいい事です。すべてのデータは同じです。ニューラルネットワークは、あなたのデータが画像であるのか、それともあなたの顧客のWebブラウジング習慣であるのかを気にしません。ニューラルネットワークのアルゴリズムは変わりません。人工ニューラルネットワークのアーキテクチャ任意の1つのニューロンを他の任意のニューロンに接続できる生物学的ニューラルネットワークとは異なり、人工ニューラルネットワークは非常に特殊な構造をしています。特に、それらはレイヤーで構成されています。

各層は次の層に入ります。 「フィードバック」接続はありません。ニューラルネットワークが第1章でどのようになっているか、およびロジスティック単位の出力を計算する方法をすでに見たことがあります。 1章の隠れ層ニューラルネットワークがあるとします(xは入力、zは隠れ層、yは出力層です)。フィードフォワードアクションyの式を完成させましょう。まず、z 1とz 2を計算する必要があります。
z1 = s(w11 * x1 + w12 * x2)z2 = s(w21 * x1 + w22 * x2)
ここでs()は任意の非線形関数になります(線形の場合はロジスティック回帰を実行するだけです)。最も一般的な3つの選択肢は、
1:シグモイド関数
def sigmoid(x):
return 1 /(1 + np.exp(-x))
2、双曲線正接:np.tanh()双曲線正接はシグモイドの単なる拡大縮小バージョンです。シグモイドは0を中心にしているため、シグモイドよりも優先されます。
3、ReLU:
def relu(x):
if x < 0:
return 0
else:
return x

以下の代替の書き方reluが正しいことを自分自身に証明してください。
def relu(x):
return x *(x> 0)
この後者の形式は、Theanoのような目的関数の勾配を自動的に計算するライブラリで必要です。 Theanoの最近のバージョンにはT.nnet.reluを介して組み込まれたrelu関数が含まれています。最後に、yは次のように計算できます。
y = s'(v1 * z1 + v2 * z2)
次のセクションで説明するように、s'()はシグモイドまたはソフトマックスにすることができます。シグモイド関数の内部には、入力と重みの間に「内積」があるだけです。 forループの代わりにNumpyでベクトル演算と行列演算を使用する方が計算上効率的であるため、可能な場合はこれを試みます。これは、ベクトル化形式でReLUとsoftmaxを使ったニューラルネットワークの例です。
def forward(X, W, V):
Z = relu(X.dot(W))
Y = softmax(Z.dot(V))
return Y

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

これから数回にわたって深層学習についての記事を書きます.ひとまとめに長文としたものを数回に分けて紹介していきます.初学者向けです,何かの参考になれば.

******

生物学的アナロジー
前の章で、人工ニューラルネットワークが脳と物理的にどのように似ているかについて説明しましたが、学習やその他の「高レベル」の属性に関してはどうですか。興奮性しきい値ロジスティック単位の出力は0から1の間でなければなりません。分類器では、予測するクラスを選択する必要があります.たとえば、1枚の写真を見て猫または犬かを判定する,の問題を考えてみましょう.出力が1ならば  cat,0ならば dogと判定するものとします.そして、出力が0.7だったら、我々はどちらの答えを出しますか?ネコ!どうして?私たちのモデルは、「これが猫のイメージである確率は70%である」と言っているからです。 50%の閾値は、ニューロンの「興奮性閾値」、すなわち活動電位が生成される閾値として作用する。興奮性および抑制性の結合ニューロンは他のニューロンにシグナルを送るときに「興奮性」または「抑制性」シグナルを送る能力を持っています。ご想像のとおり、興奮性結合は活動電位を生み出し、抑制性結合は活動電位を抑制します。これらはロジスティック回帰ユニットの重みのようなものです。非常に積極的な体重は非常に興奮的な接続になります。非常に負の重みは非常に抑制的な関係になるでしょう。
繰り返しと親しみやすさ
「練習は成功の母」と人々はよく言います。何度も何度も練習すると、上達します。ニューラルネットワークも同じです。同じまたは類似の例についてニューラルネットワークを何度もトレーニングすると、それらの例を分類するのに役立ちます。あなたの心は、タスクを実践することによって、その特定のタスクに対するその内部エラー曲線を下げることです。バックプロパゲーション、ニューラルネットワークのトレーニングアルゴリズムについて説明すると、これがコードでどのように実装されているかがわかります。基本的に私たちがやろうとしていることは何度も何度もfor-loopを行い、同じサンプルを何度も見て、毎回それらに対してバックプロパゲーションをすることです。
ニューラルネットワークから出力を取得する
使用するデータを取得する使用するデータがまだない場合は、この記事の例を実行するために必要なデータがいくつかあります。 https://kaggle.comはこれのための素晴らしいリソースです。 MNISTデータセット(https://kaggle.com/c/digit-recognizer)をお勧めします。バイナリ分類をしたい場合は、別のデータセットを選択するか、MNISTから2つのクラス(たとえば0と1)を選択することができます。機械学習の問題に使用するデータは、多くの場合同じ形式です。いくつかの入力XといくつかのラベルまたはターゲットYがあります。各サンプル(xとyのペア)はxの実数のベクトルとyのカテゴリカル変数(多くの場合0、1、2、…)として表されます。すべてのサンプル入力をまとめて行列Xを形成します。各入力ベクトルは行です。つまり、各列は異なる入力機能です。したがって、XはN x Dの行列で、Nはサンプル数、Dは各入力の次元数です。 MNISTの場合、D = 784 = 28 x 28です。これは、28 x 28行列である元の画像が1 x 784ベクトルに「平坦化」されているためです。 yがバイナリ変数(0または1)ではない場合、それをインジケータ変数の行列に変換できます。これは、後でsoftmaxを実行するときに必要になります。 MNISTの例では、Yをインディケータ行列(0と1の行列)に変換します。ここで、Y_indicatorはN x Kの行列です。ここでもN =サンプル数、K =出力のクラス数です。 MNISTの場合はもちろんK = 10です。