{ "cells": [ { "cell_type": "markdown", "metadata": { "id": "headers" }, "source": [ "Project: /overview/_project.yaml\n", "Book: /overview/_book.yaml\n", "\n", "\n", "\n", "\n", "\n", "\n", "{% comment %}\n", "The source of truth file can be found [here]: http://google3/zz\n", "{% endcomment %}" ] }, { "cell_type": "markdown", "metadata": { "id": "metadata" }, "source": [ "
tf.feature_column
迁移到 Keras 预处理层\" />\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"\n",
"tf.feature_column
迁移到 Keras 预处理层\n",
"\n",
"在 TensorFlow.org 上查看 | \n", "在 Google Colab 中运行 | \n", "在 GitHub 上查看源代码 | \n", "下载笔记本 | \n", "
tf.estimator.Estimator
时,通常使用 tf.feature_column
API 执行特征预处理。在 TensorFlow 2 中,您可以直接使用 Keras 预处理层执行此操作。\n",
"\n",
"本迁移指南演示了使用特征列和预处理层的常见特征转换,然后使用这两种 API 训练一个完整的模型。\n",
"\n",
"首先,从几个必要的导入开始:"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {
"execution": {
"iopub.execute_input": "2023-11-07T19:43:44.488225Z",
"iopub.status.busy": "2023-11-07T19:43:44.487957Z",
"iopub.status.idle": "2023-11-07T19:43:46.951876Z",
"shell.execute_reply": "2023-11-07T19:43:46.950933Z"
},
"id": "iE0vSfMXumKI"
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"2023-11-07 19:43:44.933552: E external/local_xla/xla/stream_executor/cuda/cuda_dnn.cc:9261] Unable to register cuDNN factory: Attempting to register factory for plugin cuDNN when one has already been registered\n",
"2023-11-07 19:43:44.933604: E external/local_xla/xla/stream_executor/cuda/cuda_fft.cc:607] Unable to register cuFFT factory: Attempting to register factory for plugin cuFFT when one has already been registered\n",
"2023-11-07 19:43:44.935149: E external/local_xla/xla/stream_executor/cuda/cuda_blas.cc:1515] Unable to register cuBLAS factory: Attempting to register factory for plugin cuBLAS when one has already been registered\n"
]
}
],
"source": [
"import tensorflow as tf\n",
"import tensorflow.compat.v1 as tf1\n",
"import math"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "NVPYTQAWtDwH"
},
"source": [
"接下来,添加一个用于调用特征列的效用函数进行演示:"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {
"execution": {
"iopub.execute_input": "2023-11-07T19:43:46.956277Z",
"iopub.status.busy": "2023-11-07T19:43:46.955788Z",
"iopub.status.idle": "2023-11-07T19:43:46.960098Z",
"shell.execute_reply": "2023-11-07T19:43:46.959459Z"
},
"id": "LAaifuuytJjM"
},
"outputs": [],
"source": [
"def call_feature_columns(feature_columns, inputs):\n",
" # This is a convenient way to call a `feature_column` outside of an estimator\n",
" # to display its output.\n",
" feature_layer = tf1.keras.layers.DenseFeatures(feature_columns)\n",
" return feature_layer(inputs)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "ZJnw07hYDGYt"
},
"source": [
"## 输入处理\n",
"\n",
"要将特征列与 Estimator 一起使用,模型输入始终应为张量的字典:"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {
"execution": {
"iopub.execute_input": "2023-11-07T19:43:46.963340Z",
"iopub.status.busy": "2023-11-07T19:43:46.963101Z",
"iopub.status.idle": "2023-11-07T19:43:49.173611Z",
"shell.execute_reply": "2023-11-07T19:43:49.172520Z"
},
"id": "y0WUpQxsKEzf"
},
"outputs": [],
"source": [
"input_dict = {\n",
" 'foo': tf.constant([1]),\n",
" 'bar': tf.constant([0]),\n",
" 'baz': tf.constant([-1])\n",
"}"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "xYsC6H_BJ8l3"
},
"source": [
"每个特征列都需要有一个键来索引到源数据。所有特征列的输出串联并由 Estimator 模型使用。"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {
"execution": {
"iopub.execute_input": "2023-11-07T19:43:49.177309Z",
"iopub.status.busy": "2023-11-07T19:43:49.176984Z",
"iopub.status.idle": "2023-11-07T19:43:49.226898Z",
"shell.execute_reply": "2023-11-07T19:43:49.226201Z"
},
"id": "3fvIe3V8Ffjt"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"WARNING:tensorflow:From /tmpfs/tmp/ipykernel_211312/3124623333.py:2: numeric_column (from tensorflow.python.feature_column.feature_column_v2) is deprecated and will be removed in a future version.\n",
"Instructions for updating:\n",
"Use Keras preprocessing layers instead, either directly or via the `tf.keras.utils.FeatureSpace` utility. Each of `tf.feature_column.*` has a functional equivalent in `tf.keras.layers` for feature preprocessing when training a Keras model.\n"
]
},
{
"data": {
"text/plain": [
"tf.keras.Model
可以处理单个张量输入、张量特征列表或张量特征字典。可以通过在模型创建时传递 tf.keras.Input
的字典来处理字典输入。输入不会自动串联,这样它们便能以更灵活的方式使用。它们可以与 tf.keras.layers.Concatenate
串联。"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {
"execution": {
"iopub.execute_input": "2023-11-07T19:43:49.230760Z",
"iopub.status.busy": "2023-11-07T19:43:49.230155Z",
"iopub.status.idle": "2023-11-07T19:43:49.269590Z",
"shell.execute_reply": "2023-11-07T19:43:49.268870Z"
},
"id": "5sYWENkgLWJ2"
},
"outputs": [
{
"data": {
"text/plain": [
"tf.keras.layers.CategoryEncoding
层,其中 `output_mode` 设置为 `'one_hot'`:"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {
"execution": {
"iopub.execute_input": "2023-11-07T19:43:49.323593Z",
"iopub.status.busy": "2023-11-07T19:43:49.323336Z",
"iopub.status.idle": "2023-11-07T19:43:49.693947Z",
"shell.execute_reply": "2023-11-07T19:43:49.693017Z"
},
"id": "799lbMNNuAVz"
},
"outputs": [
{
"data": {
"text/plain": [
"tf.sparse.SparseTensor
,它可以作为 tf.keras.layers.Dense
层的输入高效地处理。"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "Zf7kjhTiAErK"
},
"source": [
"## 归一化数字特征\n",
"\n",
"在处理具有特征列的连续浮点特征时,需要使用 tf.feature_column.numeric_column
。在输入已经归一化的情况下,将其转换为 Keras 的操作十分简单。可以直接在模型中使用 tf.keras.Input
,如上面所示。\n",
"\n",
"`numeric_column` 也可用于归一化输入:"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {
"execution": {
"iopub.execute_input": "2023-11-07T19:43:49.697756Z",
"iopub.status.busy": "2023-11-07T19:43:49.697497Z",
"iopub.status.idle": "2023-11-07T19:43:49.710960Z",
"shell.execute_reply": "2023-11-07T19:43:49.710312Z"
},
"id": "HbTMGB9XctGx"
},
"outputs": [
{
"data": {
"text/plain": [
"tf.keras.layers.Normalization
完成。"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {
"execution": {
"iopub.execute_input": "2023-11-07T19:43:49.714266Z",
"iopub.status.busy": "2023-11-07T19:43:49.714009Z",
"iopub.status.idle": "2023-11-07T19:43:50.179201Z",
"shell.execute_reply": "2023-11-07T19:43:50.178434Z"
},
"id": "8bcgG-yOdqUH"
},
"outputs": [
{
"data": {
"text/plain": [
"tf.feature_column.bucketized_column
实现:"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {
"execution": {
"iopub.execute_input": "2023-11-07T19:43:50.183042Z",
"iopub.status.busy": "2023-11-07T19:43:50.182721Z",
"iopub.status.idle": "2023-11-07T19:43:50.196160Z",
"shell.execute_reply": "2023-11-07T19:43:50.195481Z"
},
"id": "_rbx6qQ-LQx7"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"WARNING:tensorflow:From /tmpfs/tmp/ipykernel_211312/3043215186.py:2: bucketized_column (from tensorflow.python.feature_column.feature_column_v2) is deprecated and will be removed in a future version.\n",
"Instructions for updating:\n",
"Use Keras preprocessing layers instead, either directly or via the `tf.keras.utils.FeatureSpace` utility. Each of `tf.feature_column.*` has a functional equivalent in `tf.keras.layers` for feature preprocessing when training a Keras model.\n"
]
},
{
"data": {
"text/plain": [
"tf.keras.layers.Discretization
代替:"
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {
"execution": {
"iopub.execute_input": "2023-11-07T19:43:50.199459Z",
"iopub.status.busy": "2023-11-07T19:43:50.199203Z",
"iopub.status.idle": "2023-11-07T19:43:50.908696Z",
"shell.execute_reply": "2023-11-07T19:43:50.907914Z"
},
"id": "QK1WOG2uVVsL"
},
"outputs": [
{
"data": {
"text/plain": [
"tf.keras.layers.StringLookup
层,并将 `output_mode` 设置为 `'one_hot'`:"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {
"execution": {
"iopub.execute_input": "2023-11-07T19:43:50.939033Z",
"iopub.status.busy": "2023-11-07T19:43:50.938789Z",
"iopub.status.idle": "2023-11-07T19:43:50.958554Z",
"shell.execute_reply": "2023-11-07T19:43:50.957926Z"
},
"id": "arnPlSrWvDMe"
},
"outputs": [
{
"data": {
"text/plain": [
"tf.sparse.SparseTensor
,它可以作为 tf.keras.layers.Dense
层的输入高效地处理。"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "c1CmfSXQZHE5"
},
"source": [
"## 使用词汇表嵌入字符串数据\n",
"\n",
"对于较大的词汇表,通常需要嵌入向量才能获得良好的性能。下面是一个使用特征列嵌入字符串特征的示例:"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {
"execution": {
"iopub.execute_input": "2023-11-07T19:43:50.961689Z",
"iopub.status.busy": "2023-11-07T19:43:50.961446Z",
"iopub.status.idle": "2023-11-07T19:43:51.153732Z",
"shell.execute_reply": "2023-11-07T19:43:51.152948Z"
},
"id": "C3RK4HFazxlU"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"WARNING:tensorflow:From /tmpfs/tmp/ipykernel_211312/999372599.py:5: embedding_column (from tensorflow.python.feature_column.feature_column_v2) is deprecated and will be removed in a future version.\n",
"Instructions for updating:\n",
"Use Keras preprocessing layers instead, either directly or via the `tf.keras.utils.FeatureSpace` utility. Each of `tf.feature_column.*` has a functional equivalent in `tf.keras.layers` for feature preprocessing when training a Keras model.\n"
]
},
{
"data": {
"text/plain": [
"tf.keras.layers.StringLookup
层和 tf.keras.layers.Embedding
层来实现。`StringLookup` 的默认输出将是可直接馈送到嵌入向量中的整数索引。\n",
"\n",
"注:`Embedding` 层包含可训练参数。虽然 `StringLookup` 层可以应用于模型内部或外部的数据,但 `Embedding` 必须始终是可训练 Keras 模型的一部分才能正确训练。"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {
"execution": {
"iopub.execute_input": "2023-11-07T19:43:51.157419Z",
"iopub.status.busy": "2023-11-07T19:43:51.157137Z",
"iopub.status.idle": "2023-11-07T19:43:51.179454Z",
"shell.execute_reply": "2023-11-07T19:43:51.178816Z"
},
"id": "8resGZPo0Fho"
},
"outputs": [
{
"data": {
"text/plain": [
"tf.feature_column.weighted_categorical_column
处理。与 `indicator_column` 配对时,效果是对每个类别的权重求和。"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {
"execution": {
"iopub.execute_input": "2023-11-07T19:43:51.182687Z",
"iopub.status.busy": "2023-11-07T19:43:51.182425Z",
"iopub.status.idle": "2023-11-07T19:43:51.254991Z",
"shell.execute_reply": "2023-11-07T19:43:51.254318Z"
},
"id": "02HqjPLMRxWn"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"WARNING:tensorflow:From /tmpfs/tmp/ipykernel_211312/3529191023.py:6: weighted_categorical_column (from tensorflow.python.feature_column.feature_column_v2) is deprecated and will be removed in a future version.\n",
"Instructions for updating:\n",
"Use Keras preprocessing layers instead, either directly or via the `tf.keras.utils.FeatureSpace` utility. Each of `tf.feature_column.*` has a functional equivalent in `tf.keras.layers` for feature preprocessing when training a Keras model.\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.9/site-packages/tensorflow/python/feature_column/feature_column_v2.py:4033: sparse_merge (from tensorflow.python.ops.sparse_ops) is deprecated and will be removed in a future version.\n",
"Instructions for updating:\n",
"No similar op available at this time.\n"
]
},
{
"data": {
"text/plain": [
"tf.keras.layers.CategoryEncoding
来完成,其中 `output_mode='count'`。"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {
"execution": {
"iopub.execute_input": "2023-11-07T19:43:51.258635Z",
"iopub.status.busy": "2023-11-07T19:43:51.258386Z",
"iopub.status.idle": "2023-11-07T19:43:51.275021Z",
"shell.execute_reply": "2023-11-07T19:43:51.274365Z"
},
"id": "JsoYUUgRS7hu"
},
"outputs": [
{
"data": {
"text/plain": [
"tf.keras.layers.Embedding
没有 `combiner` 选项,但可以使用 tf.keras.layers.Dense
实现相同的效果。上面的 `embedding_column` 只是根据类别权重线性组合嵌入向量。虽然一开始并不明显,但它完全等效于将您的分类输入表示为大小为 `(num_tokens)` 的稀疏权重向量,随后将它们乘以形状为 `(embedding_size, num_tokens)` 的 `Dense` 内核 。"
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {
"execution": {
"iopub.execute_input": "2023-11-07T19:43:51.323712Z",
"iopub.status.busy": "2023-11-07T19:43:51.323430Z",
"iopub.status.idle": "2023-11-07T19:43:51.350437Z",
"shell.execute_reply": "2023-11-07T19:43:51.349807Z"
},
"id": "Y-vZvPyiYilE"
},
"outputs": [
{
"data": {
"text/plain": [
"tf.data
输入流水线内使用,或者直接构建到可训练的 Keras 模型中。\n",
"\n",
"在此示例中,您将在 tf.data
输入流水线中应用预处理层。为此,可以定义一个单独的 tf.keras.Model
来预处理您的输入特征。此模型不可训练,但可以方便地对预处理层进行分组。"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {
"execution": {
"iopub.execute_input": "2023-11-07T19:43:55.496235Z",
"iopub.status.busy": "2023-11-07T19:43:55.495501Z",
"iopub.status.idle": "2023-11-07T19:43:55.543941Z",
"shell.execute_reply": "2023-11-07T19:43:55.543028Z"
},
"id": "NMz8RfMQdCZf"
},
"outputs": [],
"source": [
"inputs = {\n",
" 'type': tf.keras.Input(shape=(), dtype='int64'),\n",
" 'size': tf.keras.Input(shape=(), dtype='string'),\n",
" 'weight': tf.keras.Input(shape=(), dtype='float32'),\n",
"}\n",
"# Convert index to one-hot; e.g. [2] -> [0,0,1].\n",
"type_output = tf.keras.layers.CategoryEncoding(\n",
" one_hot_dims, output_mode='one_hot')(inputs['type'])\n",
"# Convert size strings to indices; e.g. ['small'] -> [1].\n",
"size_output = tf.keras.layers.StringLookup(vocabulary=vocab)(inputs['size'])\n",
"# Normalize the numeric inputs; e.g. [2.0] -> [0.0].\n",
"weight_output = tf.keras.layers.Normalization(\n",
" axis=None, mean=weight_mean, variance=weight_variance)(inputs['weight'])\n",
"outputs = {\n",
" 'type': type_output,\n",
" 'size': size_output,\n",
" 'weight': weight_output,\n",
"}\n",
"preprocessing_model = tf.keras.Model(inputs, outputs)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "NRfISnj3NGlW"
},
"source": [
"注:作为在层创建时提供词汇表和归一化统计信息的替代方式,许多预处理层提供了一个 `adapt()` 方法,可用于直接从输入数据学习层状态。请参阅[预处理指南](https://tensorflow.google.cn/guide/keras/preprocessing_layers#the_adapt_method) ,了解更多详细信息。\n",
"\n",
"您现在可以在对 tf.data.Dataset.map
的调用中应用此模型。请注意,传递给 `map` 的函数将自动转换为 tf.function
,并且用于编写 tf.function
代码的通常注意事项适用(无副作用)。"
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {
"execution": {
"iopub.execute_input": "2023-11-07T19:43:55.548069Z",
"iopub.status.busy": "2023-11-07T19:43:55.547366Z",
"iopub.status.idle": "2023-11-07T19:43:55.648758Z",
"shell.execute_reply": "2023-11-07T19:43:55.648013Z"
},
"id": "c_6xAUnbNREh"
},
"outputs": [
{
"data": {
"text/plain": [
"({'type': array([[1., 0., 0.]], dtype=float32),\n",
" 'size': array([1]),\n",
" 'weight': array([0.70000005], dtype=float32)},\n",
" array([1], dtype=int32))"
]
},
"execution_count": 26,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"# Apply the preprocessing in tf.data.Dataset.map.\n",
"dataset = tf.data.Dataset.from_tensor_slices((features, labels)).batch(1)\n",
"dataset = dataset.map(lambda x, y: (preprocessing_model(x), y),\n",
" num_parallel_calls=tf.data.AUTOTUNE)\n",
"# Display a preprocessed input sample.\n",
"next(dataset.take(1).as_numpy_iterator())"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "8_4u3J4NdJ8R"
},
"source": [
"接下来,可以定义一个包含可训练层的单独 `Model`。请注意此模型的输入现在如何反映预处理的特征类型和形状。"
]
},
{
"cell_type": "code",
"execution_count": 27,
"metadata": {
"execution": {
"iopub.execute_input": "2023-11-07T19:43:55.652246Z",
"iopub.status.busy": "2023-11-07T19:43:55.651959Z",
"iopub.status.idle": "2023-11-07T19:43:55.691611Z",
"shell.execute_reply": "2023-11-07T19:43:55.690902Z"
},
"id": "kC9OZO5ldmP-"
},
"outputs": [],
"source": [
"inputs = {\n",
" 'type': tf.keras.Input(shape=(one_hot_dims,), dtype='float32'),\n",
" 'size': tf.keras.Input(shape=(), dtype='int64'),\n",
" 'weight': tf.keras.Input(shape=(), dtype='float32'),\n",
"}\n",
"# Since the embedding is trainable, it needs to be part of the training model.\n",
"embedding = tf.keras.layers.Embedding(len(vocab), embedding_dims)\n",
"outputs = tf.keras.layers.Concatenate()([\n",
" inputs['type'],\n",
" embedding(inputs['size']),\n",
" tf.expand_dims(inputs['weight'], -1),\n",
"])\n",
"outputs = tf.keras.layers.Dense(1)(outputs)\n",
"training_model = tf.keras.Model(inputs, outputs)"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "ir-cn2H_d5R7"
},
"source": [
"您现在可以使用 tf.keras.Model.fit
训练 `training_model`。"
]
},