You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TensorFlow直方图摘要报错:权重参数中存在NaN值求助

解决TensorFlow直方图摘要中出现NaN的问题

嘿,我看到你作为TensorFlow新手在训练MNIST模型时碰到了直方图摘要出现NaN的错误,这个问题我之前也踩过坑,咱们一起来解决它~

问题根源分析

你遇到的InvalidArgumentError: Nan in summary histogram for: weights,核心原因是训练过程中权重(W)的数值变成了NaN,导致直方图无法生成。具体来说有两个关键问题:

  • 损失函数数值量级过大:你用了tf.reduce_mean(tf.reduce_sum(tf.square(my_label-y)))计算损失——先把每个样本的10个类别误差平方累加,再取平均。这个计算会让损失值变得非常大,梯度更新时很容易触发数值溢出,最终让权重变成NaN。
  • 分类任务误用回归损失:MNIST是10分类任务,平方损失更适合回归问题,分类任务用交叉熵损失才更合理,它的数值稳定性更好,也更贴合分类任务的目标。

具体修复步骤

1. 替换为适合分类任务的交叉熵损失

把原来的平方和损失换成TensorFlow专门为分类任务提供的交叉熵损失API,这样能有效控制损失的数值量级:

# 替换原来的mean_error计算代码
cross_entropy = tf.nn.softmax_cross_entropy_with_logits_v2(logits=my_label, labels=y)
mean_error = tf.reduce_mean(cross_entropy)

2. 修复训练循环中的变量名错误

你代码里的train_accuracy = sess.run(train_step, ...)是个小bug:train_step是优化器的更新操作,运行它不会返回准确率,只会执行梯度更新。应该分开执行更新和准确率计算:

# 先执行梯度更新
sess.run(train_step, feed_dict={x: batch[0], y: batch[1]})
# 每500次迭代时单独计算准确率
if i % 500 == 0:
    train_acc = sess.run(accuracy, feed_dict={x: batch[0], y: batch[1]})
    print(f"第{i}次迭代,训练准确率: {train_acc}")

3. 可选:如果坚持用平方损失的调整方案

如果你不想换损失函数,那需要缩小损失的数值量级,同时调整学习率:

# 去掉reduce_sum,直接计算每个样本每个类别的平方误差均值
mean_error = tf.reduce_mean(tf.square(my_label - y))
# 适当调小学习率,比如从0.0003改成0.0001
train_step=tf.train.GradientDescentOptimizer(0.0001).minimize(mean_error)

修改后的完整代码

import tensorflow as tf
logdir="/tmp/mnist_tutorial5/"
mnist = tf.contrib.learn.datasets.mnist.read_data_sets(train_dir=logdir+"data",one_hot = True)
tf.reset_default_graph()
sess = tf.Session()
writer = tf.summary.FileWriter(logdir)

def model(input):
    w = tf.Variable(tf.truncated_normal([784,10], stddev=0.1), name="W")
    b = tf.Variable(tf.constant(0.1, shape=[10]), name="B")
    act = tf.matmul(input,w) + b
    tf.summary.histogram("weights",w)
    tf.summary.histogram("biases",b)
    tf.summary.histogram("activations",act)
    return act

def train():
    x = tf.placeholder(tf.float32, shape=[None, 784], name="input_img")
    y = tf.placeholder(tf.float32, shape=[None, 10], name="labels")
    my_label = model(x)
    print("linear_regression is completed")
    
    # 替换为交叉熵损失
    cross_entropy = tf.nn.softmax_cross_entropy_with_logits_v2(logits=my_label, labels=y)
    mean_error = tf.reduce_mean(cross_entropy)
    
    tf.summary.scalar("loss", mean_error)
    train_step=tf.train.GradientDescentOptimizer(0.0003).minimize(mean_error)
    correct_prediction = tf.equal(tf.argmax(my_label, 1), tf.argmax(y, 1))
    accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32))
    tf.summary.scalar("accuracy", accuracy)
    
    sess.run(tf.global_variables_initializer())
    summ = tf.summary.merge_all()
    
    for i in range(2000):
        batch = mnist.train.next_batch(100)
        # 单独执行梯度更新
        sess.run(train_step, feed_dict={x: batch[0], y: batch[1]})
        print(f"{i} th iteration")
        
        if i%500==0:
            print("over 2")
            # 同时计算摘要和准确率
            summarys, train_acc = sess.run([summ, accuracy], feed_dict={x: batch[0], y: batch[1]})
            print(f"第{i}次迭代,训练准确率: {train_acc}")
            print("over 3")
            writer.add_summary(summarys,i)
            print("one over")

train()
writer.add_graph(sess.graph)

额外小提示

如果你的TensorFlow版本比较新,tf.contrib.learn.datasets.mnist可能已经被弃用,可以改用tf.keras.datasets.mnist来加载MNIST数据,不过这不会影响当前问题的解决。

内容的提问来源于stack exchange,提问作者Gopirengaraj

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 08:26:58