TensorFlow自定义模型优化器返回NaN的原因是什么?

我想为我创建的自定义模型学习最优的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))# 运行正常:pred = tf.matmul(x, weights)# 不工作: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优化器不应该有处理这种情况的方法吗?

我注意到维基百科上没有显示任何激活函数,其中x被取到指数。为什么没有像下图所示的激活函数?enter image description here

对于上图,我希望我的程序能学习到正确的指数是0.5。


回答:

这是TensorFlow的正确行为,因为在那里的梯度是无穷大(并且许多数学上应该是无穷大的计算最终会因为不确定的极限而变成NaN)。

如果你想解决这个问题,稍微泛化的梯度裁剪可能会有效。你可以通过Optimizer.compute_gradients获取梯度,手动通过类似于

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

的方式对它们进行裁剪,然后将裁剪后的梯度传递给Optimizer.apply_gradients。在接近奇点的地方,梯度可能非常大,因此需要裁剪以防止爆炸。

警告:没有保证这种方法一定会有效,特别是对于较深的网络,NaN可能会污染网络的大片区域。

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注