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

训练TensorFlow神经网络时损失值恒为0的问题排查求助

排查训练损失始终为0的问题

先拆解你的代码里几个关键问题,这些错误叠加起来直接导致了损失异常:

1. 输入数据未转换为数值类型

你从文本文件读取的birth_data是字符串数组,但直接赋值给x_vals和y_vals后没有转换成浮点型。TensorFlow的占位符要求tf.float32类型,虽然不会直接报错,但数值计算会完全混乱,这是核心问题之一。

修正代码:

# 将字符串数组转换为浮点型
x_vals = np.array([x[2:10] for x in birth_data], dtype=np.float32)
y_vals = np.array([x[1] for x in birth_data], dtype=np.float32).reshape((-1,1))

2. 损失函数与任务、输出层不匹配

你的任务是二分类问题(低体重出生预测,标签应为0/1),但你犯了两个错误:

  • 最后一层用ReLU激活,把输出截断为非负值,破坏了logits的原始分布
  • 搭配了多分类专用的tf.nn.softmax_cross_entropy_with_logits损失函数

对于二分类任务,正确的做法是:

  • 最后一层不要加激活函数,直接输出原始logits
  • 使用tf.nn.sigmoid_cross_entropy_with_logits作为损失函数

修正后的网络与损失计算:

def nn(x):
    w1 = init_weight([8,25])
    b1 = init_bias([25])
    layer1 = fully_connected(x,w1,b1)
    
    w2 = init_weight([25,10])
    b2 = init_bias([10])
    layer2 = fully_connected(layer1,w2,b2)
    
    w3 = init_weight([10,3])
    b3 = init_bias([3])
    layer3 = fully_connected(layer2,w3,b3)
    
    w4 = init_weight([3,1])
    b4 = init_bias([1])
    # 最后一层去掉ReLU,直接输出logits
    final_output = tf.matmul(layer3,w4)+b4
    return final_output

# 替换为二分类专用损失函数
loss = tf.reduce_mean(tf.nn.sigmoid_cross_entropy_with_logits(labels=y_data, logits=y_))

3. 学习率设置过大

Adam优化器的默认学习率是0.001,你设置了0.1,这会导致参数更新幅度过大,模型直接跳到极端值(比如所有预测强行匹配标签,出现虚假的0损失)。

修正代码:

train_step = tf.train.AdamOptimizer(0.001).minimize(loss)

4. 损失计算的数据集选择不合理

你每次迭代计算的是测试集的损失,而不是训练集的损失。训练初期模型还未学习,测试集损失就为0显然不符合逻辑,这也侧面印证了之前的错误导致损失计算异常。建议先监控训练集损失,再定期查看测试集表现。

5. 准确率计算函数的形状不匹配

你的get_accuracy函数中,labels=y_test是二维数组([None,1]),但np.argmax(logits,axis=1)得到的是一维数组,np.equal会因为形状不匹配出错。对于二分类,应该用sigmoid转换后取阈值判断类别:

修正代码:

def get_accuracy(logits,labels):
    # 将logits转换为概率,以0.5为阈值判断类别
    batch_predictions = np.round(tf.nn.sigmoid(logits).eval(session=sess))
    num_correct = np.sum(np.equal(batch_predictions, labels))
    return(100*num_correct / batch_predictions.shape[0])

总结需要避免的操作

  • 不要忘记将输入字符串数据转换为正确的数值类型(float/int)
  • 不要混用损失函数和任务类型:二分类用sigmoid交叉熵,多分类用softmax交叉熵,且logits必须是未激活的原始输出
  • 不要设置过大的学习率,尤其是Adam这类自适应优化器
  • 不要在训练过程中只监控测试集损失,优先观察训练集损失的变化趋势
  • 最后一层的激活函数要匹配损失函数:交叉熵损失通常不需要在最后一层加激活(由损失函数内部处理)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:09:07