如何为Keras Estimator添加特征列名称以匹配输入特征名
解决Keras转Estimator时输入特征名不匹配的问题
你的问题根源很明确:用input_dim=3创建的Sequential模型会生成一个隐式的单输入层,它的名称是TensorFlow自动分配的(比如dense_4_input),但你的输入函数传入的是三个独立的特征键,两者完全不匹配,所以才会抛出找不到输入名的错误。
下面给你两种可行的解决方案,你可以根据需求选择:
方案一:修改输入函数,适配现有单输入模型
如果不想改动原有Keras模型的结构,只需要把三个特征合并成一个和模型输入形状匹配的数组,再用模型输入层的名称作为键传入即可:
- 先确认模型输入层的名称:
print(model.input_names) # 输出类似 ['dense_4_input']
- 修改输入函数,合并特征并使用正确的输入名:
import numpy as np def input_function(features, labels=None, shuffle=False): # 将三个特征合并为形状为(样本数, 3)的输入数组 combined_features = np.column_stack([ features['dept_tenure'], features['prior_tenure'], features['employ_tenure'] ]) input_fn = tf.estimator.inputs.numpy_input_fn( x={"dense_4_input": combined_features}, # 这里用模型输入层的实际名称 y=labels, shuffle=shuffle ) return input_fn() # 注意要调用函数返回数据集,而非返回函数本身!
方案二:重构Keras模型为多输入结构(推荐用于服务场景)
如果希望模型直接对应三个命名特征,方便后续服务时发送带特征名的JSON请求,建议用Keras函数式API重构为多输入模型:
# 定义三个命名输入层,每个对应一个特征 dept_tenure_input = keras.layers.Input(shape=(1,), name='dept_tenure') prior_tenure_input = keras.layers.Input(shape=(1,), name='prior_tenure') employ_tenure_input = keras.layers.Input(shape=(1,), name='employ_tenure') # 合并三个输入为一个向量,供后续层使用 concatenated_input = keras.layers.concatenate([ dept_tenure_input, prior_tenure_input, employ_tenure_input ]) # 原有网络层逻辑保持不变 dense_layer = keras.layers.Dense(300)(concatenated_input) prelu_layer = keras.layers.PReLU()(dense_layer) dropout_layer = keras.layers.Dropout(0.5)(prelu_layer) output_layer = keras.layers.Dense(2, activation='softmax')(dropout_layer) # 创建多输入模型 model = keras.models.Model( inputs=[dept_tenure_input, prior_tenure_input, employ_tenure_input], outputs=output_layer ) # 编译模型(和原来的编译逻辑一致) model.compile(optimizer='Adam', loss='categorical_crossentropy', metrics=['accuracy'])
转成Estimator后,你的原有输入函数只需要补全调用即可直接使用:
estimator_model = keras.estimator.model_to_estimator(keras_model=model) def input_function(features, labels=None, shuffle=False): input_fn = tf.estimator.inputs.numpy_input_fn( x={"dept_tenure": features['dept_tenure'], "prior_tenure": features['prior_tenure'], "employ_tenure": features['employ_tenure']}, y=labels, shuffle=shuffle ) return input_fn() # 必须调用函数返回数据集
这种方案下,后续服务模型时,你可以直接发送包含三个特征名的JSON请求,完全符合你的需求。
内容的提问来源于stack exchange,提问作者user1753640
相关产品推荐
相关产品推荐

