【问题标题】:Why are my TensorFlow network weights and costs NaN when I use RELU activations?当我使用 RELU 激活时,为什么我的 TensorFlow 网络权重和成本为 NaN?
【发布时间】:2016-09-23 17:34:09
【问题描述】:

如果没有激活和权重的 NaN 值,我无法让 TensorFlow RELU 激活(tf.nn.relutf.nn.relu6)工作,这会杀死我的训练运行。

我相信我遵循了所有正确的一般建议。例如,我用

初始化我的权重
weights = tf.Variable(tf.truncated_normal(w_dims, stddev=0.1))
biases = tf.Variable(tf.constant(0.1 if neuron_fn in [tf.nn.relu, tf.nn.relu6] else 0.0, shape=b_dims))

并使用较慢的训练速率,例如,

tf.train.MomentumOptimizer(0.02, momentum=0.5).minimize(cross_entropy_loss)

但是任何具有可观深度的网络都会导致 NaN 的成本和至少一些权重(至少在它们的摘要直方图中)。事实上,从一开始(训练之前)的成本通常是NaN

即使我使用 L2(大约 0.001)正则化和 dropout(大约 50%),我似乎也有这些问题。

是否有一些参数或设置我应该调整以避免这些问题?我不知道从哪里开始寻找,所以任何建议都将不胜感激!

【问题讨论】:

  • relu 没有什么神奇之处。错误在您的代码中,因此您应该提供它。为什么将偏差初始化为 0.1 而不是 0?为什么不简单地 tf.Variable + tf.zeros ?
  • @lejlot:0.1 的想法来自from Google
  • 你的网络有多少层?这似乎是一个梯度爆炸问题。
  • @LifuHuang:问题似乎出现在>4。但即使我可以避免我的 NaN 问题,RELU 实际上似乎也不能很好地工作。
  • “炒作”涉及很多方面。特别是对于真正的深度网络(假设至少有 10-20 个隐藏层),relu 的表现比 sigmoid 好得多。它们收敛得更快,得到更好的解决方案,它们更容易实现(计算速度也更快,如果你把它放在 gpus 上,这一点很重要)。有一些新的、特定的初始化启发式方法非常适合 relus(与旧的基于 sigmoid 的启发式方法不同),您可以在 nips 论文中找到这些启发式方法。

标签: machine-learning tensorflow nan


【解决方案1】:

按照He et. al(如lejlot 的评论中所建议),将第l层的权重初始化为具有标准偏差的零均值高斯分布

其中 nl 是输入向量的展平长度或

stddev=np.sqrt(2 / np.prod(input_tensor.get_shape().as_list()[1:]))

导致权重通常不会发散。

【讨论】:

    【解决方案2】:

    如果您在网络顶部使用 softmax 分类器,请尝试使 softmax 下方层的初始权重非常小(例如 std=1e-4)。这使得网络输出的初始分布非常柔软(高温),并有助于确保优化的前几个步骤不会太大且数值不稳定。

    【讨论】:

      【解决方案3】:

      您是否尝试过gradient clipping 和/或更小的学习率?

      基本上,您需要在应用渐变之前对其进行处理,如下所示(主要来自 tf 文档):

      # Replace this with what follows
      # opt = tf.train.MomentumOptimizer(0.02, momentum=0.5).minimize(cross_entropy_loss)
      
      # Create an optimizer.
      opt = tf.train.MomentumOptimizer(learning_rate=0.001, momentum=0.5)
      
      # Compute the gradients for a list of variables.
      grads_and_vars = opt.compute_gradients(cross_entropy_loss, tf.trainable_variables())
      
      # grads_and_vars is a list of tuples (gradient, variable).  Do whatever you
      # need to the 'gradient' part, for example cap them, etc.
      capped_grads_and_vars = [(tf.clip_by_value(gv[0], -5., 5.), gv[1]) for gv in grads_and_vars]
      
      # Ask the optimizer to apply the capped gradients.
      opt = opt.apply_gradients(capped_grads_and_vars)
      

      另外,the discussion in this question 可能会有所帮助。

      【讨论】:

        猜你喜欢
        • 2022-11-14
        • 2018-05-02
        • 1970-01-01
        • 2021-02-10
        • 1970-01-01
        • 2020-06-02
        • 2018-03-19
        • 2020-03-30
        • 2019-01-19
        相关资源
        最近更新 更多