TensorFlow带Feature Column模型的model.predict()输入格式问题
基于TensorFlow Feature Column的Keras模型predict()正确输入格式
对于用Feature Column构建的Keras模型,model.predict()的唯一正确输入格式是与训练时结构完全一致的字典,以下是具体要求和排查要点:
核心要求
输入字典的键必须和你定义的Feature Column的特征名称完全匹配,每个键对应的值是符合该特征列数据类型的numpy数组(或TensorFlow张量),形状要和训练时的输入一致(比如单特征是(N,),N为样本数)。
常见错误原因及解决
你之前尝试的列表、DataFrame、错误字典都会报错,原因如下:
- 列表/数组:无法映射到Feature Column对应的特征名称,模型不知道每个元素对应哪个特征,直接拒绝。
- DataFrame直接传入:TensorFlow无法自动解析DataFrame的列到特征列,必须先转成字典格式,每个列对应字典的一个键值对。
- 字典格式错误:大概率是特征名称不匹配、数据类型和训练时不一致(比如训练用float32,预测传int)、分类特征的取值不在训练时的词汇表内,或者某个特征的形状不对(比如多了维度)。
正确操作步骤
- 对齐特征名称:确保预测数据的特征名和你定义Feature Column时用的名称完全一致,不能缺漏或多出来。
- 匹配数据类型与形状:
- 数值特征:转成numpy数组,类型和训练时保持一致(比如
np.float32),形状为(样本数,)或(样本数,1)(和训练输入一致即可)。 - 分类特征:如果用了
categorical_column_with_vocabulary_list这类列,预测时必须传入词汇表内的字符串,或者提前编码成对应整数(如果训练时用了indicator_column或embedding_column,模型会自动处理编码,但输入必须是合法取值)。
- 数值特征:转成numpy数组,类型和训练时保持一致(比如
- 包装成字典:把每个特征的数组按名称作为键值对包装成字典。
- 调用predict:直接传入这个字典即可。
示例代码
假设你的训练代码是这样的:
import tensorflow as tf import numpy as np import pandas as pd # 定义8个特征列(示例) feat_cols = [ tf.feature_column.numeric_column(f'num_feat{i}') for i in range(5) ] + [ tf.feature_column.embedding_column( tf.feature_column.categorical_column_with_vocabulary_list(f'cat_feat{i}', ['x','y','z']), dimension=4 ) for i in range(3) ] # 构建模型 model = tf.keras.Sequential([ tf.keras.layers.DenseFeatures(feat_cols), tf.keras.layers.Dense(32, activation='relu'), tf.keras.layers.Dense(1) ]) # (省略训练过程)
预测时的正确输入方式:
# 模拟无标签预测数据 predict_df = pd.DataFrame({ 'num_feat0': [1.1, 2.2, 3.3], 'num_feat1': [4.4, 5.5, 6.6], 'num_feat2': [7.7, 8.8, 9.9], 'num_feat3': [10.1, 11.2, 12.3], 'num_feat4': [13.4, 14.5, 15.6], 'cat_feat0': ['x', 'y', 'z'], 'cat_feat1': ['y', 'z', 'x'], 'cat_feat2': ['z', 'x', 'y'] }) # 转换成符合要求的字典 input_dict = { col: predict_df[col].values.astype(np.float32) if col.startswith('num') else predict_df[col].values for col in predict_df.columns } # 执行预测 predictions = model.predict(input_dict, verbose=0)
为什么model(input_data, training=False)能正常运行?
这个方式是直接调用模型的__call__方法,它接受的是模型输入层定义的张量格式(对于DenseFeatures层来说,就是字典格式的张量),对输入的格式检查没有predict()严格,只要张量结构匹配就能运行,但本质上和predict()要求的输入结构是一致的——只是你传入的input_data刚好符合了字典(或张量字典)的要求。
内容的提问来源于stack exchange,提问作者MVDVPRSD
相关产品推荐
相关产品推荐

