tf.feature_column 已被弃用,因专为TF1.x的Estimator设计,不兼容TF2.x的Eager模式、SavedModel导出和@tf.function;应改用Normalization、StringLookup等Keras预处理层。

TensorFlow 的 tf.feature_column 已在 TensorFlow 2.x 中**被明确弃用**,官方推荐迁移到 tf.keras.layers.StringLookup、tf.keras.layers.CategoryEncoding、tf.keras.layers.Normalization 等 Keras 预处理层,或直接使用 tf.data + 自定义函数。硬套旧版 feature_column 在 TF 2.16+ 会报 AttributeError: module 'tensorflow' has no attribute 'feature_column' 或触发弃用警告。
为什么 tf.feature_column 不再适用
它原本是为 Estimator API(如 tf.estimator.DNNClassifier)设计的,依赖静态图和 input_fn 模式。TF 2.x 默认启用 Eager Execution,Estimator 已进入维护模式,且 feature_column 无法参与 SavedModel 导出、无法与 @tf.function 兼容,更难调试。
- TF 2.9 起标记为“deprecated”,2.15+ 默认禁用(需显式启用
tf.compat.v1) - 所有
tf.feature_column.*(如tf.feature_column.categorical_column_with_vocabulary_list)在纯 TF 2.x 环境下不可直接导入 - 即使强制启用
v1兼容模式,也无法与tf.keras.Model原生协同
替代方案:用 tf.keras.layers 做等效特征工程
核心思路是把特征变换封装成可训练/不可训练的 Keras 层,直接嵌入模型输入端。以下是最常见三类操作的等价写法:
-
数值归一化:用
tf.keras.layers.Normalization替代numeric_column
需先调用adapt()统计均值/方差(类似fit()) -
类别编码:用
tf.keras.layers.StringLookup+tf.keras.layers.CategoryEncoding替代categorical_column_with_vocabulary_listStringLookup将字符串映射为整数 ID,CategoryEncoding转为 one-hot 或 multi-hot -
分桶(bucketization):用
tf.keras.layers.Discretization替代bucketized_column
支持自动分位数分桶(num_bins=5+adaptive=True)或指定边界
示例(数值 + 类别联合预处理):
立即学习“Python免费学习笔记(深入)”;
import tensorflow as tf
<h1>构造示例数据</h1><p>features = {
'age': tf.constant([25, 42, 37, 51]),
'city': tf.constant(['NYC', 'LA', 'SF', 'NYC'])
}</p><h1>数值归一化层</h1><p>norm_layer = tf.keras.layers.Normalization(axis=-1)
norm_layer.adapt(tf.constant([[25.], [42.], [37.], [51.]])) # 必须 adapt!</p><h1>类别编码层</h1><p>lookup = tf.keras.layers.StringLookup(vocabulary=['NYC', 'LA', 'SF'], num_oov_indices=1)
encoding = tf.keras.layers.CategoryEncoding(num_tokens=4, output_mode='one_hot')</p><h1>执行转换</h1><p>age_norm = norm_layer(features['age'])
city_ids = lookup(features['city'])
city_onehot = encoding(city_ids)</p><p>print(age_norm) # shape=(4, 1), 已标准化
print(city_onehot) # shape=(4, 4), NYC→[1,0,0,0] 等
迁移时最容易踩的坑
旧代码直接复制粘贴 feature_column 会彻底失败,必须同步改输入管道和模型结构:
-
tf.keras.Model的inputs必须是tf.keras.Input,不能传原始 dict —— 需先用预处理层统一输出张量 -
StringLookup的vocabulary必须显式提供(不能像旧版categorical_column_with_hash_bucket那样动态哈希),缺失值需靠num_oov_indices处理 - 如果原用
weighted_categorical_column,Keras 层无直接对应,得手动实现加权 embedding(用tf.gather+ 权重向量) -
tf.data.Dataset流水线中,预处理层必须放在map()内或作为tf.keras.Sequential子模型调用,不能在外部 Python 函数里调用(否则无法 trace)
真正麻烦的不是语法替换,而是旧项目里混用 feature_column + Estimator + 自定义 input_fn 的耦合逻辑——这类代码需要整体重构成 tf.data + Keras 预处理层 + Model.fit() 流程,中间状态(如 vocabulary 文件)得重新导出加载。


















