Keras模型训练时损失函数指数级负向增长问题求助
训练二分类模型时损失指数级负增长的问题排查与解决
问题现象
运行训练代码后,损失值呈指数级负向增长,准确率始终徘徊在随机水平(约10%-18%),无法有效收敛。
训练代码:
hist=model.fit(train,epochs=20,validation_data=val,callbacks=[tensorboard_callback])
训练日志:
Epoch 1/20 18/18 [==============================] - 16s 790ms/step - loss: -1795.6414 - accuracy: 0.1319 - val_loss: -8472.8076 - val_accuracy: 0.1625 Epoch 2/20 18/18 [==============================] - 14s 718ms/step - loss: -79825.2422 - accuracy: 0.1493 - val_loss: -311502.5625 - val_accuracy: 0.1250 Epoch 3/20 18/18 [==============================] - 14s 720ms/step - loss: -1431768.2500 - accuracy: 0.1337 - val_loss: -3777775.2500 - val_accuracy: 0.1375 Epoch 4/20 18/18 [==============================] - 14s 716ms/step - loss: -11493728.0000 - accuracy: 0.1354 - val_loss: -28981542.0000 - val_accuracy: 0.1312 Epoch 5/20 18/18 [==============================] - 14s 747ms/step - loss: -61516224.0000 - accuracy: 0.1372 - val_loss: -127766784.0000 - val_accuracy: 0.1250 Epoch 6/20 18/18 [==============================] - 14s 719ms/step - loss: -251817104.0000 - accuracy: 0.1302 - val_loss: -401455168.0000 - val_accuracy: 0.1813 Epoch 7/20 18/18 [==============================] - 14s 755ms/step - loss: -731479360.0000 - accuracy: 0.1476 - val_loss: -1354252672.0000 - val_accuracy: 0.1375 Epoch 8/20 18/18 [==============================] - 14s 753ms/step - loss: -2031392128.0000 - accuracy: 0.1354 - val_loss: -3004264448.0000 - val_accuracy: 0.1625 Epoch 9/20 18/18 [==============================] - 14s 711ms/step - loss: -4619375104.0000 - accuracy: 0.1302 - val_loss: -7603259904.0000 - val_accuracy: 0.1125 Epoch 10/20 2/18 [==>...........................] - ETA: 10s - loss: -7608679424.0000 - accuracy: 0.1094
现有配置
模型编译设置
model.compile(optimizer='adam', loss=tf.keras.losses.BinaryCrossentropy(), metrics=['accuracy'])
模型结构
model.add(Conv2D(16,(3,3),1,activation='relu',input_shape=(256,256,3))) model.add(MaxPooling2D()) model.add(Conv2D(32,(3,3),1,activation='relu')) model.add(MaxPooling2D()) model.add(Conv2D(16,(3,3),1,activation='relu')) model.add(MaxPooling2D()) model.add(Flatten()) model.add(Dense(256,activation='relu')) model.add(Dense(1,activation='sigmoid'))
数据预处理
data=data.map(lambda x,y: (x/255, y))
GPU配置
gpus =tf.config.experimental.list_physical_devices('GPU') for gpu in gpus: tf.config.experimental.set_memory_growth(gpu,True)
解决方案
核心原因分析
BinaryCrossentropy的数学公式为:-y*log(p) - (1-y)*log(1-p),其中p是模型输出(0到1之间),y是真实标签。正常情况下损失值必然为正,出现负损失说明标签y的取值不符合要求,或模型训练过程中出现梯度爆炸导致参数失控。
具体修复步骤
检查标签取值
确认训练集和验证集的标签y严格为0或1,不存在负数、大于1的数值或其他异常值。可以通过以下代码快速验证:# 检查训练集标签范围 y_values = np.concatenate([y for x, y in train], axis=0) print(f"标签最小值: {np.min(y_values)}, 最大值: {np.max(y_values)}")调整学习率
默认Adam学习率(1e-3)可能过高,导致梯度爆炸。降低学习率至1e-5尝试:model.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=1e-5), loss=tf.keras.losses.BinaryCrossentropy(), metrics=['accuracy'])添加梯度裁剪
限制梯度范围,防止参数更新幅度过大:optimizer = tf.keras.optimizers.Adam(clipvalue=1.0) model.compile(optimizer=optimizer, loss=tf.keras.losses.BinaryCrossentropy(), metrics=['accuracy'])验证数据管道
确认数据预处理的map操作未错误修改标签y,确保输入模型的特征和标签对应正确。
内容的提问来源于stack exchange,提问作者Alphacell
相关产品推荐
相关产品推荐

