当我使用 RELU 激活时,为什么我的 TensorFlow 网络权重和成本为 NaN?
Why are my TensorFlow network weights and costs NaN when I use RELU activations?
如果没有用于激活和权重的 NaN 值,我无法获得 TensorFlow RELU 激活(tf.nn.relu
和 tf.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%),我似乎也有这些问题。
我应该调整一些参数或设置以避免这些问题吗?我不知道从哪里开始寻找,所以任何建议将不胜感激!
如果您在网络顶部使用 softmax 分类器,请尝试使 softmax 正下方层的初始权重非常小(例如 std=1e-4)。这使得网络输出的初始分布非常柔软(高温),并有助于确保优化的前几步不会太大和数值不稳定。
你试过gradient clippingand/or更小的学习率吗?
基本上,您需要在应用渐变之前对其进行处理,如下所示(主要来自 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)
此外, 可能会有所帮助。
根据 He et. al (as suggested in lejlot 的评论),将第 l 层的权重初始化为标准差为
的零均值高斯分布

其中 nl 是输入向量的展平长度或
stddev=np.sqrt(2 / np.prod(input_tensor.get_shape().as_list()[1:]))
导致权重通常不会发散。
如果没有用于激活和权重的 NaN 值,我无法获得 TensorFlow RELU 激活(tf.nn.relu
和 tf.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%),我似乎也有这些问题。
我应该调整一些参数或设置以避免这些问题吗?我不知道从哪里开始寻找,所以任何建议将不胜感激!
如果您在网络顶部使用 softmax 分类器,请尝试使 softmax 正下方层的初始权重非常小(例如 std=1e-4)。这使得网络输出的初始分布非常柔软(高温),并有助于确保优化的前几步不会太大和数值不稳定。
你试过gradient clippingand/or更小的学习率吗?
基本上,您需要在应用渐变之前对其进行处理,如下所示(主要来自 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)
此外,
根据 He et. al (as suggested in lejlot 的评论),将第 l 层的权重初始化为标准差为
的零均值高斯分布其中 nl 是输入向量的展平长度或
stddev=np.sqrt(2 / np.prod(input_tensor.get_shape().as_list()[1:]))
导致权重通常不会发散。