迁移到 YDF¶
YDF 和 TensorFlow Decision Forests (TF-DF) 都是同一高性能 C++ 实现的决策森林算法的前端。两个库均由同一团队开发,并使用相同的训练代码,这意味着使用任一库训练的模型将是相同的。
YDF 是 TF-DF 的继任者,并且在功能上显著更丰富、更高效且更易于使用。
一览好处¶
YDF | TensorFlow Decision Forests | |
---|---|---|
模型描述 | model.describe() 生成丰富的模型描述 HTML 或文本报告。 |
model.summary() 生成较不完整的文本报告,但在从磁盘加载的模型上无法使用。 |
模型评估 | model.evaluate(ds) 评估模型并返回丰富的模型评估报告。指标也可以通过编程访问。 |
每个评估指标需要手动配置和运行, 使用 model.compile() 和 model.evaluate() 。没有评估报告。没有置信区间。没有用于排名和提升模型的指标。 |
模型分析 | model.analyze(ds) 生成丰富的模型分析 HTML 报告。 |
不可用 |
模型基准测试 | model.benchmark(ds) 测量并报告模型推理速度。 |
不可用 |
自定义损失 | 可用于训练梯度提升树。 | 不可用 |
交叉验证 | learner.cross_validation(ds) 执行交叉验证并返回丰富的模型评估报告。 |
不可用 |
Python 模型服务 | model.predict(ds) 进行预测。 |
model.predict(ds) 有时有效。但是,由于TensorFlow SavedModel 格式的限制,从 磁盘加载的模型可能需要签名工程。 |
其他模型服务 | 模型可直接在 C++、Python、CLI、Go 和 JavaScript 中使用。您还可以 使用工具生成服务代码:例如,调用 model.to_cpp() 生成 C++ 服务代码。模型可以使用 model.to_tensorflow_saved_model(path) 导出为 TensorFlowSavedModel。 |
调用 model.save(path, signature) 生成 TensorFlowSaveModel,并使用 TensorFlow C++ API 在 C++ 中运行模型。 或者,将模型导出到 YDF。 |
训练速度 | 在小型数据集上,训练速度比 TensorFlow Decision Forests 快 高达 5 倍。对于所有数据集大小,模型推理速度比 TensorFlow Decision Forests 快高达 1000 倍。 |
在小型数据集上,大部分时间花费在 TensorFlow 数据集读取上。 |
库大小 | YDF 库小于 10MB。 | TF-DF 库小,但需要大约 600MB 的 TensorFlow。 |
错误信息 | 简短、高级且可操作的错误信息。 | 错误信息冗长且难以理解,通常与 Tensor 形状有关。 |
我必须迁移吗?¶
TensorFlow Decision Forests 将继续获得支持,用户不需要迁移他们的管道! 如果 TF-DF 和 Keras 对您来说很好用,可以继续使用 TF-DF。我们的团队将继续发布新版本,并通过我们的各种支持渠道支持用户。
有关更多信息,请查看 FAQ。
大纲¶
本指南分为三个部分:
- 迁移您的 TF-DF 训练、推理和评估管道。
- 导入和导出现有的 TF-DF 模型。
- 高级主题:检查、构建、调优和分布式训练。
本指南不涵盖 YDF 的每个配置细节。请参阅 https://ydf.readthedocs.org 获取完整文档。
!pip install ydf
import ydf
import pandas as pd
import numpy as np
# 检查软件包的版本
print("Found YDF v" + ydf.__version__)
迁移训练管道¶
本节将介绍YDF中的简单训练/评估管道。
模型训练¶
YDF 和 TF-DF 具有相同的超参数和相同的默认值,因此大多数训练管道可以轻松迁移。
更改摘要¶
下面的比较展示了两个训练管道的差异。
TF-DF | YDF |
---|---|
# 安装 TF-DF
!pip install tensorflow tensorflow_decision_forests
import tensorflow_decision_forests as tfdf
import tensorflow as tf
import pandas as pd
# 使用 Pandas 加载数据集
train_df = pd.read_csv("train.csv")
test_df = pd.read_csv("test.csv")
# 将数据集转换为 TensorFlow 数据集。
train_ds = tfdf.keras.pd_dataframe_to_tf_dataset(train_df, label="my_label")
test_ds = tfdf.keras.pd_dataframe_to_tf_dataset(test_df, label="my_label")
# 训练模型
model = tfdf.keras.RandomForestModel(num_trees=500)
model.fit(train_ds)
# 评估模型。
model.compile([tf.keras.metrics.SparseCategoricalAccuracy(),tf.keras.metrics.AUC()])
model.evaluate(test_ds)
# 保存模型
model.save("project/model")
|
# 安装 YDF
pip install ydf
import ydf
import pandas as pd
# 使用 Pandas 加载数据集
train_ds = pd.read_csv("train.csv")
test_ds = pd.read_csv("test.csv")
# 训练模型
model = ydf.RandomForestLearner(label="my_label", num_trees=500).train(train_ds)
# 评估模型(例如 ROC、准确率、混淆矩阵、置信区间)
model.evaluate(test_ds)
# 保存模型
model.save("/tmp/my_model")
|
YDF | TF-DF | |
---|---|---|
数据集支持 | Pandas DataFrame, tf.Data.Dataset, Numpy 数组, CSV 文件 | Tensorflow 数据集, 通过 tfdf.keras.pd_dataframe_to_tf_dataset() 的 DataFrame |
模型训练 | ydf.RandomForestLearner(label=label).train(train_ds_pd) |
model = tfdf.keras.RandomForestModel() model.fit(train_ds) |
输出详细程度 | 全局设置 ydf.verbose(2) |
每个模型的设置 verbose=2 在模型构造函数中。 |
模型编译 | 不必要 | model.compile() 需要额外的指标。 |
超参数 | 在学习器上设置。与 TF-DF 中的名称和默认值相同。 | 在模型上设置。 |
标签列 | 学习器上的参数 label= |
输入数据集的第二个“通道” |
示例权重 | 学习器上的参数 weights= |
输入数据集的第三个“通道” |
模型任务 | 学习器上的参数 task=ydf.Task.REGRESSION |
模型上的参数 task=tfdf.keras.Task.REGRESSION |
接下来,我们在一个实际示例中运行 YDF 训练代码。
ds_path = "https://raw.githubusercontent.com/google/yggdrasil-decision-forests/main/yggdrasil_decision_forests/test_data/dataset"
# 下载并加载数据集为Pandas数据框
train_ds = pd.read_csv(f"{ds_path}/adult_train.csv")
test_ds = pd.read_csv(f"{ds_path}/adult_test.csv")
# 标签列的名称。
label = "income"
# 显示扩展日志。
ydf.verbose(2)
# 使用简单的超参数训练一个随机森林模型
model = ydf.RandomForestLearner(label=label, num_trees=50).train(train_ds)
# 使用模型进行预测
predictions = model.predict(test_ds)
# 显示模型摘要
model.describe()
模型训练 - 重要事项¶
- YDF不会自动对字符串列进行分词以用于列类型CATEGORICAL_SET。如果要使用此列类型,用户需要提供自己的分词方法。
- TF-DF通常将分类列转换为整数,而YDF则不会。因此,由TF-DF和YDF训练的模型可能会有所不同,即使在相同数据集上使用相同的超参数进行训练。
模型评估、分析与存储¶
YDF 提供了更高级的模型评估和分析功能。
更改总结¶
YDF | TF-DF | |
---|---|---|
评估 | model.evaluate() 显示丰富的图表和许多指标 |
model.evaluate() 显示较少的指标,没有图表 |
自我评估 | model.self_evaluation() |
model.make_inspector().evaluation() |
模型格式 | YDF 格式。可以导出为 SavedModel | TensorFlow SavedModel |
模型加载 | ydf.load_model() |
tf_keras.models.load_model() |
加载的模型是等价的 | 加载的模型仅用于推断 | |
变量重要性 | model.variable_importances() |
model.make_inspector().variable_importances() |
模型分析 | model.analyze(test_ds) |
不可用 |
使用 TF Serving | 使用 model.to_tensorflow_saved_model() 可用 |
默认可用 |
模型检查器 | 不需要(功能在模型上) | 许多任务需要 |
模型评估与自我评估¶
可以在测试数据集上对模型进行评估。
作为一个快速、低质量的替代方案,YDF模型也提供自我评估。 自我评估的具体逻辑取决于模型。例如,随机森林将使用袋外评估,而梯度提升树将使用内部训练-验证。
# 在Colab中,这会打印出一个丰富的评估对象。
model.evaluate(test_ds)
# 自我评估虽有其益处,但往往质量不及基于测试数据的评估。
model.self_evaluation()
保存和加载¶
模型可以保存为YDF格式,以便后续重复使用。有关与TF Serving和TensorFlow生态系统其他部分的兼容性,请参见下面的导出到TF Serving部分。
model.save("/tmp/my_ydf_model")
如果你重新加载模型,它在功能上与原始模型是等效的。
model_reloaded = ydf.load_model("/tmp/my_ydf_model")
model_reloaded.describe()
从 / 导出到 TensorFlow¶
YDF 模型可以导出到 TensorFlow,例如用于 TF-Serving。有关导出到 TensorFlow 的更详细教程,请参见 TF Serving 教程。
# 导出功能需要安装 TensorFlow Decision Forests。
# !pip 安装 tensorflow_决策_森林
model.to_tensorflow_saved_model("/tmp/my_tensorflow_saved_model")
TF-DF模型可以导入到YDF中。导入的模型通常与原始模型等价,并应返回相同的预测结果。主要的区别在于,导入模型中的分类列必须作为字符串而不是整数提供。
请注意,只有包含单个决策森林(例如随机森林或梯度提升树)的TF-DF模型才能导出为YDF。模型图的其他部分(例如神经网络)不能被导入。
# 导入TF-DF模型。请提供包含saved_model.pb文件的顶级目录。
model_from_tfdf = ydf.from_tensorflow_decision_forests("/tmp/my_tensorflow_saved_model")
model_from_tfdf.describe()
模型分析¶
YDF可以在测试数据集上计算详细的模型分析报告,包括更高级的变量重要性。
# 创建一份详尽的分析报告
model.analyze(test_ds)
模型检查器和构建器¶
YDF 为用户提供了比 TF-DF 更强大的检查和修改模型的方法。这些方法现在直接位于模型上,速度比 TF-DF 中暴露的方法快得多。TF-DF 中的 inspector
和 builder
组件不再必要。
# 绘制一棵树
model.print_tree(tree_idx=0)
# 结构变量重要性可通过编程方式获取。
model.variable_importances()
# 直接访问一棵树
tree = model.get_tree(tree_idx=0)
tree
# 修改树并将其添加到模型中
if isinstance(tree.root.condition, ydf.tree.CategoricalIsInCondition):
tree.root.condition.mask = [1]
if isinstance(tree.root.condition, ydf.tree.NumericalHigherThanCondition):
tree.root.condition.threshold = 18.22
print(tree)
model.add_tree(tree)
model.print_tree(tree_idx=model_1.num_trees()-1)
超参数调整¶
使用 YDF 进行超参数调整与使用 TF-DF 非常相似。只需将 tfdf.tuner.RandomSearch()
更改为 ydf.RandomSearchTuner()
,并将其结果作为学习者的参数。YDF 随后会使用相同的参数运行相同的调整算法。
Keras Tuner 不支持 YDF。
# 减少冗长以避免过长的日志记录
ydf.verbose(1)
# 定义带有某些选项的调谐器。
tuner = ydf.RandomSearchTuner(num_trials=20)
tuner.choice("shrinkage", [0.2, 0.1, 0.05])
tuner.choice("subsample", [1.0, 0.9, 0.8])
tuner.choice("max_depth", [3, 4,5, 6])
# 使用调优器训练模型
model_tuned = ydf.GradientBoostedTreesLearner(
label="income",
num_trees=100, # 用于所有试验。
tuner=tuner,
).train(train_ds)
# See the "Tuning" tab in the description for details.
model_tuned.describe()
分布式训练 / 调优¶
YDF中的分布式训练要求将数据集作为一个文件路径序列,以便各个工作节点打开。有关详细信息,请查看YDF分布式训练教程。YDF不支持来自有限TensorFlow分布式数据集的分布式训练。
结束语¶
谷歌决策森林团队希望将从TF-DF到YDF的迁移变得尽可能简单。如果您有任何问题、建议、问题或成功故事,请通过decision-forests-contact@google.com与我们联系。