使用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')
解决思路
替换
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。简化输入层定义
用明确的形状定义替代type_spec,避免Dataset的类型规范干扰掩码传递:model.add(tf.keras.layers.Input(shape=(3177, 2)))检查LSTM激活函数
relu激活在遇到inf时会直接输出inf,进一步放大数值异常。如果坚持用inf填充,可先尝试把LSTM的激活换成tanh(原生LSTM默认激活),再观察损失变化。验证掩码有效性
在模型中添加中间输出,查看掩码是否正确生成: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
相关产品推荐
相关产品推荐

