まったく同じ問題に陥り、勾配が発散しnan
、予測されy
た . nessuno によって提案されたものを実装しましたが、残念ながら、発散する勾配はまだ修正されていません。
sigmoid
代わりに、レイヤー1のアクティベーション関数として試してみましたが、うまくいきました! しかし、初期化され、ゼロ行列としてrelu
機能しなかった場合、精度はわずか 0.1135 です。と の両方を機能させるには、との初期化をより適切にランダム化します。ここに変更されたコードがありますW1
W2
relu
sigmoid
W1
W2
import tensorflow as tf
x = tf.placeholder(tf.float32, [None, 784])
# layer 1
with tf.variable_scope('layer1'):
W1 = tf.get_variable('w1',[784,200],
initializer=tf.random_normal_initializer())
b1 = tf.get_variable('b1',[1,],
initializer=tf.constant_initializer(0.0))
y1 = tf.nn.sigmoid(tf.matmul(x, W1) + b1)
# y1 = tf.nn.relu(tf.matmul(x, W1) + b1) # alternative choice for activation
# layer 2
with tf.variable_scope('layer2'):
W2 = tf.get_variable('w2',[200,10],
initializer= tf.random_normal_nitializer())
b2 = tf.get_variable('b2',[1,],
initializer=tf.constant_initializer(0.0))
y2 = tf.nn.softmax(tf.matmul(y1, W2) + b2)
# output
y = y2
y_ = tf.placeholder(tf.float32, [None, 10])
このリンクが役立つことがわかりました。質問 2 のパート (c) を参照してください。基本的な 2 層ニューラル ネットワークのバックプロパゲーション導関数が得られます。私の意見では、ユーザーがアクティベーション関数を指定しなかった場合、レイヤー 1 に線形フローを適用するだけで、最終的に のような勾配が逆伝播さ(sth)*W2^T*W1^T
れ、 と の両方を初期W1
化W2
してゼロになると、それらの積は非常に大きくなる可能性がありますゼロに近く、勾配が消失します。
アップデート
これは、ニューラル ネットワークの適切な初期重みについてOfirが投稿した Quora の回答からのものです。
最も一般的な初期化は、ランダム初期化と Xavier 初期化です。ランダムな初期化では、標準分布 (通常は正規分布) から各重みを低い偏差でサンプリングするだけです。偏差が低いと、実際に重みを 0 に初期化することによる悪影響を与えることなく、ネットワークを「単純な」0 ソリューションに偏らせることができます。