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

使用Keras LSTM时含np.inf掩码填充序列出现NaN损失问题

问题:LSTM掩码np.inf填充值后仍出现NaN损失

我正在训练LSTM网络预测序列下一个坐标元组,训练数据集通过轨迹序列扩充:提取轨迹前n个元组后填充剩余部分,再提取前n+1个元组填充,以此类推。

用np.inf填充时,MSE损失出现NaN,说明即便加了Masking层,填充值还是引发了数值异常。我本以为mask_value=np.inf会屏蔽这些值,求解决办法。


相关代码

Pad_sequences调用

padded_values = np.squeeze(tf.keras.utils.pad_sequences(train_sequences, maxlen= 3177, padding='post',dtype=float, value=np.inf))

原始输入

array([[-0.1843775,  0.6867699],
       [-1.0841161, -3.0429556],
       [ 1.3582058, -0.6040352],
       [ 1.8754534, -1.7010269],
       [-1.5366333, -2.2335546],
       [ 1.9193598, -0.285654 ]], dtype=float32)

填充后输入

array([[-0.18437751,  0.6867699 ],
       [-1.0841161 , -3.04295564],
       [ 1.3582058 , -0.6040352 ],
       ...,
       [        inf,         inf],
       [        inf,         inf],
       [        inf,         inf]])

最终数据集中的元组(填充后输入,标签)

(array([[-0.18437751,  0.6867699 ],
       [-1.0841161 , -3.04295564],
       [ 1.3582058 , -0.6040352 ],
       ...,
       [        inf,         inf],
       [        inf,         inf],
       [        inf,         inf]]), array([[2.154067, 0.871821]], dtype=float32))

创建tf.Dataset

train_data = tf.data.Dataset.from_generator(
    padded_generator_whole_trajectory,
    output_types= (tf.float32, tf.float32),
    output_shapes= ((3177,2),(1,2))
)
train_data = train_data.batch(10)
spec = train_data.element_spec

模型(Keras)

model = Sequential()
model.add(tf.keras.layers.Input(type_spec=spec[0]))
model.add(tf.keras.layers.Masking(mask_value=np.inf))
model.add(tf.keras.layers.LSTM(100,activation='relu', return_sequences=True))
model.add(tf.keras.layers.LSTM(50, activation='relu', return_sequences=True))
model.add(tf.keras.layers.LSTM(25, activation='relu'))
model.add(tf.keras.layers.Dense(10, activation='relu'))
model.add(tf.keras.layers.Dense(2))
model.compile(optimizer='adam', loss='mse')

解决思路
  1. 替换np.inf为安全填充值
    np.inf属于极端数值,即便Masking层屏蔽了序列处理,TensorFlow计算图中只要接触到inf就会直接产生NaN(比如LSTM内部矩阵运算)。建议改用数据统计极值或中性值填充:

    # 用训练数据最小值减1作为填充值,避免和有效数据冲突
    min_coord = np.min([seq.min() for seq in train_sequences])
    padded_values = np.squeeze(tf.keras.utils.pad_sequences(train_sequences, maxlen=3177, padding='post', dtype=float, value=min_coord - 1))
    

    同步修改Masking层的mask_value=min_coord -1。

  2. 简化输入层定义
    用明确的形状定义替代type_spec,避免Dataset的类型规范干扰掩码传递:

    model.add(tf.keras.layers.Input(shape=(3177, 2)))
    
  3. 检查LSTM激活函数
    relu激活在遇到inf时会直接输出inf,进一步放大数值异常。如果坚持用inf填充,可先尝试把LSTM的激活换成tanh(原生LSTM默认激活),再观察损失变化。

  4. 验证掩码有效性
    在模型中添加中间输出,查看掩码是否正确生成:

    from tensorflow.keras import backend as K
    
    # 获取Masking层的掩码输出
    mask_output = model.layers[1].output_mask
    # 打印某批次数据的掩码结果
    sample_input, _ = next(iter(train_data))
    print(K.eval(mask_output))
    

    如果掩码全为True,说明填充值没有被正确识别,需检查数据类型是否一致(比如np.inf和tf.float32的兼容性)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 23:25:17