如何判断哪个 Keras 模型更好?

Posted

技术标签:

【中文标题】如何判断哪个 Keras 模型更好?【英文标题】:How to tell which Keras model is better? 【发布时间】:2016-04-14 14:40:17 【问题描述】:

我不明白在输出中使用哪种精度来比较我的 2 个 Keras 模型,看看哪个更好。

我是使用“acc”(来自训练数据?)一个还是“val acc”(来自验证数据?)一个?

每个时期都有不同的 accs 和 val accs。我如何知道整个模型的 acc 或 val acc?我是否对所有 epochs accs 或 val accs 进行平均以找到整个模型的 acc 或 val acc?

模型 1 输出

Train on 970 samples, validate on 243 samples
Epoch 1/20
0s - loss: 0.1708 - acc: 0.7990 - val_loss: 0.2143 - val_acc: 0.7325
Epoch 2/20
0s - loss: 0.1633 - acc: 0.8021 - val_loss: 0.2295 - val_acc: 0.7325
Epoch 3/20
0s - loss: 0.1657 - acc: 0.7938 - val_loss: 0.2243 - val_acc: 0.7737
Epoch 4/20
0s - loss: 0.1847 - acc: 0.7969 - val_loss: 0.2253 - val_acc: 0.7490
Epoch 5/20
0s - loss: 0.1771 - acc: 0.8062 - val_loss: 0.2402 - val_acc: 0.7407
Epoch 6/20
0s - loss: 0.1789 - acc: 0.8021 - val_loss: 0.2431 - val_acc: 0.7407
Epoch 7/20
0s - loss: 0.1789 - acc: 0.8031 - val_loss: 0.2227 - val_acc: 0.7778
Epoch 8/20
0s - loss: 0.1810 - acc: 0.8010 - val_loss: 0.2438 - val_acc: 0.7449
Epoch 9/20
0s - loss: 0.1711 - acc: 0.8134 - val_loss: 0.2365 - val_acc: 0.7490
Epoch 10/20
0s - loss: 0.1852 - acc: 0.7959 - val_loss: 0.2423 - val_acc: 0.7449
Epoch 11/20
0s - loss: 0.1889 - acc: 0.7866 - val_loss: 0.2523 - val_acc: 0.7366
Epoch 12/20
0s - loss: 0.1838 - acc: 0.8021 - val_loss: 0.2563 - val_acc: 0.7407
Epoch 13/20
0s - loss: 0.1835 - acc: 0.8041 - val_loss: 0.2560 - val_acc: 0.7325
Epoch 14/20
0s - loss: 0.1868 - acc: 0.8031 - val_loss: 0.2573 - val_acc: 0.7407
Epoch 15/20
0s - loss: 0.1829 - acc: 0.8072 - val_loss: 0.2581 - val_acc: 0.7407
Epoch 16/20
0s - loss: 0.1878 - acc: 0.8062 - val_loss: 0.2589 - val_acc: 0.7407
Epoch 17/20
0s - loss: 0.1833 - acc: 0.8072 - val_loss: 0.2613 - val_acc: 0.7366
Epoch 18/20
0s - loss: 0.1837 - acc: 0.8113 - val_loss: 0.2605 - val_acc: 0.7325
Epoch 19/20
0s - loss: 0.1906 - acc: 0.8010 - val_loss: 0.2555 - val_acc: 0.7407
Epoch 20/20
0s - loss: 0.1884 - acc: 0.8062 - val_loss: 0.2542 - val_acc: 0.7449

模型 2 输出

Train on 970 samples, validate on 243 samples
Epoch 1/20
0s - loss: 0.1735 - acc: 0.7876 - val_loss: 0.2386 - val_acc: 0.6667
Epoch 2/20
0s - loss: 0.1733 - acc: 0.7825 - val_loss: 0.1894 - val_acc: 0.7449
Epoch 3/20
0s - loss: 0.1781 - acc: 0.7856 - val_loss: 0.2028 - val_acc: 0.7407
Epoch 4/20
0s - loss: 0.1717 - acc: 0.8021 - val_loss: 0.2545 - val_acc: 0.7119
Epoch 5/20
0s - loss: 0.1757 - acc: 0.8052 - val_loss: 0.2252 - val_acc: 0.7202
Epoch 6/20
0s - loss: 0.1776 - acc: 0.8093 - val_loss: 0.2449 - val_acc: 0.7490
Epoch 7/20
0s - loss: 0.1833 - acc: 0.7897 - val_loss: 0.2272 - val_acc: 0.7572
Epoch 8/20
0s - loss: 0.1827 - acc: 0.7928 - val_loss: 0.2376 - val_acc: 0.7531
Epoch 9/20
0s - loss: 0.1795 - acc: 0.8062 - val_loss: 0.2445 - val_acc: 0.7490
Epoch 10/20
0s - loss: 0.1746 - acc: 0.8103 - val_loss: 0.2491 - val_acc: 0.7449
Epoch 11/20
0s - loss: 0.1831 - acc: 0.8082 - val_loss: 0.2477 - val_acc: 0.7449
Epoch 12/20
0s - loss: 0.1831 - acc: 0.8113 - val_loss: 0.2496 - val_acc: 0.7490
Epoch 13/20
0s - loss: 0.1920 - acc: 0.8000 - val_loss: 0.2459 - val_acc: 0.7449
Epoch 14/20
0s - loss: 0.1945 - acc: 0.7928 - val_loss: 0.2446 - val_acc: 0.7490
Epoch 15/20
0s - loss: 0.1852 - acc: 0.7990 - val_loss: 0.2459 - val_acc: 0.7449
Epoch 16/20
0s - loss: 0.1800 - acc: 0.8062 - val_loss: 0.2495 - val_acc: 0.7449
Epoch 17/20
0s - loss: 0.1891 - acc: 0.8000 - val_loss: 0.2469 - val_acc: 0.7449
Epoch 18/20
0s - loss: 0.1891 - acc: 0.8041 - val_loss: 0.2467 - val_acc: 0.7531
Epoch 19/20
0s - loss: 0.1853 - acc: 0.8072 - val_loss: 0.2511 - val_acc: 0.7449
Epoch 20/20
0s - loss: 0.1905 - acc: 0.8062 - val_loss: 0.2460 - val_acc: 0.7531

