多分类任务中ResNet模型验证损失与准确率始终为0的问题排查
ResNet多分类任务中验证指标始终为0的解决方案
问题场景
使用ResNet50开展8分类任务时,训练阶段损失和准确率变化正常,但添加验证环节后,每个epoch的val_loss和val_accuracy始终为0,即使修改测试生成器添加标签后问题仍未解决。
相关代码片段
模型定义
resnet = tf.keras.applications.ResNet50( include_top=False , weights='imagenet' , input_shape=(96, 96, 3) , pooling="avg" ) for layer in resnet.layers: layer.trainable = True model_resnet = tf.keras.Sequential() model_resnet.add(resnet) model_resnet.add(tf.keras.layers.Flatten()) model_resnet.add(tf.keras.layers.Dense(8, activation='softmax',name='output') ) model_resnet.compile( loss="sparse_categorical_crossentropy" , optimizer=tf.keras.optimizers.Adam(learning_rate=0.001) ,metrics=['accuracy'])
训练/测试生成器(修改前)
train_generator=img_gen.flow_from_dataframe(dataframe=train_dataset,x_col="file_loc",y_col='expr',target_size=(96, 96),batch_size=91,class_mode="raw") test_generator=img_gen.flow_from_dataframe(dataframe=test_dataset,x_col="file_loc",target_size=(96, 96),batch_size=93,y_col='expr',shuffle=False,class_mode=None)
验证训练代码
model_path = f"/content/weights" + "{val_accuracy:.4f}.hdf5" checkpoint = tf.keras.callbacks.ModelCheckpoint( model_path, monitor='val_accuracy', save_best_only=True, mode='max', verbose=1 ) history = model_resnet.fit_generator( train_generator, epochs=5, steps_per_epoch=STEP_SIZE_TRAIN_resnet, validation_data=test_generator, validation_steps=STEP_SIZE_TEST_resnet, max_queue_size=1, shuffle=True, callbacks=[checkpoint], verbose=1 )
核心问题分析
测试生成器class_mode配置错误:
训练生成器使用class_mode="raw",对应sparse_categorical_crossentropy所需的整数型标签,但修改后的测试生成器仍设置class_mode=None,导致生成器仅返回图像数据,不提供真实标签。模型在验证阶段没有标签可用于计算损失和准确率,因此指标显示为0。ModelCheckpoint路径定义错误:
代码中直接使用{val_accuracy:.4f}作为路径占位符,但此时val_accuracy变量未定义,会引发NameError,需改用Keras回调支持的动态占位符。
解决方案
1. 修正测试生成器的class_mode参数
将测试生成器的class_mode改为"raw",与训练生成器保持一致,确保生成器返回图像和对应的整数标签:
test_generator=img_gen.flow_from_dataframe( dataframe=test_dataset, x_col="file_loc", target_size=(96, 96), batch_size=93, y_col='expr', shuffle=False, class_mode="raw" )
2. 修正ModelCheckpoint的路径格式
使用Keras回调支持的动态占位符,避免未定义变量的错误,同时添加epoch编号防止模型文件被覆盖:
checkpoint = tf.keras.callbacks.ModelCheckpoint( "/content/weights_epoch{epoch:02d}_valacc{val_accuracy:.4f}.hdf5", monitor='val_accuracy', save_best_only=True, mode='max', verbose=1 )
3. 验证validation_steps计算正确性
确保STEP_SIZE_TEST_resnet的计算符合测试集样本数与batch_size的比例:
STEP_SIZE_TEST_resnet = len(test_dataset) // test_generator.batch_size # 处理剩余样本 if len(test_dataset) % test_generator.batch_size != 0: STEP_SIZE_TEST_resnet += 1
验证效果
修正后重新运行训练代码,验证阶段将正常计算val_loss和val_accuracy,指标会根据模型性能动态变化。
内容的提问来源于stack exchange,提问作者Alexandra Kapa
相关产品推荐
相关产品推荐

