返回NaN的TensorFlow自定义模型优化器。为什么呢?

时间:2016-07-12 10:42:48

标签: machine-learning neural-network tensorflow

我想为我创建的自定义模型学习最佳weightsexponents

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。

1 个答案:

答案 0 :(得分: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。对于奇点附近的值,剪切将是必要的,其中渐变可能是任意大的。

警告:无法保证这一点可行,尤其是对于nans可能会污染网络大片区域的更深层网络。