我尝试使用Tensorflow的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=users
,cols=items
,单元格包含0.0到10.0之间的浮点数。因此,我的输入数据是一个矩阵,而不是典型的特征数组。
我认为问题可能出在serving_input_fn
函数中。这是我的SageMaker入口点脚本:
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)
我觉得问题可能是我遗漏了什么简单的部分。这是我的第一个机器学习算法,所以任何帮助都将不胜感激。
回答:
感谢javadba的回答!
我对机器学习或TensorFlow的了解并不多,所以请指正我。不过,看起来你已经成功地与SageMaker集成了,但预测结果并不是你期望的。
最终,SageMaker使用EstimatorSpec运行你的训练脚本,并使用train_and_evaluate进行训练,并使用TensorFlow Serving进行预测。它没有其他隐藏的功能,因此你使用TensorFlow估计器得到的KMeans预测结果将独立于SageMaker。不过,它可能会受到你如何定义serving_input_fn
和output_fn
的影响。
当你在SageMaker生态系统之外使用相同的设置运行此估计器时,你是否得到了你期望的格式的预测结果?
SageMaker TensorFlow的体验在这里开源,展示了目前可能和不可能实现的功能。https://github.com/aws/sagemaker-tensorflow-container