Keras Transformer时间序列二分类训练loss为nan、精度无提升如何解决
问题根因
- 池化层参数配置错误:你使用的
GlobalAveragePooling1D指定了data_format="channels_first",但时间序列输入的常规格式为(样本数, 时间步, 特征数),特征维度(通道维度)在最后一位,对应默认的channels_last格式。参数配置错误会导致张量维度计算完全错位,后续层运算时出现数值溢出/无效计算,直接生成nan损失。 - 二分类配置不匹配:你采用
softmax+categorical_crossentropy的组合,要求输出维度n_classes=2,且标签必须为one-hot编码格式。如果你的num_class设为1,或者标签仍为单维度的0/1值,会导致softmax输出恒为1,交叉熵计算时出现log(0)的非法操作,直接返回nan。同时你使用binary_accuracy作为评估指标,和categorical类损失的适配性也存在问题。 - 超参数设置异常:你设置的
ff_dim=2数值过小,Transformer编码器的前馈网络维度远低于输入特征维度时,容易出现特征信息丢失、梯度爆炸/消失的问题,进一步加剧数值异常。
修复方案
- 修正池化层参数:删除
GlobalAveragePooling1D的data_format参数,使用默认的channels_last即可,修改后代码为:
x = layers.GlobalAveragePooling1D()(x)
- 调整二分类输出配置(推荐方案):
将输出层改为sigmoid激活适配二分类,同步修改损失函数,和你当前使用的binary_accuracy完全适配,无需对标签做one-hot编码:
# 输出层修改 outputs = layers.Dense(1, activation="sigmoid")(x) # 编译时损失函数修改 model.compile( loss="binary_crossentropy", optimizer=keras.optimizers.Adam(learning_rate=1e-4), metrics=["binary_accuracy"], )
如果需要保留softmax的配置,需确保n_classes=2,且training_output_data为shape是(样本数,2)的one-hot编码标签,同步将评估指标改为categorical_accuracy即可。
- 检查输入数据有效性:运行以下代码确认数据无无效值:
import numpy as np print(np.isnan(training_input_data).any()) print(np.isinf(training_input_data).any()) print(np.isnan(training_output_data).any()) print(np.isinf(training_output_data).any())
若返回True,提前对无效值做删除或填充处理。
- 调整超参数:将
ff_dim调整为32/64,避免因前馈网络维度不足导致的特征丢失问题,学习率可调整为1e-4,加快收敛速度。
内容的提问来源于stack exchange,提问作者Hense
相关产品推荐
相关产品推荐

