2016-07-12 3 views
1

私が作成したカスタムモデルに最適なweightsexponentsを学びたい:TensorFlow NaNを返すカスタムモデルオプティマイザ。どうして?

weights = tf.Variable(tf.zeros([t.num_features, 1], dtype=tf.float64)) 
exponents = tf.Variable(tf.ones([t.num_features, 1], dtype=tf.float64)) 

# works fine: 
pred = tf.matmul(x, weights) 

# doesn't work: 
x_to_exponent = tf.mul(tf.sign(x), tf.pow(tf.abs(x), tf.transpose(exponents))) 
pred = tf.matmul(x_to_exponent, weights) 

cost_function = tf.reduce_mean(tf.abs(pred-y_)) 
optimizer = tf.train.GradientDescentOptimizer(t.LEARNING_RATE).minimize(cost_function) 

問題が負の値があるたびにゼロxでオプティマイザはNaNとして重みを返すことです。 x = 0のときに単純に0.0001を追加すると、すべてが期待通りに機能します。しかし、私は本当にこれを行う必要がありますか? TensorFlowオプティマイザはこれを処理する方法がありますか?

ウィキペディアには表示されません。activation functionsここで、xは指数になります。なぜ以下のような画像が表示されるのですか? enter image description here

上記の画像では、正しい指数が0.5であることを私のプログラムが知りたいと思います。

+0

重量を**指数**にしてもよろしいですか?これは簡単にinfintiyに行くことができます。あなたの全体のコードも含めてください。 – lejlot

+0

はい - 正しい予測をするために、入力データをどの指数に持っていかなければならないかを知りたい。指数は通常0〜1の間にあるので、無限にしてはいけません。たとえば、上記の画像が、私たちが学習する必要のある正しい指数を予測しようとしているモデルであれば、0.5です。 –

+0

@lejlotコードを更新して、動作するものと動作しないものをより明確に表示しました。私は間違いを訂正しました。 –

答えて

0

グラデーションが無限大であるため、これはTensorFlowの部分で正しく動作します(また、数学的には無限大になるはずの計算は不確定な限界によりNaNになります)。

問題を回避するには、少し一般化されたグラデーションのクリッピングが機能することがあります。手動で、Optimizer.compute_gradients経由勾配を得る

safe_grad = tf.clip_by_value(tf.select(tf.is_nan(grad), 0, grad), -lim, lim) 

のようなものを経由してそれらをクリップして、Optimizer.apply_gradientsにクリップグラデーションを渡すことができます。クリッピングは、勾配が任意に大きくなる可能性がある特異点付近の値に対しては爆発しないために必要です。

警告:特にネットワークが広範囲に及ぶネットワークを汚染する可能性があるより深いネットワークの場合、これが機能するとは限りません。

+0

ヒントをありがとう!私の理解が向上し、そのような解決策を実行する準備ができているとき、私はここに戻ります。 –