Keras训练ResNet时Tensorboard验证损失异常偏高是否为预处理导致?
问题描述
基于Keras框架使用自有图像数据集微调ResNet模型时,Tensorboard持续上报的验证损失与训练损失无相关性,验证损失数值显著偏高。
橙色线为训练损失、蓝色线为验证损失
训练完成时Tensorboard记录的最终训练损失为0.06、验证损失为0.57,但手动执行模型评估时,测得验证损失与训练损失处于同一区间,数值约为0.07。
异常初步怀疑由预处理环节导致,模型输入与输出构建代码如下:
inp = tf.keras.Input(input_shape) resnet = tf.keras.applications.ResNet50V2(include_top=False, input_shape=input_shape, input_tensor=inp,pooling="avg") # Add ResNet50V2 specific preprocessing method into the model. preprocessed = tf.keras.layers.Lambda(lambda x: tf.keras.applications.resnet_v2.preprocess_input(x))(inp) out = resnet(preprocessed) out = tf.keras.layers.Dense(num_outputs, activation=None)(out)
模型训练相关代码如下:
model.compile( optimizer=tf.keras.optimizers.Adam(lrate), loss='mse', metrics=[tf.keras.metrics.MeanSquaredError()], ) model.fit( train_dataset, epochs=epochs, validation_data=val_dataset, callbacks=callbacks )
初步判断计算验证损失时预处理逻辑未生效,但无法定位具体原因。
根因分析
问题出在ResNet初始化时传入的input_tensor=inp参数:该参数会让ResNet层内部直接绑定原始输入张量inp作为计算入口,绕开后续定义的Lambda预处理层。
- 训练阶段的前向传播沿手动定义的
inp -> preprocessed(预处理层) -> resnet -> Dense输出路径执行,预处理逻辑正常生效,因此训练损失数值符合预期。 - 验证阶段Keras自动推导计算图的输入节点时,会识别到ResNet层绑定的原始输入
inp,直接将未经过预处理的原始验证集数据送入ResNet计算,最终得到虚高的验证损失。 - 手动评估时是沿完整定义的模型路径执行前向传播,预处理逻辑正常生效,因此得到的损失值和训练损失处于同一区间。
修复方案
移除ResNet初始化时绑定原始输入的input_tensor=inp配置,将预处理后的张量传入ResNet即可,修正后的代码示例:
inp = tf.keras.Input(input_shape) # 先执行预处理 preprocessed = tf.keras.layers.Lambda(lambda x: tf.keras.applications.resnet_v2.preprocess_input(x))(inp) # 初始化ResNet时不绑定原始输入,直接调用层实例传入预处理后的张量 resnet = tf.keras.applications.ResNet50V2(include_top=False, input_shape=input_shape, pooling="avg") resnet_out = resnet(preprocessed) out = tf.keras.layers.Dense(num_outputs, activation=None)(resnet_out)
内容的提问来源于stack exchange,提问作者Patrick
相关产品推荐
相关产品推荐

