我在我的模型中使用张量流估计器,它适用于训练和评估部分(下面给出的代码片段)。虽然结果显示的准确率为 93%,但查准率和查全率均为 0,这是不可能的。训练结果和测试结果都是如此。
我想从模型中获得预测并自己计算性能指标。除此之外,我还想保存训练后的模型(任何类型的格式都适合我)。下面是我正在使用的代码的一小部分。
labeled_features
是用于模型的主要数据集,train_spec
和 eval_spec
只是主数据集的一部分。
请假设
hidden_units
和 dropout_rate
等变量具有与模型/数据集相关的值,这些值运行良好,因为如果为每个变量提供示例代码,那么帖子就太大了。
import tensorflow as tf
wide_columns = []
wide_columns += [tf.feature_column.categorical_column_with_hash_bucket(
key = 'user_id', hash_bucket_size = 1000, dtype = tf.dtypes.int64)]
wide_columns += [tf.feature_column.categorical_column_with_hash_bucket(
key = 'product_id', hash_bucket_size = 100, dtype = tf.dtypes.int64)]
wide_columns += [tf.feature_column.crossed_column(
['user_id', 'product_id'], hash_bucket_size = 1000)]
deep_columns = []
cat_keys = {}
for col in cat_features:
cat_keys[col] = (labeled_features.selectExpr('{0} as key'.format(col)).distinct().orderBy('key')
.groupBy().agg(f.collect_list('key').alias('keys')).collect()[0]['keys'])
# categorical features
for col in cat_features:
if col not in ['user_id', 'product_id']:
col_def = tf.feature_column.categorical_column_with_identity(
key=col, num_buckets=np.max(cat_keys[col]) + 1)
deep_columns += [tf.feature_column.embedding_column(
col_def, dimension=int(np.max(cat_keys[col]) ** 0.25))]
# continuous features
for col in num_features:
deep_columns += [tf.feature_column.numeric_column(col)]
model = tf.estimator.DNNLinearCombinedClassifier(
linear_feature_columns = wide_columns,
linear_optimizer = tf.keras.optimizers.legacy.Ftrl(),
dnn_feature_columns = deep_columns,
dnn_hidden_units = hidden_units,
dnn_dropout = dropout_rate,
dnn_optimizer = tf.keras.optimizers.legacy.Adagrad()
)
train_results = tf.estimator.train_and_evaluate(model, train_spec, eval_spec)
batch_size = 128
steps = int(test.count() / batch_size)
test_results = model.evaluate(test_spec, steps = steps)
为了从模型中获取预测,我尝试了以下代码,该代码不断运行,直到我自己停止执行。
predictions = model.predict(get_input_fn(test))
predictions_df = spark.createDataFrame(predictions)
为了保存模型,我尝试了几种语法 - 但没有一个有效。以下是我所做的两次尝试(我注意到这是最常用的)以及我收到的相应错误。
尝试1:
model_path = "path/to/model"
feature_columns = wide_columns + deep_columns
serving_input_fn = tf.estimator.export.build_parsing_serving_input_receiver_fn(
tf.feature_column.make_parse_example_spec(feature_columns))
export_path = model.export_saved_model(model_path, serving_input_fn)
ValueError:feature_columns 包含关键 user_id 的不同 parse_spec。给定 VarLenFeature(dtype=tf.string) 和 VarLenFeature(dtype=tf.int64)
尝试2:
model_path = "path/to/model"
checkpoint = tf.train.Checkpoint(model = model)
checkpoint.save(model_path)
tf.saved_model.save(model, model_path)
ValueError:
期望模型是一个可跟踪的对象(从Checkpoint
派生的对象),得到了Trackable
。如果您认为该对象应该是可跟踪的(即它是 TensorFlow Python API 的一部分并管理状态),请提出问题。
您的问题有 3 个部分:1- 性能指标(精度/召回率为 0)2- 在处理大型数据集时,直接使用 model.predict 可能效率低下。我们将使用批处理方法来有效地处理这个问题 3- tf.estimator 模型与 tf.saved_model.save 不兼容,因为它们使用不同的保存机制。我们将使用适当的方法导出您的模型
修复#1:确保标签格式正确并在预测后计算指标。
修复#2:
import pandas as pd
def predict_with_batches(model, input_fn):
results = []
for pred in model.predict(input_fn):
results.append(pred)
return pd.DataFrame(results)
def test_input_fn():
return tf.data.Dataset.from_tensor_slices(test_features).batch(128)
predictions_df = predict_with_batches(model, test_input_fn)
修复模型保存方式
feature_spec = tf.feature_column.make_parse_example_spec(wide_columns + deep_columns)
serving_input_fn = tf.estimator.export.build_parsing_serving_input_receiver_fn(feature_spec)
model_path = "path/to/saved_model"
export_path = model.export_saved_model(model_path, serving_input_fn)
print(f"Model saved to: {export_path}")