【问题讨论】:

【参考方案1】:

我是使用“acc”(来自训练数据?)一个还是“val acc”(来自验证数据?)一个?

如果您想估计模型泛化到新数据的能力(这可能是您想要做的),那么您可以查看验证准确度,因为验证拆分仅包含模型在运行期间从未见过的数据培训不能只记住。

如果您的训练数据准确性(“acc”)不断提高,而您的验证数据准确性(“val_acc”)变得更糟,您很可能处于overfitting 情况,即您的模型开始基本上只是记住数据。

每个时期都有不同的 accs 和 val accs。我如何知道整个模型的 acc 或 val acc?我是否对所有 epochs accs 或 val accs 进行平均以找到整个模型的 acc 或 val acc?

每个时期都是对所有数据的训练。在运行期间,模型的参数会根据您的损失函数进行调整。结果是一组具有一定能力泛化到新数据的参数。这种能力反映在验证准确性上。因此,将每个 epoch 视为自己的模型,如果针对另一个 epoch 进行训练,它可能会变得更好或更糟。它是变好还是变坏由验证准确度的变化来判断(更好=验证准确度增加)。因此选择验证准确率最高的时代模型。不要平均不同时期的准确度,这没有多大意义。您可以使用 Keras 回调 ModelCheckpoint 自动保存验证准确度最高的模型(请参阅 callbacks documentation)。

模型 1 中精度最高的是 0.7737,模型 2 中精度最高的是 0.7572。因此,您应该更好地查看模型 1(在 epoch 3)。尽管0.7737 可能只是一个随机异常值。

【讨论】:

模型检查点“如果验证损失减少,则在每个 epoch 后保存模型权重”。这是否“等同于”更高的验证准确性。看看我有时看到的数字,虽然验证损失降低了验证准确度并没有提高。为什么会这样? 假设您有 4 个示例,您的模型应该预测标签 1。现在它确实预测值 0.51 的 4 倍(每个都高于阈值 0.5,因此准确度测量认为预测是正确的)。在下一个时期,它将值更改为 0.49、0.49、0.49 和 0.95。损失函数的值会显着提高(因为从 0.51 到 0.95 变化很大),但是准确率会变差,因为现在三个值都低于 0.5 的阈值,所以它们被视为标签 0。 @aleju 只是想知道,增加 epoch 的数量会使模型变得更好吗?对于 epoch 的数量如何影响模型的准确性,我仍然很困惑。 只要验证准确度提高,只需使用ModelCheckpoint 回调即可自动将当前模型的权重保存到文件中。然后在测试或生产使用期间,您重建和编译相同的架构(层、激活等)并使用 model.load_weights(filename) 加载权重(在调用 model.predict(...) 或类似名称之前)。 保存最佳模型,定义cb = [ModelCheckpoint("weights.h5", save_best_only=True, save_weights_only=True)],训练时添加回调参数:model.fit(... callbacks=cb)【参考方案2】:

你需要重点减少 val_loss 或增加 val_acc,最终这并不重要。差异完全在随机/舍入误差范围内。

在实践中,由于过度拟合,训练损失可能会显着下降,这就是您要查看验证损失的原因。

在您的情况下,您可以看到您的训练损失并没有下降 - 这意味着您在每个 epoch 之后都没有学到任何东西。除了一些微不足道的线性拟合或截止值之外,这个模型似乎没有什么可学习的。

此外,当什么都不学,或者是微不足道的线性事物时,您应该在训练和验证方面取得类似的表现(微不足道的学习总是可以推广的)。在使用 validation_split 功能之前,您可能应该对数据进行洗牌。

【讨论】:

以上是关于如何判断哪个 Keras 模型更好?的主要内容,如果未能解决你的问题,请参考以下文章

如何将 keras 模型文件加载到 OpenCV 代码中?

如何理解Keras中的指标Metrics

评测 | CNTK在Keras上表现如何?能实现比TensorFlow更好的深度学习吗?

keras 如何保存训练集与验证集正确率的差最小那次epoch的网络及权重

Keras中模型的编译

添加功能确实会使模型更好吗?