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

Keras网络训练Loss为nan、准确率无变化问题求助

解决Keras模型训练时Loss为NaN且准确率固定的问题

我完全懂这种卡在NaN损失和纹丝不动的准确率上的挫败感——咱们从你的代码和训练现象入手,一步步排查解决:

一、先排查代码里的潜在风险点

1. 权重初始化与激活函数的冲突

你的第一层用了tanh激活+init='normal'(注意Keras新版本中该参数已更名为kernel_initializer),tanh的饱和区间是±1,如果权重初始化的方差过大,会导致大量神经元的激活值直接饱和到±1,梯度趋近于0,后续更新时极易出现数值不稳定,甚至直接产生NaN。

  • 建议把第一层的初始化改成kernel_initializer='glorot_normal'(即Xavier初始化),它专门针对tanh这类对称激活函数设计,能让输入输出的方差保持一致,避免激活饱和。
  • 或者直接把tanh换成relu,它的抗饱和能力更强,配合he_normal初始化效果会更稳定。

2. 交叉熵损失的数值稳定性问题

你使用的categorical_crossentropy损失,如果模型输出的softmax结果出现极接近0的数值,计算log(0)会直接得到NaN。

  • 可以尝试在编译时对损失做数值裁剪,或者如果你的标签是整数形式(而非one-hot),换成sparse_categorical_crossentropy,它的数值稳定性更好。

3. 优化器与学习率的适配问题

你用的是SGD+0.01的学习率,对于503维输入、1000个神经元的模型来说,这个学习率可能过高——如果存在梯度爆炸的情况,一步更新就会让权重变成NaN。

  • 先把学习率降到0.001甚至0.0001试试,或者换成自适应优化器比如Adam,它会自动调整学习率,数值稳定性更优。

二、再深挖数据的隐藏问题

你说已经检查了NaN和做了归一化,但还有几个容易忽略的点要确认:

  • 是否存在Inf值? 数据里的无穷大比NaN更隐蔽,用np.isinf(x_train).any()和np.isinf(y_train).any()检查一下。
  • 标签是否完全合规? 确认所有y_train的one-hot向量都是严格的[1,0]或[0,1],有没有出现[0,0]、[1,1]或其他异常值?这类标签会直接导致交叉熵计算出NaN。
  • 归一化是否彻底? 你的输入例子有负数,用的是[-1,1]的归一化?有没有个别特征的数值范围特别极端(比如某个特征最大值是1000、最小值是-1000),导致整体归一化后仍存在异常值?可以用x_train.max()和x_train.min()查看,确保所有特征都落在合理区间(比如[-1,1]或[0,1])。

三、训练参数的调整

你的batch_size设为1000,对于99804个样本来说,batch size过大——大batch会降低梯度估计的方差,但也更容易出现数值不稳定,尤其是当梯度本身就很大的时候。

  • 先把batch_size降到32或64试试,小batch的梯度更新更频繁,数值稳定性更好,也更容易定位问题。

四、调试小技巧

可以在训练前加一段代码,检查模型的初始输出是否异常:

# 取一小批数据,验证模型初始输出
sample_x = x_train[:10]
sample_y = y_train[:10]
preds = model.predict(sample_x)
print("初始预测输出:", preds)
print("预测输出的和:", preds.sum(axis=1)) # softmax输出的和应接近1
print("小批量交叉熵损失:", model.evaluate(sample_x, sample_y, verbose=0))

如果初始输出就有0或者无穷大,那问题肯定出在模型初始化或者数据上。


内容的提问来源于stack exchange,提问作者Максим

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 04:42:12