如何在Keras中合并3个模型:按性别分类结果分支预测对应人群年龄
现有代码问题修正
首先你当前的子网络实现有两个明显问题需要先调整:
- 性别分类头(A10)使用1个神经元搭配
softmax激活是错误的,二分类场景下1神经元的softmax输出永远为1,无法实现0/1分类,需要把激活函数换成sigmoid - 你当前的男性/女性年龄分支直接对接性别分类的输出不符合设计逻辑,年龄预测的输入应该是原始输入特征,性别输出仅作为分支选择的判断依据,不应该作为年龄模型的输入特征
分支网络实现方案
基于TensorFlow Keras Functional API结合条件判断算子即可实现你要的分支路由逻辑,完整可运行代码如下:
import tensorflow as tf from tensorflow.keras import layers # 定义性别分类子模型 def build_gender_model(input_shape): A1 = layers.Input(shape=input_shape, name='gender_input') A2 = layers.Dense(512, activation='relu')(A1) A3 = layers.Dropout(0.5)(A2) A4 = layers.Dense(1024, activation='relu')(A3) A5 = layers.Dropout(0.5)(A4) A6 = layers.Dense(1024, activation='relu')(A5) A7 = layers.Dropout(0.4)(A6) A8 = layers.Dense(256, activation='relu')(A7) A9 = layers.Dropout(0.1)(A8) A10 = layers.Dense(1, activation='sigmoid', name='gender_output')(A9) return tf.keras.Model(inputs=A1, outputs=[A10, A1], name='gender_model') # 定义男性年龄预测子模型 def build_male_age_model(input_shape): B1 = layers.Input(shape=input_shape, name='male_age_input') B2 = layers.Dense(512, activation='relu')(B1) B3 = layers.Dropout(0.5)(B2) B4 = layers.Dense(1024, activation='relu')(B3) B5 = layers.Dropout(0.5)(B4) B6 = layers.Dense(1024, activation='relu')(B5) B7 = layers.Dropout(0.4)(B6) B8 = layers.Dense(256, activation='relu')(B7) B9 = layers.Dropout(0.1)(B8) B10 = layers.Dense(8, activation='softmax', name='male_age_output')(B9) return tf.keras.Model(inputs=B1, outputs=B10, name='male_age_model') # 定义女性年龄预测子模型 def build_female_age_model(input_shape): C1 = layers.Input(shape=input_shape, name='female_age_input') C2 = layers.Dense(512, activation='relu')(C1) C3 = layers.Dropout(0.5)(C2) C4 = layers.Dense(1024, activation='relu')(C3) C5 = layers.Dropout(0.5)(C4) C6 = layers.Dense(1024, activation='relu')(C5) C7 = layers.Dropout(0.4)(C6) C8 = layers.Dense(256, activation='relu')(C7) C9 = layers.Dropout(0.1)(C8) C10 = layers.Dense(8, activation='softmax', name='female_age_output')(C9) return tf.keras.Model(inputs=C1, outputs=C10, name='female_age_model') # 组装端到端模型 input_shape = pca.shape[1] inputs = layers.Input(shape=input_shape, name='main_input') # 先执行性别分类 gender_pred, raw_features = build_gender_model(input_shape)(inputs) # 二值化性别预测结果 gender_mask = tf.cast(tf.greater(gender_pred, 0.5), tf.bool) # 两个年龄分支并行计算 male_age_pred = build_male_age_model(input_shape)(raw_features) female_age_pred = build_female_age_model(input_shape)(raw_features) # 按性别选择对应分支的输出 final_age_pred = layers.Lambda(lambda x: tf.where(x[0], x[1], x[2]))([gender_mask, male_age_pred, female_age_pred]) # 生成最终端到端模型 end2end_model = tf.keras.Model(inputs=inputs, outputs=[gender_pred, final_age_pred], name='gender_age_pipeline')
整体准确率计算
自定义评估指标即可统计端到端准确率,规则为性别分类正确且对应年龄分支预测正确才算样本预测正确,实现代码如下:
def end2end_acc(y_true, y_pred): # y_true结构:[真实性别标签, 真实年龄标签] # y_pred结构:[预测性别输出, 预测年龄输出] gender_true = y_true[:, 0] age_true = y_true[:, 1] gender_pred = tf.cast(tf.greater(y_pred[:, 0], 0.5), tf.float32) age_pred = tf.cast(tf.argmax(y_pred[:, 1:], axis=1), tf.float32) gender_correct = tf.equal(gender_true, gender_pred) age_correct = tf.equal(age_true, age_pred) total_correct = tf.cast(tf.logical_and(gender_correct, age_correct), tf.float32) return tf.reduce_mean(total_correct)
训练时将该指标传入model.compile()的metrics参数即可自动统计。
内容的提问来源于stack exchange,提问作者Armağan
相关产品推荐
相关产品推荐

