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

使用sklearn与Keras分析累计和长期可靠性时Loss为NaN的问题排查

训练LSTM模型时Loss出现NaN的故障排查

问题场景

使用仅包含cumulative_sum字段的CSV数据,通过MinMaxScaler做归一化,再用Keras构建LSTM模型分析累计和的长期增长可靠性,但训练全程输出loss: nan,测试Loss也为NaN。

用户提供的CSV数据片段

cumulative_sum
0.2244
0.75735
1.74845
1.93545
2.15985
2.8611
1.8611
2.2538
2.88025
3.83395
2.83395
5.0312
5.4426000000000005
5.5735
4.5735
3.5735
2.5735
3.38695
2.38695
1.3869500000000001
1.7048500000000002
2.47155
3.6309500000000003
4.1078
4.640750000000001
3.6407500000000006
4.3420000000000005
3.3420000000000005
3.6318500000000005
3.8282000000000003
4.08065
3.0806500000000003
3.7725500000000003
4.2868
3.2868000000000004
3.9974000000000003
4.7454
3.7454
4.7178
5.129200000000001
5.297500000000001
4.297500000000001
4.708900000000002
3.7089000000000016

用户使用的Python代码

import numpy as np
import pandas as pd
from sklearn.preprocessing import MinMaxScaler
from keras.models import Sequential
from keras.layers import LSTM, Dense

df = pd.read_csv("gradual_cumsum.csv")

scaler = MinMaxScaler(feature_range=(0, 1))
data = scaler.fit_transform(df)

train_size = int(len(data) * 0.8)
test_size = len(data) - train_size
train, test = data[0:train_size,:], data[train_size:len(data),:]

X_train = train[:, 0:1]
y_train = train[:, 1:2]
X_test = test[:, 0:1]
y_test = test[:, 1:2]
X_train = np.reshape(X_train, (X_train.shape[0], 1, X_train.shape[1]))
X_test = np.reshape(X_test, (X_test.shape[0], 1, X_test.shape[1]))

model = Sequential()
model.add(LSTM(50, input_shape=(X_train.shape[1], X_train.shape[2])))
model.add(Dense(1))
model.compile(loss='mean_squared_error', optimizer='adam')

model.fit(X_train, y_train, epochs=100, batch_size=1, verbose=1)

test_loss = model.evaluate(X_test, y_test, verbose=0)

print(f'Test Loss: {test_loss}')

训练与测试输出

Epoch 1/100
849/849 [==============================] - 2s 1ms/step - loss: nan

Test Loss: nan


故障原因

  1. 标签数据为空:CSV仅包含1列cumulative_sum,代码中y_train = train[:, 1:2]和y_test = test[:, 1:2]尝试提取第2列数据(索引从0开始),实际得到的是空数组。模型训练时标签无效,计算MSE损失时会出现NaN。
  2. 时间序列数据构造错误:LSTM用于时间序列预测时,需要用历史窗口数据作为输入特征,预测下一个时刻的值。原代码直接将单列数据拆分X和Y,不符合时间序列预测的逻辑,本质上没有有效的输入-标签对。

修正方案

步骤1:构造时间序列数据集

先实现一个函数,将一维的累计和数据转换成(样本数, 时间步长, 特征数)的输入格式,同时对应每个输入的标签为下一个时刻的累计和值。

步骤2:修正数据拆分逻辑

确保X为历史窗口数据,Y为对应下一个时刻的数值,避免提取空标签。

修正后的完整代码

import numpy as np
import pandas as pd
from sklearn.preprocessing import MinMaxScaler
from keras.models import Sequential
from keras.layers import LSTM, Dense

# 构造时间序列数据集的函数
def create_dataset(data, time_steps=1):
    X, Y = [], []
    for i in range(len(data) - time_steps):
        # 取time_steps长度的历史数据作为输入
        X.append(data[i:(i + time_steps), 0])
        # 取下一个时刻的数据作为标签
        Y.append(data[i + time_steps, 0])
    return np.array(X), np.array(Y)

df = pd.read_csv("gradual_cumsum.csv")

scaler = MinMaxScaler(feature_range=(0, 1))
data = scaler.fit_transform(df)

# 设置时间步长,这里用1步历史数据预测下一个值,可根据需求调整
time_steps = 1
X, y = create_dataset(data, time_steps)

# 拆分训练集和测试集
train_size = int(len(X) * 0.8)
X_train, X_test = X[0:train_size], X[train_size:len(X)]
y_train, y_test = y[0:train_size], y[train_size:len(y)]

# 调整输入格式为LSTM要求的 [样本数, 时间步长, 特征数]
X_train = np.reshape(X_train, (X_train.shape[0], X_train.shape[1], 1))
X_test = np.reshape(X_test, (X_test.shape[0], X_test.shape[1], 1))

# 构建LSTM模型
model = Sequential()
model.add(LSTM(50, input_shape=(X_train.shape[1], X_train.shape[2])))
model.add(Dense(1))
model.compile(loss='mean_squared_error', optimizer='adam')

# 训练模型
model.fit(X_train, y_train, epochs=100, batch_size=1, verbose=1)

# 评估测试集
test_loss = model.evaluate(X_test, y_test, verbose=0)
print(f'Test Loss: {test_loss}')

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.04 07:15:31