CategoryResourceRepost/极客时间专栏/geek/深度学习推荐系统实战/模型评估篇/特别加餐|TensorFlow的模型离线评估实践怎么做?.md
louzefeng bf99793fd0 del
2024-07-09 18:38:56 +00:00

10 KiB
Raw Blame History

你好,我是王喆。

上两节课,我们学习了离线评估的主要方法以及离线评估的主要指标。那这些方法和指标具体是怎么使用的,会遇到哪些问题呢?我们之前实现的深度学习模型的效果怎么样呢?

这节课我们直接进入实战在TensorFlow环境下评估一下我们之前实现过的深度学习模型。一方面这能帮助我们进一步加深对离线评估方法和指标的理解另一方面也能检验一下我们自己模型的效果。

训练集和测试集的生成

离线评估的第一步就是要生成训练集和测试集在这次的评估实践中我会选择最常用的Holdout检验的方式来划分训练集和测试集。划分的方法我们已经在第23讲里用Spark实现过了就是调用Spark中的randomSplit函数进行划分具体的代码你可以参考 FeatureEngForRecModel对象中的splitAndSaveTrainingTestSamples函数。

这里我们按照8:2的比例把全量样本集划分为训练集和测试集再把它们分别存储在SparrowRecSys/src/main/resources/webroot/sampledata/trainingSamples.csvSparrowRecSys/src/main/resources/webroot/sampledata/testSamples.csv路径中。

在TensorFlow内部我们跟之前载入数据集的方式一样调用get_dataset方法分别载入训练集和测试集就可以了。

TensorFlow评估指标的设置

在载入训练集和测试集后我们需要搞清楚如何在TensorFlow中设置评估指标并通过这些指标观察模型在每一轮训练上的效果变化以及最终在测试集上的表现。这个过程听起来还挺复杂好在TensorFlow已经为我们提供了非常丰富的评估指标这让我们可以在模型编译阶段设置metrics来指定想要使用的评估指标。

具体怎么做呢我们一起来看看下面的代码它是设置评估指标的一个典型过程。首先我们在model complie阶段设置准确度Accuracy、ROC曲线AUCtf.keras.metrics.AUC(curve='ROC')、PR曲线AUCtf.keras.metrics.AUC(curve='PR')),这三个在评估推荐模型时最常用的指标。

同时在训练和评估过程中模型还会默认产生损失函数loss这一指标。在模型编译时我们采用了binary_crossentropy作为损失函数所以这里的Loss指标就是我们在上一节课介绍过的二分类问题的模型损失Logloss。

在设置好评估指标后模型在每轮epoch结束后都会输出这些评估指标的当前值。在最后的测试集评估阶段我们可以调用model.evaluate函数来生成测试集上的评估指标。具体的实现代码你可以参考SparrowRecsys项目中深度推荐模型相关的代码。

# compile the model, set loss function, optimizer and evaluation metrics
model.compile(
    loss='binary_crossentropy',
    optimizer='adam',
    metrics=['accuracy', tf.keras.metrics.AUC(curve='ROC'), tf.keras.metrics.AUC(curve='PR')])
# train the model
model.fit(train_dataset, epochs=5)
# evaluate the model
test_loss, test_accuracy, test_roc_auc, test_pr_auc = model.evaluate(test_dataset)

在执行这段代码的时候它的输出是下面这样的。从中我们可以清楚地看到每一轮训练的Loss、Accuracy、ROC AUC、PR AUC这四个指标的变化以及最终在测试集上这四个指标的结果。

Epoch 1/5
8236/8236 [==============================] - 60s 7ms/step - loss: 3.0724 - accuracy: 0.5778 - auc: 0.5844 - auc_1: 0.6301
Epoch 2/5
8236/8236 [==============================] - 55s 7ms/step - loss: 0.6291 - accuracy: 0.6687 - auc: 0.7158 - auc_1: 0.7365
Epoch 3/5
8236/8236 [==============================] - 56s 7ms/step - loss: 0.5555 - accuracy: 0.7176 - auc: 0.7813 - auc_1: 0.8018
Epoch 4/5
8236/8236 [==============================] - 56s 7ms/step - loss: 0.5263 - accuracy: 0.7399 - auc: 0.8090 - auc_1: 0.8305
Epoch 5/5
8236/8236 [==============================] - 56s 7ms/step - loss: 0.5071 - accuracy: 0.7524 - auc: 0.8256 - auc_1: 0.8481


1000/1000 [==============================] - 5s 5ms/step - loss: 0.5198 - accuracy: 0.7427 - auc: 0.8138 - auc_1: 0.8430
Test Loss 0.5198314250707626, Test Accuracy 0.7426666617393494, Test ROC AUC 0.813848614692688, Test PR AUC 0.8429719805717468


