Keras多输出模型训练时整体准确率不显示的问题咨询
我来帮你逐一梳理这两个问题:
问题1:loss和val_loss是否代表整体损失与验证损失?
没错,在你这种多输出模型里,训练日志里的loss就是模型所有输出头损失的总和——如果你在编译模型时设置了loss_weights参数,那就是加权后的总和;如果没设置,就是各个输出头损失直接相加的结果。对应的val_loss则是在验证集上计算得到的整体损失值,逻辑和训练集的loss完全一致。
顺带提一句,每个输出头的单独损失其实也会被计算,但默认不会显示在日志里。如果想查看单个输出的损失,可以在metrics字典里给对应输出额外添加损失指标(比如给output_a加上crossentropy),这样日志里就会显示该输出的单独损失了。
问题2:如何让整体准确率显示在训练日志中?
首先得明确:你的模型里既有分类任务(output_a、output_e)又有回归任务(output_b/c/d),回归任务本身不存在“准确率”这个指标,所以这里的“整体准确率”应该是指分类任务的综合准确率。要实现这个,你需要自定义一个整体准确率指标,然后把它加入到模型的metrics中,具体步骤如下:
步骤1:自定义整体准确率指标
根据你的任务需求,比如把output_a和output_e的准确率取平均(你也可以根据任务重要性设置不同权重),可以写一个自定义函数:
import tensorflow as tf from tensorflow.keras import backend as K def overall_class_accuracy(y_true, y_pred): # 拆分多输出的真实标签与预测值 y_true_a, _, _, _, y_true_e = y_true y_pred_a, _, _, _, y_pred_e = y_pred # 计算output_a的分类准确率(因为用了交叉熵,需要先转成类别索引) acc_a = K.cast(K.equal(K.argmax(y_true_a, axis=-1), K.argmax(y_pred_a, axis=-1)), K.floatx()) acc_a = K.mean(acc_a) # 计算output_e的分类准确率 acc_e = K.mean(K.cast(K.equal(K.argmax(y_true_e, axis=-1), K.argmax(y_pred_e, axis=-1)), K.floatx())) # 返回两个分类任务的平均准确率,可根据需求调整权重 return (acc_a + acc_e) / 2
步骤2:在模型编译时添加自定义指标
修改模型编译代码,把自定义的整体准确率加入到metrics字典中(这里给整体指标起个直观的名字,比如overall_acc):
model.compile( optimizer='adam', loss={'output_a': 'crossentropy', 'output_b': 'mse', 'output_c': 'mse', 'output_d': 'mse', 'output_e': 'categorical_crossentropy'}, metrics={ 'output_a': ['crossentropy', 'categorical_accuracy'], 'output_b': 'mse', 'output_c': 'mse', 'output_d': 'mse', 'output_e': 'categorical_accuracy', 'overall_acc': overall_class_accuracy } )
这样训练时,日志里就会显示overall_acc和val_overall_acc这两个整体准确率指标了。
如果你只是想查看各个分类输出的单独准确率,那更简单——直接给output_a的metrics加上categorical_accuracy,日志里就会显示output_a_categorical_accuracy和output_e_categorical_accuracy了。
内容的提问来源于stack exchange,提问作者Grigorios Kalliatakis

