Path: blob/master/site/zh-cn/tfx/tutorials/transform/census.ipynb
25118 views
Copyright 2020 The TensorFlow Authors.
使用 TensorFlow Transform 预处理数据
TensorFlow Extended (TFX) 的特征工程组件
此示例 Colab 笔记本提供了一个更高级的示例,说明了如何使用 TensorFlow Transform (tf.Transform
) 预处理数据,此示例使用完全相同的代码训练模型和在生产环境中应用推断。
TensorFlow Transform 是一个用于预处理 TensorFlow 输入数据的库,包括创建需要在训练数据集上进行完整传递的特征。利用 TensorFlow Transform,您可以:
使用平均值和标准差归一化输入值
通过在所有输入值上生成词汇将字符串转换为整数
根据观测到的数据分布,通过分配给桶将浮点数转换为整数
TensorFlow 内置了对在单个样本或一批样本上进行操作的支持。tf.Transform
扩展了这些功能,支持在整个训练数据集上进行完整传递。
tf.Transform
的输出将导出为可用于训练和应用的 TensorFlow 计算图。将同一个计算图用于训练和应用可以避免偏差,因为会在两个阶段应用相同的转换。
要点:要了解 tf.Transform
以及它如何与 Apache Beam 配合使用,您需要对 Apache Beam 有所了解。最好是从Beam 编程指南开始着手。
##我们在此示例中执行的操作
在此示例中,我们将处理包含人口普查数据的广泛使用的数据集,并训练模型进行分类。在这个过程中,我们将使用 tf.Transform
转换数据。
要点:作为模型创建者和开发者,思考如何使用这些数据以及模型预测的潜在好处和危害。此类模型可能会加剧社会偏见和差距。某个特征与您要解决的问题相关,还是会引入偏差?有关更多信息,请阅读 ML 公平性。
注:TensorFlow Model Analysis 是了解模型对数据各个部分的预测能力的强大工具,包括了解模型如何加剧社会偏见和差距。
安装 TensorFlow Transform
导入和全局
首先导入我们需要的东西。
接下来下载数据文件:
为列命名
我们将创建一些方便的列表来引用数据集中的列。
以下是数据的快速预览:
测试数据有 1 个需要跳过的标题行,在每一行的结尾还有一个尾随“.”。
###定义特征和架构
我们根据输入中列的类型来定义一个架构。这将有助于正确导入它们,也将惠及其他操作。
[可选] 编码和解码 tf.train.Example 原型
本教程需要在几个地方将数据集中的示例与 tf.train.Example
原型相互转换。
下面隐藏的 encode_example
函数将数据集中的特征字典转换为 tf.train.Example
。
现在,您可以将数据集示例转换为 Example
原型:
您还可以将成批的序列化 Example 原型转换回张量字典:
在某些情况下不会传入标签,所以我们编写了 encode 函数,以便标签可选:
创建 Example
原型时,它根本不包含标签键。
###设置超参数和基本内务管理
用于训练的常量和超参数。
##使用 tf.Transform
进行预处理
###创建一个 tf.Transform
preprocessing_fn
预处理函数是 tf.Transform 最重要的概念。预处理函数是真正发生数据集转换的地方。它接受并返回一个张量字典,其中张量是指 Tensor
或 SparseTensor
。有两组主要的 API 调用,它们通常构成预处理函数的核心:
TensorFlow 运算:接受并返回张量的任何函数,通常是指 TensorFlow 运算。这些函数会将 TensorFlow 运算添加到计算图中,计算图能够以每次一个特征向量的方式转换原始数据。在训练和应用期间,将为每个样本运行这种转换。
TensorFlow Transform 分析器/映射器:tf.Transform 提供的任何分析器/映射器。它们也接受并返回张量,并且通常包含 TensorFlow 运算和 Beam 计算的组合,但与 TensorFlow 运算不同的是,它们仅在需要对整个训练数据集进行完整传递的分析期间在 Beam 流水线中运行。Beam 计算只运行一次(在训练之前,分析期间运行),且通常会对整个训练数据集进行一次完整传递。它们会创建
tf.constant
张量,并将其添加到您的计算图中。例如,tft.min
计算训练数据集上张量的最小值。
警告:将预处理函数用于应用推断时,分析器在训练过程中创建的常量不会更改。如果您的数据包含趋势或季节性分量,请相应地制定计划。
这是此数据集的 preprocessing_fn
。其用于执行几项操作:
使用
tft.scale_to_0_1
将数字特征缩放到[0,1]
范围。使用
tft.compute_and_apply_vocabulary
计算每个分类特征的词汇表,并将每个输入的整数 ID 作为tf.int64
返回。这适用于字符串和整数分类输入。使用标准 TensorFlow 运算对数据进行一些手动转换。在此处,这些运算应用于标签,但也可以转换特征。TensorFlow 运算实现几个目标:
为标签构建查找表(
tf.init_scope
确保仅在第一次调用函数时创建该表)。规范化标签的文本。
将标签转换为 one-hot。
语法
您几乎已准备好将所有内容放在一起并使用 Apache Beam 运行它。
Apache Beam 使用特殊的语法定义和调用转换。例如,在这一行中:
方法 to_this_call
正在被调用并传递给名为 pass_this
的对象,在堆栈跟踪中,此运算被称为 name this step
。调用 to_this_call
的结果将在 result
中返回。您经常会看到流水线的各个阶段像这样链接在一起:
由于这是从一个新的流水线开始的,因此您可以按以下方式继续:
转换数据
现在,我们准备开始在 Apache Beam 流水线中转换数据。
使用
tfxio.CsvTFXIO
CSV 读取器读入数据(要处理流水线中的文本行,请改用tfxio.BeamRecordCsvTFXIO
)。使用上面定义的
preprocessing_fn
分析和转换数据。将结果作为
Example
proto 的TFRecord
写出来,我们稍后会使用它来训练模型
运行流水线:
将输出目录封装为 tft.TFTransformOutput
:
如果您查看该目录,则会看到它包含三个内容:
train_transformed
和test_transformed
数据文件transform_fn
目录 (tf.saved_model
)transformed_metadata
以下部分显示如何使用这些工件来训练模型。
##使用预处理数据通过 tf.keras 训练模型
为了展示 tf.Transform
如何使我们能够将相同的代码用于训练和应用,进而避免偏差,我们将训练一个模型。要训练模型并为生产环境准备经过训练的模型,我们需要创建输入函数。训练输入函数与应用输入函数之间的主要区别在于,训练数据包含标签,而生产数据则不包含标签。两者的参数和返回值也有所不同。
###创建训练输入函数
运行上一部分中的流水线会创建 TFRecord
文件,其中包含转换后的数据。
以下代码使用 tf.data.experimental.make_batched_features_dataset
和 tft.TFTransformOutput.transformed_feature_spec
将这些数据文件读取为 tf.data.Dataset
:
您可以在下面看到转换后的数据示例。请注意,education-num
和 hourd-per-week
这样的数字列已转换为范围为 [0,1] 的浮点数,而字符串列已转换为 ID:
训练、评估模型
构建模型
构建数据集
训练并评估模型:
转换新数据
在上一部分中,训练过程使用了由 transform_dataset
函数中的 tft_beam.AnalyzeAndTransformDataset
生成的转换数据的硬拷贝。
要对新数据执行运算,您需要加载 tft_beam.WriteTransformFn
所保存的 preprocessing_fn
的最终版本。
TFTransformOutput.transform_features_layer
方法从输出目录加载 preprocessing_fn
SavedModel。
下面是从源文件加载未处理的新批次的函数:
加载 tft.TransformFeaturesLayer
以使用 preprocessing_fn
转换此数据:
tft_layer
足够聪明,如果只传入某些特征,它仍可以执行转换。例如,如果您仅传入两个特征,则只会得到这些特征的转换后版本:
下面的版本更加强大,它会删除不在特征规范中的特征,如果标签在提供的特征中,则返回 (features, label)
对:
现在,您可以使用 Dataset.map
将该转换即时应用于新数据:
导出模型
您目前拥有经过训练的模型,以及将 preprocessing_fn
应用于新数据的方法。将它们组装成一个新模型,该模型接受序列化的 tf.train.Example
proto 作为输入。
构建模型并在一批序列化示例上测试运行它:
将模型导出为 SavedModel:
重新加载模型,并在同一批示例上对其进行测试:
##我们所执行的操作。在本例中,我们使用 tf.Transform
预处理人口普查数据集,并使用经过清理和转换的数据来训练模型。我们还创建一个输入函数,当我们在生产环境中部署经过训练的模型以执行推断时可以使用该函数。通过对训练和推断使用相同的代码,我们避免了数据偏差的任何问题。在此过程中,我们了解了如何创建 Apache Beam 转换来执行清理数据所需的转换。我们还看到了如何使用这些转换后的数据通过 tf.keras
来训练模型。这只是 TensorFlow Transform 可以实现的一小部分!我们鼓励您深入研究 tf.Transform
并发现它可以为您做些什么。
[可选] 使用预处理数据通过 tf.estimator 来训练模型
警告:不建议将 Estimator 用于新代码。Estimator 运行 v1.Session 风格的代码,此类代码更加难以正确编写,并且可能会出现意外行为,尤其是与 TF 2 代码结合使用时。Estimator 确实在我们的兼容性保证范围内,但除了安全漏洞之外不会得到任何修复。请参阅迁移指南以了解详情。
###创建训练输入函数
###创建应用输入函数
我们创建一个可以在生产环境中使用的输入函数,并针对应用准备经过训练的模型。
###将输入数据封装到 FeatureColumns 中
模型希望我们的数据处于 TensorFlow FeatureColumns 中。
##训练、评估并导出模型
##总结
我们已经创建了所需的一切来预处理人口普查数据、训练模型并针对应用准备模型。到目前为止,我们已经做好了一切准备。是时候开始运行了!
注:滚动此单元的输出可查看整个流程。结果位于底部。