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

CNN训练首轮出现NaN损失及MAE问题求助(附优化疑问)

解决方案:CNN训练NaN问题及MAE优化

一、解决带BatchNormalization时的NaN问题

出现NaN的核心是训练过程中数值不稳定,结合你的代码和日志,可从以下几点调整:

1. 降低初始学习率

你用的Adam初始学习率0.01远高于默认的0.001,ReLU激活本身易产生大梯度,配合BN的批量统计,极易导致权重更新过大引发数值溢出。修改代码:

modelCNN.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=0.001), loss='mean_absolute_error', metrics=['mae'])

2. 对输入数据做标准化处理

BN依赖批量内数据的均值和方差统计,若输入数据范围过大(比如未归一化的0-255像素值),会导致BN计算的方差过小甚至趋近于0,引发除以0的NaN问题。训练前添加数据归一化:

# 先缩放到0-1,再标准化到均值0、方差1
X_train = X_train / 255.0
X_test = X_test / 255.0

mean = X_train.mean()
std = X_train.std()
X_train = (X_train - mean) / std
X_test = (X_test - mean) / std

3. 调整BatchNormalization超参数

默认epsilon=1e-5太小,批量方差极小时易出问题;momentum=0.99对于TPU大批次可适当调小,让BN更快适应数据分布:

modelCNN.add(tf.keras.layers.BatchNormalization(epsilon=1e-3, momentum=0.9))

4. 优化学习率衰减函数

当前公式在首轮无衰减且速度偏慢,可改成更温和的指数衰减,或从第2轮开始衰减:

def scheduler(epoch, lr):
    if epoch == 0:
        return lr  # 首轮不衰减
    return lr * 0.95  # 每轮衰减5%

5. 检查标签数据是否异常

确认Y_train和Y_test中没有NaN、无穷大或极端值,这些会直接导致Loss计算出现NaN。


二、解决MAE下降慢且不稳定的问题

移除BN后模型稳定性下降,可通过以下方式优化:

1. 对输出标签做归一化

若Y数值范围大(比如几十上百),MAE的Loss值过高会导致优化器难以稳定更新。将Y缩放到0-1或均值0的范围,训练后再反归一化:

# 标签归一化
y_mean = Y_train.mean()
y_std = Y_train.std()
Y_train = (Y_train - y_mean) / y_std
Y_test = (Y_test - y_mean) / y_std

# 预测时反归一化
predictions = modelCNN.predict(X_test) * y_std + y_mean

2. 添加正则化与Dropout

防止过拟合导致的MAE震荡,在卷积层和全连接层加入L2正则化或Dropout:

from tensorflow.keras import regularizers

# 卷积层加L2正则化
modelCNN.add(tf.keras.layers.Conv2D(100, (8, 8), strides=(2, 2), activation='relu', 
                                    kernel_regularizer=regularizers.l2(1e-4),
                                    input_shape=(256, 256, 1)))
# 全连接层前加Dropout
modelCNN.add(tf.keras.layers.GlobalMaxPooling2D())
modelCNN.add(tf.keras.layers.Dropout(0.3))
modelCNN.add(tf.keras.layers.Dense(100, activation='relu', kernel_regularizer=regularizers.l2(1e-4)))

3. 调整模型结构

  • 减少卷积滤波器数量:第一个Conv2D用64代替100,降低参数规模避免训练震荡;
  • 调整池化策略:将第一个MaxPooling的strides从(3,3)改为(2,2),保留更多特征;
  • 重新加入BatchNormalization:在解决NaN问题后恢复BN,它本身能稳定训练、降低梯度震荡。

4. 使用自适应学习率回调

替换固定衰减策略,用ReduceLROnPlateau在验证MAE连续不下降时自动降学习率:

lr_schedule = tf.keras.callbacks.ReduceLROnPlateau(
    monitor='val_mae',
    factor=0.5,         # 每次衰减为原学习率的50%
    patience=5,         # 连续5轮无下降则触发衰减
    min_lr=1e-6         # 最小学习率阈值
)

modelCNN.fit(X_train, Y_train, epochs=96, validation_data=(X_test, Y_test), callbacks=[lr_schedule])

5. 增大批量大小

TPU适合大批次训练,增大batch_size(比如256或512,根据TPU内存调整)可让BN统计更准确,梯度更新更稳定:

modelCNN.fit(X_train, Y_train, epochs=96, validation_data=(X_test, Y_test), 
             batch_size=256, callbacks=[lr_schedule])

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 21:40:34