TensorFlow Extended | Trainer Not Warm Starting With GenericExecutor & Keras Model

我目前正在尝试让TFX管道的Trainer组件从之前的相同管道运行中进行热启动。用例是:

  1. 运行管道一次,生成一个模型。
  2. 随着新数据的到来,使用新数据训练现有模型。

我知道ResolverNode组件是为此目的设计的,所以你可以看到我如何使用它如下:

# 检测先前训练的模型
latest_model_resolver = ResolverNode(
  instance_name='latest_model_resolver',
  resolver_class=latest_artifacts_resolver.LatestArtifactsResolver,
  latest_model=Channel(type=Model))
context.run(latest_model_resolver)
# 将先前模型设置为base_model
train_file = 'tfx_modules/recommender_train.py'
trainer = Trainer(
    module_file=os.path.abspath(train_file),
    custom_executor_spec=executor_spec.ExecutorClassSpec(GenericExecutor),
    transformed_examples=transform.outputs['transformed_examples'],
    transform_graph=transform.outputs['transform_graph'],
    schema=schema_gen.outputs['schema'],
    train_args=trainer_pb2.TrainArgs(num_steps=10000),
    eval_args=trainer_pb2.EvalArgs(num_steps=5000),
    base_model=latest_model_resolver.outputs['latest_model'])

上述组件运行成功,并且ResolverNode能够检测到之前管道运行的最新模型。没有抛出错误 – 但是,当运行context.run(trainer)时,模型损失基本上从第一次开始的地方开始。在模型的第一次运行后,它的训练损失大约为0.1,但在第二次运行(假设是热启动)时,它重新开始大约为18.2。

这让我认为所有的权重都被重新初始化了,我认为这不应该发生。以下是相关模型构建函数:

def build_keras_model():
    """构建Keras模型"""
    embedding_max_values = load(open(os.path.abspath('tfx-example/user_artifacts/embedding_max_dict.pkl'), 'rb'))
    embedding_dimensions = dict([(key, 20) for key in embedding_max_values.keys()])
    embedding_pairs = [recommender.EmbeddingPair(embedding_name=feature,
                                                 embedding_dimension=embedding_dimensions[feature],
                                                 embedding_max_val=embedding_max_values[feature])
                       for feature in recommender_constants.univalent_features]
    numeric_inputs = []
    for num_feature in recommender_constants.numeric_features:
        numeric_inputs.append(keras.Input(shape=(1,), name=num_feature))
    input_layers = numeric_inputs + [elem for pair in embedding_pairs for elem in pair.input_layers]
    pre_concat_layers = numeric_inputs + [elem for pair in embedding_pairs for elem in pair.embedding_layers]
    concat = keras.layers.Concatenate()(pre_concat_layers) if len(pre_concat_layers) > 1 else pre_concat_layers[0]
    layer_1 = keras.layers.Dense(64, activation='relu', name='layer1')(concat)
    output = keras.layers.Dense(1, kernel_initializer='lecun_uniform', name='out')(layer_1)
    model = keras.models.Model(input_layers, outputs=output)
    model.compile(optimizer='adam', loss='mean_squared_error')
    return model
def run_fn(fn_args: TrainerFnArgs):
    """Trainer组件的函数"""
    tf_transform_output = tft.TFTransformOutput(fn_args.transform_output)
    train_dataset = _input_fn(fn_args.train_files, fn_args.data_accessor,
                              tf_transform_output, 40)
    eval_dataset = _input_fn(fn_args.eval_files, fn_args.data_accessor,
                             tf_transform_output, 40)
    model = build_keras_model()
    tensorboard_callback = tf.keras.callbacks.TensorBoard(
        log_dir=fn_args.model_run_dir, update_freq='epoch', histogram_freq=1,
        write_images=True)
    model.fit(train_dataset, steps_per_epoch=fn_args.train_steps, validation_data=eval_dataset,
              validation_steps=fn_args.eval_steps, callbacks=[tensorboard_callback],
              epochs=5)
    signatures = {
        'serving_default':
            _get_serve_tf_examples_fn(model, tf_transform_output).get_concrete_function(tf.TensorSpec(
                    shape=[None],
                    dtype=tf.string,
                    name='examples')
            )
    }
    model.save(fn_args.serving_model_dir, save_format='tf', signatures=signatures)

为了研究这个问题,我查看了以下内容:

来自TFX的热启动示例https://github.com/tensorflow/tfx/blob/master/tfx/examples/chicago_taxi_pipeline/taxi_pipeline_warmstart.py

然而,这个指南使用的是Estimator组件而不是Keras组件。该组件有一个warm_start_from初始化参数,我在Keras的等效组件中找不到这个参数。

我怀疑:

  1. 热启动功能仅适用于Estimator组件,即使为Keras组件设置了base_model,也不会生效。

  2. 我不知何故告诉模型在成功加载之前模型后重新初始化权重 – 如果是这样,我希望能指出这是如何发生的。

任何帮助都将不胜感激!非常感谢。


回答:

对于Keras模型,你必须首先使用基本模型路径加载模型,然后你可以从那里继续训练,而不是构建一个新模型。

你的Trainer组件看起来是正确的,但在run_fn中,应该这样做:

def run_fn(fn_args: FnArgs):
  model = tf.keras.models.load_model(fn_args.base_model)
  model.fit(train_dataset, steps_per_epoch=fn_args.train_steps, validation_data=eval_dataset,
              validation_steps=fn_args.eval_steps, callbacks=[tensorboard_callback],
              epochs=5)

Related Posts

使用LSTM在Python中预测未来值

这段代码可以预测指定股票的当前日期之前的值,但不能预测…

如何在gensim的word2vec模型中查找双词组的相似性

我有一个word2vec模型,假设我使用的是googl…

dask_xgboost.predict 可以工作但无法显示 – 数据必须是一维的

我试图使用 XGBoost 创建模型。 看起来我成功地…

ML Tuning – Cross Validation in Spark

我在https://spark.apache.org/…

如何在React JS中使用fetch从REST API获取预测

我正在开发一个应用程序,其中Flask REST AP…

如何分析ML.NET中多类分类预测得分数组?

我在ML.NET中创建了一个多类分类项目。该项目可以对…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注