【Python深度学习】model.compile()与model.evaluate()的关系解析,以及.predict()与.evaluate()的区别探讨
参考:https://www.jianshu.com/p/e9d535b906fa
model.evaluate() 和 compile() 之间的关系?
evaluate() 并不会“调用” compile(),但它依赖 compile 的结果。
模型使用前必须先 .compile(),否则 .fit() 和 .evaluate() 都不能用。
compile():设置好模型的“规则”(优化器 optimizer, 损失函数 loss, 评估指标 metrics等)evaluate():在预测完成后,会用你在 compile 中指定的指标,来评估结果并返回所以它们的关系是:
compile()先设置好规则 👉evaluate()才能使用这些规则进行打分。
evaluate() 里确实没有写 compile(),但它默认用的就是你之前 .compile() 时设置的内容
test_loss, test_acc, test_auc, test_precision, test_recall = self.model.evaluate(
X_test,
{'output_1': y_test, 'output_2': np.zeros((len(y_test), ...))},
verbose=0
)
并 没有再次显式调用 compile(),因为:
self.model.compile(...)(比如在 compile_model() 函数里).evaluate() 会自动使用之前设置的损失函数和评估指标X_test 和目标输出 y_test✅ 它背后的机制是:
# 假设你之前已 compile:
model.compile(loss=..., metrics=['accuracy', AUC(), ...])
# 现在可以直接调用
model.evaluate(X_test, y_test)
# evaluate 会自动用你在 compile 时定义的规则返回:
# loss, accuracy, auc, ...
为什么 .evaluate() 只输入 X_test 和 y_test,却能输出多个指标?
因为:
模型已经在
.compile()阶段 提前“绑定”好了损失函数和评估指标,这些并不是在.evaluate()时才传入的,而是早就存储在模型内部了。
可以理解成这样一个过程:
模型结构 = 一种“函数”
model = tf.keras.Model(...) # 定义好了结构,但还不能跑
compile() = 给这个“函数”附加了规则:
model.compile(
optimizer=Adam(...),
loss={...}, # 指定损失函数
metrics={'output_1': [...]} # 指定评估指标
)
此时模型内部就已经存储好这些指标和损失的计算方法了。
所以:你只需要在 .evaluate() 时喂数据,模型就会:
- 自动把
X_test喂进网络前向传播,得到预测结果y_pred - 调用你 compile 时配置的 loss 函数,计算
y_test vs y_pred的损失 - 调用你配置的 metrics,计算 accuracy、AUC、precision、recall……
- 然后按顺序返回这些值
.evaluate() 返回指标顺序怎么知道?
你可以查看它的指标名称列表:
print(model.metrics_names)
# ➜ ['loss', 'output_1_accuracy', 'output_1_auc', 'output_1_precision', 'output_1_recall']
所以如果你写:
loss, acc, auc, precision, recall = model.evaluate(...)
这就是多变量赋值,顺序必须与 metrics_names 一致。
.evaluate() 中的损失是怎么计算的?为什么说它是 y_test vs y_pred?
.evaluate() 的本质就是:
使用 训练好的模型,对测试集
X_test做预测(y_pred),然后 和真实值y_test比较,计算“损失”和“指标”。
损失不是简单“差值”,而是根据你设置的 损失函数(loss function) 来定义的。
例如:
| 任务类型 | 常见损失函数 | 作用 |
|---|---|---|
| 二分类 | 'binary_crossentropy' |
衡量预测概率和真实标签之间的差异(比简单差值更合理) |
| 回归 | 'mse'(均方误差) |
用平方差来衡量预测值和真实值之间的差异 |
| 多分类 | 'categorical_crossentropy' |
衡量一个概率分布(预测)和目标分布之间的距离 |
所以当你在 .compile() 中写了:
loss={'output_1': 'binary_crossentropy'}
Keras 在 .evaluate() 时就会按照 交叉熵函数 来计算每个 y_pred 和 y_test 之间的损失值,而不是简单地 abs(y_pred - y_test) 或平方差。
损失函数定义了“什么叫预测得不好”,不同任务有不同标准,这就是它的价值。
.predict() vs .evaluate() 的区别?
| 方法 | 作用 | 输出 | 是否需要标签 (y_test) |
计算指标 |
|---|---|---|---|---|
predict() |
仅做前向预测 | y_pred(模型输出) |
❌ 不需要 | ❌ 不计算损失、准确率等 |
evaluate() |
做预测 + 计算损失与指标 | loss, accuracy, AUC, … |
✅ 需要 y_test |
✅ 会计算并返回所有定义好的指标 |
举例说明:
用 .predict():
y_pred = model.predict(X_test)
你只会得到预测结果(比如概率或类别),但你得 自己写代码去评估预测得好不好(比如计算准确率、绘制 ROC)。
用 .evaluate():
loss, acc, auc = model.evaluate(X_test, y_test)
模型自动预测 + 自动根据你 .compile() 中定义的规则,计算 loss 和指标,一步完成。
总结
.predict()是预测;.evaluate()是预测 + 比较(用 compile 中定义的损失函数和指标)。
作者:新子y