如何为 Sagemaker 编写 Tensorflow KMeans Estimator 脚本

How to write Tensorflow KMeans Estimator script for Sagemaker

我正在尝试将 Tensorflows tf.contrib.factorization.KMeansClustering 估算器与 SageMaker 一起使用,但遇到了一些问题。我的 SageMaker predictor.predict() 调用的输出看起来不正确。聚类值太大,因为它们应该是 0-7 之间的整数。 (我将簇数设置为 8)。

我在每个 运行 上得到类似的输出(其中数组的后半部分是 4L 或其他一些数字,如 0L)。数组中有 40 个值,因为那是多少行(我将用户及其评分传递给 predict() 函数)

示例: {'outputs': {u'output': {'int64_val': [6L, 0L, 6L, 1L, 2L, 4L, 5L, 7L, 7L, 7L, 7L, 5L, 0L, 1L, 7L, 3L, 3L, 6L, 7L, 3L, 7L, 2L, 6L, 2L, 3L, 7L, 6L, 3L, 3L, 6L, 1L, 2L, 1L, 3L, 7L, 7L, 7L, 3L, 5L, 7L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L, 4L], 'dtype': 9, 'tensor_shape': {'dim': [{'size': 100L}]}}}, 'model_spec': {'signature_name': u'serving_default', 'version': {'value': 1534392971L}, 'name': u'generic_model'}}

我正在使用的数据是项目评级的稀疏矩阵,其中 rows=userscols=items 和单元格包含介于 0.0 和 10 之间的浮点数。所以我的输入数据是一个矩阵典型的特征数组。

我认为问题可能出在 serving_input_fn 函数中。这是我的 SageMaker entry_point 脚本:

def estimator_fn(run_config, params):
    #feature_columns = [tf.feature_column.numeric_column('inputs', shape=list(params['input_shape']))]
    return tf.contrib.factorization.KMeansClustering(num_clusters=NUM_CLUSTERS,
                            distance_metric=tf.contrib.factorization.KMeansClustering.COSINE_DISTANCE,
                            use_mini_batch=False,
                            feature_columns=None,
                            config=run_config)

def serving_input_fn(params):
    tensor = tf.placeholder(tf.float32, shape=[None, None])
    return tf.estimator.export.build_raw_serving_input_receiver_fn({'inputs': tensor})()

def train_input_fn(training_dir, params):
    """ Returns input function that would feed the model during training """
    return generate_input_fn(training_dir, 'train.csv')


def eval_input_fn(training_dir, params):
    """ Returns input function that would feed the model during evaluation """
    return generate_input_fn(training_dir, 'test.csv')


def generate_input_fn(training_dir, training_filename):
    """ Generate all the input data needed to train and evaluate the model. """
    # Load train/test data from s3 bucket
    train = np.loadtxt(os.path.join(training_dir, training_filename), delimiter=",")
    return tf.estimator.inputs.numpy_input_fn(
        x={'inputs': np.array(train, dtype=np.float32)},
        y=None,
        num_epochs=1,
        shuffle=False)()

generate_input_fn()中,train是numpy评分矩阵。

如果有帮助,这是我对 predict() 函数的调用,(ratings_matrix 是一个 40 x num_items numpy 数组):

mtx = tf.make_tensor_proto(values=ratings_matrix,
                           shape=list(ratings_matrix.shape), dtype=tf.float32)
result = predictor.predict(mtx)

我觉得这个问题很简单,我错过了。这是我编写的第一个机器学习算法,如有任何帮助,我们将不胜感激。

您的问题 - 当然还有输入数据集 - 似乎更适合 Alternating Least Squares / Non-Negative Matrix Factorization:这些正确地针对提供给定 user/[=13= 的建议] 矩阵作为输入。

看来 Sagemaker 目前可能没有这一系列算法 - 但他们确实有 `Factorization Machines https://docs.aws.amazon.com/sagemaker/latest/dg/fact-machines.html - 这是推荐系统的类似方法。

这是亚马逊关于如何设置的博客:https://aws.amazon.com/blogs/machine-learning/build-a-movie-recommender-with-factorization-machines-on-amazon-sagemaker/:其中的一些要点是:

该博客展示了如何将 SageMaker Factorization MachinesMovieLens 输入数据集一起使用:您可以找到一个类比,您的 user 是他们的 user 而你的 item 是他们的 movie:

您需要将数据写入 protobuf 个文件,如下所示:

然后您将在他们的 API 上调用 fit() 方法,并可以查看结果,包括结果输出上的 F1 分数。

感谢 javadba 的回答!

我对机器学习或TensorFlow不是很了解,所以请指正。但是,您似乎能够与 SageMaker 集成,但预测结果并非您所期望的那样。

最终,SageMaker 运行 将您的 EstimatorSpec with train_and_evaluate 用于训练并使用 TensorFlow Serving 进行预测。它没有任何其他隐藏功能,因此您使用 TensorFlow 估算器从 KMeans 预测中获得的结果将独立于 SageMaker。但是,它可能会受到您如何定义 serving_input_fn 和 output_fn 的影响。

当您 运行 使用相同设置在 SageMaker 生态系统之外使用相同的估算器时,您是否会以您期望的格式获得预测?

SageMaker TensorFlow 体验在此处开源,展示了目前的可能性和可能性。 https://github.com/aws/sagemaker-tensorflow-container