基于预训练VGG16的年龄回归自定义MAE指标失效,求修正方案
问题分析与代码修正
你的核心问题是用了分类任务的逻辑处理回归任务:原代码依赖argmax提取类别,但年龄回归的标签是连续数值,没有类别维度,直接用argmax会导致维度错误或逻辑完全偏离目标。
以下针对两种常见场景给出修正方案:
场景1:计算特定年龄值样本的MAE
如果你的子文件夹对应单个年龄(比如20/、21/),需要计算该年龄样本的预测绝对误差均值:
import tensorflow.keras.backend as K def single_age_mae(target_age): def mae(y_true, y_pred): # 筛选出真实年龄等于target_age的样本 mask = K.cast(K.equal(y_true, target_age), K.floatx()) # 避免除以0,当没有该年龄样本时返回极小值防止报错 mask_sum = K.maximum(K.sum(mask), 1e-6) # 计算该年龄样本的绝对误差,再加权平均 absolute_error = K.abs(y_true - y_pred) * mask return K.sum(absolute_error) / mask_sum mae.__name__ = f'mae_age_{target_age}' return mae
场景2:计算特定年龄区间样本的MAE
如果子文件夹对应年龄区间(比如20-25/、26-30/),需要计算该区间内样本的MAE:
import tensorflow.keras.backend as K def age_range_mae(min_age, max_age): def mae(y_true, y_pred): # 筛选出真实年龄在[min_age, max_age]区间的样本 mask = K.cast(K.logical_and(y_true >= min_age, y_true <= max_age), K.floatx()) mask_sum = K.maximum(K.sum(mask), 1e-6) absolute_error = K.abs(y_true - y_pred) * mask return K.sum(absolute_error) / mask_sum mae.__name__ = f'mae_age_{min_age}_{max_age}' return mae
使用方式
在编译模型时,将自定义指标传入:
from tensorflow.keras.applications import VGG16 from tensorflow.keras.layers import Dense, Flatten from tensorflow.keras.models import Model # 构建回归模型 base_model = VGG16(weights='imagenet', include_top=False, input_shape=(224,224,3)) x = Flatten()(base_model.output) x = Dense(256, activation='relu')(x) output = Dense(1, activation='linear')(x) # 回归任务用linear激活 model = Model(inputs=base_model.input, outputs=output) # 编译时添加自定义指标 model.compile(optimizer='adam', loss='mse', metrics=['mae', single_age_mae(25), age_range_mae(20,30)])
内容的提问来源于stack exchange,提问作者Monika Roopak
相关产品推荐
相关产品推荐

