训练多输出自编码器时损失全为NaN该如何修复?
问题修复方案
1. 修复代码语法与逻辑错误
你现有代码里存在多个可直接导致loss输出nan的错误,优先修复:
- 解码器输入行缺少右括号:
原错误代码:
修正为:decoder_input=keras.layers.Dense(hidden_layers_decoder[0],activation='tanh'(encoder_output)decoder_input=keras.layers.Dense(hidden_layers_decoder[0],activation='tanh')(encoder_output) - Committor预测分支循环变量引用错误:
pb分支循环用迭代变量k,但你错误引用了之前解码器循环的变量j,会导致层维度不匹配:
原错误代码:
修正为:for k in range(nhid-1): pb_cal=keras.layers.Dense(hidden_layers_decoder[j+1],activation='sigmoid')(pb_cal)for k in range(nhid-1): pb_cal=keras.layers.Dense(hidden_layers_decoder[k+1],activation='sigmoid')(pb_cal) - Committor输出层连接错误:
你前面堆叠了pb分支的隐藏层,最后输出层却直接接了编码器输出,前面的隐藏层完全没生效,甚至可能引发维度错误:
原错误代码:
修正为:pb_output=keras.layers.Dense(npb,activation='sigmoid',name='pb_decoder')(encoder_output)pb_output=keras.layers.Dense(npb,activation='sigmoid',name='pb_decoder')(pb_cal)
2. 修复模型结构缺陷
- 编码器全用线性激活:多层线性层叠加等价于单层线性层,完全没有非线性拟合能力,容易出现梯度爆炸/消失。建议将编码器的激活函数替换为
relu或者tanh。 - 加入梯度裁剪防止梯度爆炸:修改优化器定义,加入梯度裁剪参数,避免梯度过大导致权重更新为nan:
opt = keras.optimizers.Adam(learning_rate=0.001, clipnorm=1.0)
3. 数据预处理检查
确认你已经对输入特征做了归一化,将输入缩放到[0,1]或者[-1,1]区间,避免前向传播时计算出过大的数值触发nan。
4. 分步调试验证
修复上述问题后,先取小批量数据(比如10条样本)做一轮训练,确认loss不再为nan后再全量训练,若仍有问题可以逐层打印输出值,定位是哪一层出现了nan计算。
内容的提问来源于stack exchange,提问作者Tanmoy Paul
相关产品推荐
相关产品推荐

