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

Keras模型训练出现NaN Loss问题求助(附代码)

多分类任务Loss变NaN的调试方案

问题根源及修复步骤:

  • 输出层配置错误
    你做的是4分类任务,输出层必须输出对应4个类别的概率分布,当前用Dense(1, activation="relu")完全不符合要求:relu无法输出概率分布,和sparse_categorical_crossentropy损失函数不兼容,计算时会直接出现NaN。必须改成Dense(4, activation="softmax")。

  • 输入数据未标准化
    你的特征值量级差异极大(比如有-1.77这种量级,也有1e-03的小值),未标准化会导致梯度爆炸,直接让Loss变成NaN。必须对训练集和测试集做标准化处理,注意测试集要使用训练集的均值和标准差,避免数据泄露。

  • 标签维度冗余
    你的标签values是二维数组(shape=(694,1)),但sparse_categorical_crossentropy要求标签是一维数组(shape=(694,)),需要做降维处理。

  • Dropout层参数多余
    Dropout层不需要重复写input_shape,只需要接在上一层输出后面即可。


修改后的完整代码:

import pyreadr
from sklearn.model_selection import train_test_split
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers
import numpy as np
from sklearn.preprocessing import StandardScaler

# 读取并处理数据
result = pyreadr.read_r("/home/ignat/Downloads/Telegram Desktop/TMS_coefficients.RData")
dataset = []
values = []

for i in range(694):
    dataset.append((result['tms.coef']['bs0'][i],
                    result['tms.coef']['bs'][i],
                    result['tms.coef']['bi0'][i],
                    result['tms.coef']['bi'][i],
                    result['tms.coef']['b0'][i],
                    result['tms.coef']['b1'][i],
                    result['tms.coef']['b2'][i],
                    result['tms.coef']['a0'][i],
                    result['tms.coef']['a1'][i]))

    # 处理标签,直接生成一维数组
    y_label = 0.0 if result['tms.coef']['Y'][i] == "НС" \
              else 1.0 if result['tms.coef']['Y'][i] == "AD" \
              else 2.0 if result['tms.coef']['Y'][i] == "DLB" \
              else 3.0
    values.append(y_label)

dataset = np.array(dataset, dtype="float")
values = np.array(values, dtype="float")

# 拆分数据集
(trainX, testX, trainY, testY) = train_test_split(dataset,
    values, test_size=0.25, random_state=42)

# 标准化输入数据
scaler = StandardScaler()
trainX = scaler.fit_transform(trainX)
testX = scaler.transform(testX)

# 构建模型
visible = layers.Input(shape=(9,))
drop1 = layers.Dropout(0.5)(visible)
hidden1 = layers.Dense(32, activation="relu")(drop1)
drop2 = layers.Dropout(0.5)(hidden1)
# 输出层改为4个神经元+softmax
output = layers.Dense(4, activation="softmax")(drop2)
model = tf.keras.Model(inputs=visible, outputs=output)

# 编译模型
model.compile(optimizer=tf.keras.optimizers.Adam(0.001),  # 适当调小学习率避免震荡
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

# 训练模型
model.fit(trainX, trainY, validation_data=(testX, testY), epochs=100)

model.save('my_model')

# 预测示例
for i in range(1, 10):
    # predict返回每个类别的概率,取argmax得到预测类别
    pred = np.argmax(model.predict(dataset[i-1:i], verbose=0), axis=1)
    print(f"预测类别: {pred[0]}, 真实类别: {values[-i]}")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 16:01:31