TensorFlow2.5多标签训练验证出现predictions>=0断言错误如何解决
错误根因
你使用的tfa.losses.SigmoidFocalCrossEntropy默认要求输入的y_pred是未经过sigmoid激活的原始logits值(可正可负),而你配置的RecallAtPrecision、PrecisionAtRecall、AUC等分类指标要求输入预测值必须是[0,1]区间的概率,不能为负。训练前期模型输出的logits暂时没有出现负值,所以不会报错,训练到第5~10epoch后logits出现负值,就触发了predictions must be >= 0的断言校验。
解决方案
以下两种方案二选一即可:
方案1:调整模型输出为概率值(更推荐)
- 在模型最后一层添加
activation='sigmoid'参数,保证输出范围落在[0,1]区间 - 修改损失函数初始化代码,显式指定
from_logits=False:
loss_func = tfa.losses.SigmoidFocalCrossEntropy(gamma=1.5, alpha=0.25, from_logits=False)
该方案无需修改其他指标配置,逻辑更直观。
方案2:保留logits输出,给指标添加sigmoid转换
如果你需要保留模型输出logits的设计,可以对所有需要概率输入的指标做包装,输入前先做sigmoid转换:
# 定义通用包装函数 def wrap_with_sigmoid(metric): def wrapper(y_true, y_pred): return metric(y_true, tf.sigmoid(y_pred)) return wrapper # 修改get_metrics里的对应指标 def get_metrics(): NUM_CLASSES = config.data.num_classes metrics = [ wrap_with_sigmoid(tfa.metrics.F1Score(num_classes=NUM_CLASSES, average='micro', threshold=0.5, name="f1_micro")), wrap_with_sigmoid(tfa.metrics.F1Score(num_classes=NUM_CLASSES, average='macro', threshold=0.5, name="f1_macro")), wrap_with_sigmoid(tfa.metrics.F1Score(num_classes=NUM_CLASSES, average='weighted', threshold=0.5, name="f1_weighted")), wrap_with_sigmoid(tfa.metrics.HammingLoss(mode='multilabel', threshold=0.5)), wrap_with_sigmoid(tf.keras.metrics.RecallAtPrecision(0.8)), wrap_with_sigmoid(tf.keras.metrics.PrecisionAtRecall(0.8)), wrap_with_sigmoid(tf.keras.metrics.AUC(multi_label=True, curve='PR', name='auc_pr')) ] metrics += [wrap_with_sigmoid(IndividualAUC(multi_label=False, curve='PR',class_idx=i, name='auc_pr_{}'.format(i))) for i in range(NUM_CLASSES)] return metrics
内容的提问来源于stack exchange,提问作者Panomwat Warattaseth
相关产品推荐
相关产品推荐

