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

多单元LSTM RNN训练损失为NaN的代码问题排查求助

问题定位与修复方案

我帮你梳理了代码里导致训练损失NaN的几个核心问题,以及对应的修复方案:

1. 重复定义占位符Y导致计算图关联错误

你在代码里先后两次定义了Y占位符:

Y = tf.placeholder(tf.float32, [None, n_steps, NUM_OF_OUTPUTS])
# ... 中间模型构建代码 ...
Y = tf.placeholder(tf.float32, [None, n_steps, NUM_OF_OUTPUTS])

第二次定义会覆盖第一次的占位符节点,但损失计算逻辑关联的是第一次的Y,而训练时喂入的是第二次的Y,导致损失计算时Y没有被正确赋值,直接引发NaN。

修复方法:删除重复的占位符定义,只保留一次。

2. 损失计算的数值稳定性问题

你当前的损失计算路径是「先算L2范数→再平方→求和求平均」,两次开方+平方的操作容易放大数值误差,当差值较大时可能触发数值溢出导致NaN。实际上,tf.norm(..., ord=2)的平方等价于直接计算差值的平方和,后者的数值稳定性更好。

修改后的损失计算代码:

# 直接计算差值的平方和,替代先norm再平方的冗余操作
diff = prediction[:,:,6:75] - Y[:,:,6:75]
distance_square = tf.square(diff)
reduced_distance = tf.math.reduce_sum(distance_square, axis=2)  # 每个时间步的平方和
reduced_distance = tf.math.reduce_sum(reduced_distance, axis=1) # 每个样本所有时间步的总和
train_loss = tf.math.reduce_mean(reduced_distance, axis=0)

3. 深层LSTM的梯度爆炸问题

4层LSTM结构很容易出现梯度爆炸,这是训练损失NaN的高频诱因。你需要在优化流程中加入梯度裁剪,限制梯度的最大范数,避免参数更新幅度过大导致数值溢出。

修改后的优化器代码:

learning_rate = 0.001
optimizer = tf.train.AdamOptimizer(learning_rate)
# 添加梯度裁剪,最大范数设为5.0(可根据实际情况调整)
grads, vars = zip(*optimizer.compute_gradients(train_loss))
grads, _ = tf.clip_by_global_norm(grads, 5.0)
trainOptimizer = optimizer.apply_gradients(zip(grads, vars), global_step=global_step)

4. 数据标准化的合理性优化

你当前对拼接后的输入+输出数据做了全局标准化,但输入(G_t + m_t)和输出(P_t + m_t+1)的分布可能差异较大,分开标准化能避免输出部分被输入分布干扰,进一步提升数值稳定性。

修改后的标准化代码:

# 单独标准化输入部分
train_input_mean = np.mean(train_input)
train_input_std = np.std(train_input)
train_input = (train_input - train_input_mean) / train_input_std
valid_input = (valid_input - train_input_mean) / train_input_std

# 单独标准化标签部分
train_label_mean = np.mean(train_label)
train_label_std = np.std(train_label)
train_label = (train_label - train_label_mean) / train_label_std
valid_label = (valid_label - train_label_mean) / train_label_std

修复后的核心代码片段

# 仅定义一次占位符
X = tf.placeholder(tf.float32, [None, n_steps, NUM_OF_INPUTS])
Y = tf.placeholder(tf.float32, [None, n_steps, NUM_OF_OUTPUTS])

encoded_inputs = tf.layers.dense(X, 256)
layers = [tf.contrib.rnn.LSTMCell(num_units = n_neurons, activation=tf.nn.tanh) for layer in range(n_layers)]
multi_layer_cell = tf.contrib.rnn.MultiRNNCell(layers)
outputs, _ = tf.nn.dynamic_rnn(multi_layer_cell, encoded_inputs, dtype=tf.float32)
prediction = tf.layers.dense(outputs, NUM_OF_OUTPUTS)

# 优化后的损失计算
diff = prediction[:,:,6:75] - Y[:,:,6:75]
distance_square = tf.square(diff)
reduced_distance = tf.math.reduce_sum(distance_square, axis=2)
reduced_distance = tf.math.reduce_sum(reduced_distance, axis=1)
train_loss = tf.math.reduce_mean(reduced_distance, axis=0)

# 带梯度裁剪的优化器
learning_rate = 0.001
optimizer = tf.train.AdamOptimizer(learning_rate)
grads, vars = zip(*optimizer.compute_gradients(train_loss))
grads, _ = tf.clip_by_global_norm(grads, 5.0)
trainOptimizer = optimizer.apply_gradients(zip(grads, vars), global_step=global_step)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 17:42:49