成功训练后,脚本模式py3和s3中没有输出

时间:2019-01-20 23:04:53

标签: amazon-web-services tensorflow amazon-sagemaker

我创建了一个脚本,在其中定义了Tensorflow Estimator,然后将其传递给AWS sagemaker sdk并运行fit(),训练通过了(尽管未在控制台中显示与训练有关的任何内容),并且在S3中输出是/source/sourcedir.tar.gz,我相信至少也应该存在/model/model.tar.gz,由于某种原因,该模型不会生成,并且我没有收到任何错误。

sagemaker_session = sagemaker.Session()
role = get_execution_role()
inputs = sagemaker_session.upload_data(path='data', key_prefix='data/NamingConventions')
NamingConventions_estimator = TensorFlow(entry_point='NamingConventions.py',
                               role=role,
                               framework_version='1.12.0',
                               train_instance_count=1,
                               train_instance_type='ml.m5.xlarge',
                               py_version='py3',
                               model_dir="s3://sagemaker-eu-west-2-218566301064/model")
NamingConventions_estimator.fit(inputs, run_tensorboard_locally=True)

和我来自'NamingConventions.py'的model_fn

def model_fn(features, labels, mode, params):
    net = keras.layers.Embedding(alphabetLen + 1, 8, input_length=maxFeatureLen)(features[INPUT_TENSOR_NAME])
    net = keras.layers.LSTM(12)(net)

    logits = keras.layers.Dense(len(conventions), activation=tf.nn.softmax)(net) #output
    predictions = tf.reshape(logits, [-1])

    if mode == tf.estimator.ModeKeys.PREDICT:
        return tf.estimator.EstimatorSpec(
            mode=mode,
            predictions={"ages": predictions},
            export_outputs={SIGNATURE_NAME: PredictOutput({"ages": predictions})})

    loss = keras.losses.sparse_categorical_crossentropy(labels, predictions)

    train_op = tf.contrib.layers.optimize_loss(
        loss=loss,
        global_step=tf.contrib.framework.get_global_step(),
        learning_rate=params["learning_rate"],
        optimizer="AdamOptimizer")

    predictions_dict = {"ages": predictions}

    eval_metric_ops = {
        "rmse": tf.metrics.root_mean_squared_error(
            tf.cast(labels, tf.float32), predictions)
    }

    return tf.estimator.EstimatorSpec(
        mode=mode,
        loss=loss,
        train_op=train_op,
        eval_metric_ops=eval_metric_ops)

我仍然无法运行它,我正在尝试使用脚本模式,看来我无法从同一目录导入模型。 当前我的脚本:

import argparse
import os

if __name__ =='__main__':

    parser = argparse.ArgumentParser()

    # hyperparameters sent by the client are passed as command-line arguments to the script.
    parser.add_argument('--epochs', type=int, default=10)
    parser.add_argument('--batch_size', type=int, default=100)
    parser.add_argument('--learning_rate', type=float, default=0.1)

    # input data and model directories
    parser.add_argument('--model_dir', type=str)
    parser.add_argument('--train', type=str, default=os.environ.get('SM_CHANNEL_TRAIN'))
    parser.add_argument('--test', type=str, default=os.environ.get('SM_CHANNEL_TEST'))

    args, _ = parser.parse_known_args()

import tensorflow as tf
from NC_model import model_fn, train_input_fn, eval_input_fn

def train(args):
    print(args)
    estimator = tf.estimator.Estimator(model_fn=model_fn, model_dir=args.model_dir)
    train_spec = tf.estimator.TrainSpec(train_input_fn, max_steps=1000)
    eval_spec = tf.estimator.EvalSpec(eval_input_fn)
    tf.estimator.train_and_evaluate(estimator, train_spec, eval_spec)

if __name__ == '__main__':
    train(args)

3 个答案:

答案 0 :(得分:0)

AWS控制台中列出的培训工作是否成功?您是否在Amazon CloudWatch中检查了培训日志?

答案 1 :(得分:0)

我认为您需要将估算器model_dir设置为环境变量SM_MODEL_DIR中的路径。

这与目前尚不清楚的文档有些相反。我怀疑--model_dir arg用于分布式训练,而不是保存最终工件。

请注意,您将获得所有检查点和摘要,因此最好在估计器中使用--model_dir,并在训练结束后将模型导出复制到SM_MODEL_DIR。

答案 2 :(得分:0)

脚本模式使您可以自由地编写所需的TensorFlow脚本,但代价是,您必须自己完成几乎所有事情。例如,在这种情况下,如果要在S3中使用model.tar.gz,则必须先在本地导出模型。然后SageMaker将您的本地模型自动上传到S3。

因此,您需要在脚本中添加的内容是:

  1. 您需要添加一个导出器并将其传递给eval_spec。
  2. 您需要调用export_savedmodel将模型保存到SageMaker可以获取的本地模型目录中。本地模型目录位于env变量SM_MODEL_DIR中,并且应为'/ opt / ml / model'。
  3. 要完成上述操作,我想您也需要实现serve_input_fn。

然后,SageMaker会将您的模型从本地模型目录自动上传到您指定的S3模型目录。您可以在作业成功后的S3中看到它。