TensorFlow两种测试准确率差异:evaluate与手动计算结果不符
核心差异与问题分析
两种评估流程不一致,准确率差异巨大的核心原因主要有以下几点:
1. 数据集迭代特性导致标签与预测错位
TensorFlow的BatchDataset是迭代器式数据集,默认情况下:
- 若数据集使用了
shuffle且未设置固定随机种子、未调用cache(),每次遍历的样本顺序会随机变化 - 遍历一次后数据集会被耗尽,再次遍历会从头重新生成(若未缓存,顺序依然随机)
你的手动流程中,先遍历一次test_set获取true_labels,再遍历一次获取输入做预测,两次遍历的样本顺序完全不对应,导致预测标签和真实标签错位,计算出的准确率接近随机猜测水平(比如29%符合多分类任务的随机准确率特征)。
而model.evaluate是在同一次遍历中同时读取输入x和标签y,样本与标签严格对应,不会出现错位问题。
2. 代码存在变量名错误
手动代码最后一行使用了res_labels,但前面定义的预测标签变量是predicted_labels,这是明显笔误。即使实际运行时修正了该问题,核心的数据集顺序错位问题依然会导致准确率异常。
3. 模型推理模式的潜在影响(次要)
model.evaluate和model.predict都会自动将模型切换到推理模式(禁用Dropout、BatchNormalization的训练状态等),这一点两者逻辑一致。但如果加载权重后手动设置过model.trainable = True或model.train(),会导致预测时使用训练模式,可能影响结果,但这种情况导致的准确率下降通常不会如此极端,属于次要排查点。
修复方案
- 先缓存数据集,确保两次遍历的样本顺序一致:
test_set = test_set.cache() # 执行后续操作 true_labels= tf.concat([y for x, y in test_set], axis=0) test_set_inputs = test_set.map(lambda x,y : x) predicted_labels = tf.argmax(model.predict(test_set_inputs), axis=1) print('acc ', accuracy_score(predicted_labels, true_labels))
- 或在一次遍历中同时获取输入和标签,避免两次遍历:
true_list = [] pred_list = [] for x, y in test_set: true_list.append(y) pred = tf.argmax(model.predict(x, verbose=0), axis=1) pred_list.append(pred) true_labels = tf.concat(true_list, axis=0) predicted_labels = tf.concat(pred_list, axis=0) print('acc ', accuracy_score(predicted_labels, true_labels))
- 务必修正变量名错误,确保
predicted_labels与true_labels对应。
内容的提问来源于stack exchange,提问作者Los
相关产品推荐
相关产品推荐