总的来说随着训练的进行模型的Loss在降低而Accuracy、Roc AUC、Pr AUC这几个指标都在升高这证明模型的效果随着训练轮数的增加在逐渐变好。

最终我们就得到了测试集上的评估指标。你会发现测试集上的评估结果相比训练集有所下降比如Accuracy从0.7524下降到了0.7427ROC AUC从0.8256下降到了0.8138。这是非常正常的现象,因为模型在训练集上都会存在着轻微过拟合的情况。

如果测试集的评估结果相比训练集出现大幅下降比如下降幅度超过了5%就说明模型产生了非常严重的过拟合现象我们就要反思一下是不是在模型设计过程中出现了一些问题比如模型的结构对于这个问题来说过于复杂模型的层数或者每层的神经元数量过多或者我们要看一看是不是需要加入Dropout正则化项来减轻过拟合的风险。

除了观察模型自己的效果,在模型评估阶段,我们更应该重视不同模型之间的对比,这样才能确定我们最终上线的模型,下面我们就做一个模型效果的横向对比。

模型的效果对比

在推荐模型篇我们已经实现了EmbeddingMLP、NerualCF、Wide&Deep以及DeepFM这四个深度学习模型后来还有同学添加了DIN的模型实现。

那接下来我们就利用这节课的模型评估方法来尝试对比一下这几个模型的效果。首先我直接把这些模型在测试集上的评估结果记录到了表格里当然我更建议你利用SparrowRecsys项目中的代码自己来计算一下多实践一下我们刚才说的模型评估方法。

通过上面的比较我们可以看出Embedding MLP和Wide&Deep模型在我们的MovieLens这个小规模数据集上的效果最好它们两个的指标也非常接近只不过是在不同指标上有细微的差异比如模型Loss指标上Wide&Deep模型好一点在Accuracy、ROC AUC、PR AUC指标上Embedding MLP模型好一点。

遇到这种情况我们该如何挑出更好的那个模型呢一般我们会在两个方向上做尝试一是做进一步的模型调参特别是对于复杂一点的Wide&Deep模型我们可以尝试通过参数的Fine Tuning微调让模型达到更好的效果二是如果经过多次尝试两个模型的效果仍比较接近我们就通过线上评选出最后的胜出者。

说完了效果好的指标不知道你有没有注意到一个反常的现象那就是模型DeepFM的评估结果非常奇怪怎么个奇怪法呢理论上来说DeepFM的表达能力是最强的可它现在展示出来的评估结果却最差。这种情况就极有可能是因为模型遇到了过拟合问题。为了验证个想法我们再来看一下DeepFM在训练集上的表现如下表所示

我们很惊讶地发现DeepFM在测试集上的表现比训练集差了非常多。毫无疑问这个模型过拟合了。当然这里面也有我们数据的因素因为我们采用了一个规模很小的采样过的MovieLens数据集在训练复杂模型时小数据集往往更难让模型收敛并且由于训练不充分的原因模型中很多参数其实没有达到稳定的状态因此在测试集上的表现往往会呈现出比较大的随机性。

通过DeepFM模型效果对比的例子也再一次印证了我们在“最优的模型结构该怎么找?”那节课的结论:推荐模型没有银弹,每一个业务,每一类数据,都有最合适的模型结构,并不是说最复杂的,最新的模型结构就是最好的模型结构,我们需要因地制宜地调整模型和参数,这才是算法工程师最大的价值所在。

小结

这节实践课我们基于TensorFlow进行了深度推荐模型的评估整个实践过程可以分成三步。

第一步是导入Spark分割好的训练集和测试集。

第二步是在TensorFlow中设置评估指标再在测试集上调用model.evaluate函数计算这些评估指标。在实践过程中我们要清楚有哪些TensorFlow的指标可以直接调用。那在这节课里我们用到了最常用的Loss、Accuracy、ROC AUC、PR AUC四个指标。

第三步是根据四个深度推荐模型的评估结果进行模型效果的对比。通过对比的结果我们发现Embedding MLP和Wide&Deep的效果是最好的。同时我们也发现本该表现很好的DeepFM模型它的评估结果却比较差原因是模型产生了非常严重的过拟合问题。

因此,在实际工作中,我们需要通过不断调整模型结构、模型参数,来找到最合适当前业务和数据集的模型。

课后思考

1.除了这节课用到的Loss、Accuracy、ROC AUC、PR AUC这四个指标你在TensorFlow的实践中还会经常用到哪些评估指标呢 你能把这些常用指标以及它们特点分享出来吗你可以参考TensorFlow的官方Metrics文档

2.你认为DeepFM评估结果这么差的原因除了过拟合还有什么更深层次的原因呢可以尝试从模型结构的原理上给出一些解释吗

期待在留言区看到你对DeepFM模型的思考和使用评估指标的经验我们下节课见