
{
"cell_type": "code",
"execution_count": 28,
"metadata": {
"execution": {
"iopub.execute_input": "2023-11-07T19:43:55.695560Z",
"iopub.status.busy": "2023-11-07T19:43:55.694912Z",
"iopub.status.idle": "2023-11-07T19:43:56.898967Z",
"shell.execute_reply": "2023-11-07T19:43:56.898209Z"
},
"id": "6TS3YJ2vnvlW"
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"3/3 [==============================] - 1s 5ms/step - loss: 0.5726\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"WARNING: All log messages before absl::InitializeLog() is called are written to STDERR\n",
"I0000 00:00:1699386236.696100 211480 device_compiler.h:186] Compiled cluster using XLA! This line is logged at most once for the lifetime of the process.\n"
]
},
{
"data": {
"text/plain": [
"tf.data
异步应用它们。这样做可以获得性能优势,因为您既可以预提取预处理的批次,又可以释放任何加速器以专注于模型的可微分部分(请在使用 tf.data
API 提升性能指南的预提取部分了解更多信息)。如本指南中所示,在训练期间分离预处理并在推断期间组合预处理是一种利用这些性能提升的灵活方式。但是,如果您的模型很小或预处理时间可以忽略不计,那么从一开始就将预处理构建为一个完整的模型可能会更简单。为此,您可以从 tf.keras.Input
开始构建单一模型,接着是预处理层,最后是可训练层。"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "2pjp7Z18gRCQ"
},
"source": [
"## 特征列对应关系表\n",
"\n",
"作为参考,下面是特征列和 Keras 预处理层之间的大致对应关系:\n",
"\n",
"tf.keras.layers.CategoryEncoding
、tf.keras.layers.StringLookup
、tf.keras.layers.IntegerLookup
和 tf.keras.layers.TextVectorization
。\n",
"\n",
"† tf.keras.layers.TextVectorization
可以直接处理自由格式的文本输入(例如,整个句子或段落)。这不是 TensorFlow 1 中分类序列处理的一对一替代,但可以为临时文本预处理提供方便的替代。\n",
"\n",
"注:线性 Estimator(例如 tf.estimator.LinearClassifier
)可以在没有 `embedding_column` 或 `indicator_column` 的情况下处理直接分类输入(整数索引)。但是,整数索引不能直接传递给 tf.keras.layers.Dense
或 tf.keras.experimental.LinearModel
。在调用 `Dense` 或 `LinearModel` 之前,应当首先使用 `tf.layers.CategoryEncoding` 对这些输入进行编码,其中 `output_mode='count'`(如果类别大小很大,则为 `sparse=True`)。"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "AQCJ6lM3YDq_"
},
"source": [
"## 后续步骤\n",
"\n",
"- 有关 Keras 预处理层的更多信息,请转到[使用预处理层](https://tensorflow.google.cn/guide/keras/preprocessing_layers)指南。\n",
"- 有关将预处理层应用于结构化数据的更深入示例,请参阅[使用 Keras 预处理层对结构化数据进行分类](../../tutorials/structured_data/preprocessing_layers.ipynb)教程。"
]
}
],
"metadata": {
"colab": {
"collapsed_sections": [],
"name": "migrating_feature_columns.ipynb",
"toc_visible": true
},
"kernelspec": {
"display_name": "Python 3",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.9.18"
}
},
"nbformat": 4,
"nbformat_minor": 0
}