最近、ニューラルネットワークをいじり始めました。 TensorflowでAND
ゲートを実装しようとしていました。異なるコストとアクティベーション機能をいつ使用するかを理解するのが困難ですこれは、入力層と出力層のみを持ち、隠れ層を持たない基本的なニューラルネットワークです。
まず、この方法で実装しようとしました。ご覧のとおり、これは貧弱な実装ですが、少なくとも何らかの形で仕事を成し遂げると思います。そのため、実際の出力のみを試し、真のホットな出力は試しませんでした。アクティベーション関数については、シグモイド関数を使用し、コスト関数については、二乗誤差コスト関数を使用しました(それがそれと呼ばれると思います。間違っている場合は修正してください)。
ReLUとSoftmaxをアクティベーション関数(同じコスト関数)として使用しようとしましたが、機能しません。なぜ機能しないのかがわかりました。また、シグモイド関数とクロスエントロピーコスト関数を試しましたが、やはり機能しません。
import tensorflow as tf
import numpy
train_X = numpy.asarray([[0,0],[0,1],[1,0],[1,1]])
train_Y = numpy.asarray([[0],[0],[0],[1]])
x = tf.placeholder("float",[None, 2])
y = tf.placeholder("float",[None, 1])
W = tf.Variable(tf.zeros([2, 1]))
b = tf.Variable(tf.zeros([1, 1]))
activation = tf.nn.sigmoid(tf.matmul(x, W)+b)
cost = tf.reduce_sum(tf.square(activation - y))/4
optimizer = tf.train.GradientDescentOptimizer(.1).minimize(cost)
init = tf.initialize_all_variables()
with tf.Session() as sess:
sess.run(init)
for i in range(5000):
train_data = sess.run(optimizer, feed_dict={x: train_X, y: train_Y})
result = sess.run(activation, feed_dict={x:train_X})
print(result)
5000回の反復後:
[[ 0.0031316 ]
[ 0.12012422]
[ 0.12012422]
[ 0.85576665]]
質問1-パラメータを変更せずに(変更せずに、上記のネットワークで機能する(学習する)他のアクティベーション関数とコスト関数はありますかW、x、b)。
質問2-StackOverflowの投稿から読みました ここ :
[アクティベーション機能]の選択は問題に依存します。
だからどこでも使用できるコスト関数はありませんか?つまり、どのニューラルネットワークでも使用できるstandardコスト関数はありません。正しい?これを修正してください。
また、別のアプローチでAND
ゲートを実装し、出力をone-hot trueにしました。ご覧の通り、train_Y
[1,0]
は、0番目のインデックスが1であることを意味するため、答えは0です。取得していただければ幸いです。
ここでは、コスト関数としてクロスエントロピーを使用して、ソフトマックス活性化関数を使用しました。アクティベーション関数としてのシグモイド関数は悲惨に失敗します。
import tensorflow as tf
import numpy
train_X = numpy.asarray([[0,0],[0,1],[1,0],[1,1]])
train_Y = numpy.asarray([[1,0],[1,0],[1,0],[0,1]])
x = tf.placeholder("float",[None, 2])
y = tf.placeholder("float",[None, 2])
W = tf.Variable(tf.zeros([2, 2]))
b = tf.Variable(tf.zeros([2]))
activation = tf.nn.softmax(tf.matmul(x, W)+b)
cost = -tf.reduce_sum(y*tf.log(activation))
optimizer = tf.train.GradientDescentOptimizer(0.5).minimize(cost)
init = tf.initialize_all_variables()
with tf.Session() as sess:
sess.run(init)
for i in range(5000):
train_data = sess.run(optimizer, feed_dict={x: train_X, y: train_Y})
result = sess.run(activation, feed_dict={x:train_X})
print(result)
5000回の反復後
[[ 1.00000000e+00 1.41971401e-09]
[ 9.98996437e-01 1.00352429e-03]
[ 9.98996437e-01 1.00352429e-03]
[ 1.40495342e-03 9.98595059e-01]]
質問3この場合、どのようなコスト関数とアクティベーション関数を使用できますか?どのタイプのコストとアクティベーション機能を使用すべきかをどのように理解すればよいですか?標準的な方法やルールはありますか、それとも経験のみですか?あらゆるコストとアクティベーション機能をブルートフォース方式で試す必要がありますか?私は答えを見つけました こちら 。しかし、私はより詳細な説明を期待しています。
質問4ほぼ正確な予測に収束するには多くの反復が必要であることに気付きました。収束率は、学習率(多すぎると解が失われます)とコスト関数(間違っている場合は修正してください)に依存すると思います。それで、正しいソリューションに収束するための最適な方法(最速を意味する)またはコスト関数はありますか?
より一般的な回答から始めて、特定の実験に固有の質問で終わります。
アクティベーション関数異なるアクティベーション関数は、実際には異なるプロパティを持っています。最初に、ニューラルネットワークの2つのレイヤー間の活性化関数を考えてみましょう。アクティベーション関数の唯一の目的は、非線形性として機能することです。 2つのレイヤーの間にアクティベーション関数を配置しない場合、2つのレイヤーを一緒に使用しても1つのレイヤーより効果があります。長い間、人々はシグモイド関数とtanhを使用していたが、ReLUが支配的な非劣性になる最近まで、シグモイドがより人気があり、かなり自由に選択していた。レイヤー間でReLUを使用する理由は、ReLUが非飽和であるためです(計算も高速です)。シグモイド関数のグラフについて考えてください。 x
の絶対値が大きい場合、シグモイド関数の導関数は小さくなります。つまり、エラーを逆方向に伝播すると、レイヤーを通過するときにエラーの勾配が非常に速く消えます。 。 ReLUでは、導関数はすべての正の入力に対して1
であるため、発火したニューロンの勾配は活性化ユニットによってまったく変更されず、勾配降下を遅くしません。
ネットワークの最後の層では、アクティベーションユニットもタスクに依存します。回帰では、結果を0〜1にしたいので、シグモイドまたはtanhアクティベーションを使用する必要があります。分類では、出力の1つだけをゼロにし、他のすべてのゼロにする必要があります。正確に言えば、ソフトマックスを使用して近似する必要があります。
例。次に例を見てみましょう。最初の例では、AND
の出力を次の形式で計算しようとします。
sigmoid(W1 * x1 + W2 * x2 + B)
(W1
、W2
)の出力は(x1
、x2
)の出力と等しくなければならないため、x2
とx1
は常に同じ値に収束することに注意してください。したがって、フィッティングするモデルは次のとおりです。
sigmoid(W * (x1 + x2) + B)
x1 + x2
は3つの値(0、1、または2)のうちの1つのみを取り、0
の場合はx1 + x2 < 2
を、x1 + x2 = 2
の場合は1を返します。シグモイド関数はかなり滑らかであるため、出力を望ましい値に近づけるためにW
およびB
の非常に大きな値を取りますが、学習率が小さいため、これらの大きな値は高速です。最初の例で学習率を上げると、収束の速度が上がります。
2番目の例は、softmax
関数が正確に1つの出力を1
に等しく、他のすべてを0
に等しくするのに優れているため、より収束します。これはまさにあなたのケースなので、すぐに収束します。 sigmoid
も最終的には適切な値に収束しますが、かなり多くの反復(または高い学習率)が必要になることに注意してください。
使用するもの。さて、最後の質問に、使用するアクティベーション関数とコスト関数をどのように選択するのでしょうか。これらのアドバイスは、ほとんどの場合に有効です。
分類を行う場合は、最後のレイヤーの非線形性にsoftmax
を使用し、コスト関数としてcross entropy
を使用します。
回帰を行う場合は、最後のレイヤーの非線形性にsigmoid
またはtanh
を使用し、コスト関数としてsquared error
を使用します。
レイヤー間の非類似性としてReLUを使用します。
AdamOptimizer
の代わりに、より優れたオプティマイザー(AdagradOptimizer
、GradientDescentOptimizer
)を使用するか、モーメンタムを使用して収束を高速化します。