TensorFlow音频分类:tf.math.confusion_matrix报错predictions含负值的解决
音频分类教程中混淆矩阵报错的原因与解决方法
问题场景
按照TensorFlow官方音频分类教程完成所有代码执行后,运行以下代码生成混淆矩阵时,在Kaggle和Jupyter Notebook中均出现错误:
confusion_mtx = tf.math.confusion_matrix(y_true, y_pred) plt.figure(figsize=(10, 8)) sns.heatmap(confusion_mtx, xticklabels=label_names, yticklabels=label_names, annot=True, fmt='g') plt.xlabel('Prediction') plt.ylabel('Label') plt.show()
错误信息
--------------------------------------------------------------------------- InvalidArgumentError Traceback (most recent call last) Cell In[32], line 1 ----> 1 confusion_mtx = tf.math.confusion_matrix(y_true, y_pred) 2 plt.figure(figsize=(10, 8)) 3 sns.heatmap(confusion_mtx, 4 xticklabels=label_names, 5 yticklabels=label_names, 6 annot=True, fmt='g') File /opt/conda/lib/python3.10/site-packages/tensorflow/python/util/traceback_utils.py:153, in filter_traceback.<locals>.error_handler(*args, **kwargs) 151 except Exception as e: 152 filtered_tb = _process_traceback_frames(e.__traceback__) ---> 153 raise e.with_traceback(filtered_tb) from None 154 finally: 155 del filtered_tb File /opt/conda/lib/python3.10/site-packages/tensorflow/python/ops/check_ops.py:487, in _binary_assert(sym, opname, op_func, static_func, x, y, data, summarize, message, name) 484 if message is not None: 485 data = [message] + list(data) ---> 487 raise errors.InvalidArgumentError( 488 node_def=None, 489 op=None, 490 message=('\n'.join(_pretty_print(d, summarize) for d in data))) 492 else: # not context.executing_eagerly() 493 if data is None: InvalidArgumentError: `predictions` contains negative values. Condition x >= 0 did not hold element-wise: x (shape=(832, 8) dtype=int64) = ['-10', '-4', '-1', '...']
报错原因
tf.math.confusion_matrix要求输入的y_true和y_pred必须是非负的整数类别索引,但当前传入的y_pred存在负数,且形状为(832,8)——这说明传入的不是模型输出的类别预测结果,而是模型最后一层的原始logits(未经过softmax转换的输出),甚至可能是预处理后的音频特征或错误张量。
正常流程中,模型输出的logits需要通过tf.argmax(axis=1)转换为每个样本对应的类别索引(取值范围为0到类别数-1的整数),才能用于生成混淆矩阵。
解决方法
1. 转换模型输出为类别索引
如果y_pred是模型输出的logits(形状为(样本数, 类别数)),需用tf.argmax提取每个样本概率最高的类别索引:
# 假设model为训练好的模型,test_ds为测试数据集 y_pred_logits = model.predict(test_ds) y_pred = tf.argmax(y_pred_logits, axis=1)
2. 确保真实标签为类别索引
如果y_true是one-hot编码形式(形状(样本数, 类别数)),同样需要转换为一维类别索引:
# 从测试数据集中提取真实标签 y_true = tf.concat([y for x, y in test_ds], axis=0) # 若为one-hot编码则转换为索引 y_true = tf.argmax(y_true, axis=1) if len(y_true.shape) == 2 else y_true
3. 验证输入形状
转换完成后,y_true和y_pred都应为一维张量(形状为(样本数,)),而非二维的(样本数, 类别数)。
修改后的完整代码
# 获取模型输出并转换为类别索引 y_pred_logits = model.predict(test_ds) y_pred = tf.argmax(y_pred_logits, axis=1) # 处理真实标签为一维类别索引 y_true = tf.concat([y for x, y in test_ds], axis=0) y_true = tf.argmax(y_true, axis=1) if len(y_true.shape) == 2 else y_true # 生成并可视化混淆矩阵 confusion_mtx = tf.math.confusion_matrix(y_true, y_pred) plt.figure(figsize=(10, 8)) sns.heatmap(confusion_mtx, xticklabels=label_names, yticklabels=label_names, annot=True, fmt='g') plt.xlabel('预测值') plt.ylabel('真实标签') plt.show()
内容的提问来源于stack exchange,提问作者Sazzad Hissain Khan
相关产品推荐
相关产品推荐

