TensorFlow:导出 TensorForestEstimator 模型时出错

TensorFlow: Error exporting TensorForestEstimator model

我正在尝试在 Google Cloud 的机器学习引擎上托管 TensorForestEstimator 模型。一切正常,但最后模型无法导出堆栈跟踪:

Traceback (most recent call last):
[...]
File "/root/.local/lib/python2.7/site-packages/tensorflow/contrib/learn/python/learn/experiment.py", line 502, in train_and_evaluate
  export_results = self._maybe_export(eval_result)
File "/root/.local/lib/python2.7/site-packages/tensorflow/contrib/learn/python/learn/experiment.py", line 597, in _maybe_export
  eval_result=eval_result))
File "/root/.local/lib/python2.7/site-packages/tensorflow/contrib/learn/python/learn/export_strategy.py", line 87, in export
  return self.export_fn(estimator, export_path, **kwargs)
File "/root/.local/lib/python2.7/site-packages/tensorflow/contrib/learn/python/learn/utils/saved_model_export_utils.py", line 412, in export_fn
  checkpoint_path=checkpoint_path)
File "/root/.local/lib/python2.7/site-packages/tensorflow/contrib/learn/python/learn/estimators/estimator.py", line 1280, in export_savedmodel
  actual_default_output_alternative_key)
File "/root/.local/lib/python2.7/site-packages/tensorflow/contrib/learn/python/learn/utils/saved_model_export_utils.py", line 252, in build_all_signature_defs
  for input_key, inputs in input_alternatives.items()
File "/root/.local/lib/python2.7/site-packages/tensorflow/contrib/learn/python/learn/utils/saved_model_export_utils.py", line 254, in <dictcomp>
  in output_alternatives.items()}
File "/root/.local/lib/python2.7/site-packages/tensorflow/contrib/learn/python/learn/utils/saved_model_export_utils.py", line 119, in build_standardized_signature_def
  input_tensors, output_tensors)
File "/root/.local/lib/python2.7/site-packages/tensorflow/python/saved_model/signature_def_utils_impl.py", line 146, in predict_signature_def
  signature_constants.PREDICT_METHOD_NAME)
File "/root/.local/lib/python2.7/site-packages/tensorflow/python/saved_model/signature_def_utils_impl.py", line 45, in build_signature_def
  signature_def.outputs[item].CopyFrom(outputs[item])
TypeError: None has type NoneType, but expected one of: bytes, unicode

根据该跟踪,我认为错误出在带有 default_output_alternative_key=Nonemake_export_strategy 函数中。所以我所做的是设置 default_output_alternative_key='default' 但随后出现错误:

ValueError: Requested default_output_alternative: default, but available output_alternatives are: [None]

所以这表明没有输出选择,我的模型是单头的。这是代码:

def serving_input_fn():
    feature_placeholders = {
    column['name']: tf.placeholder(dtype=column['dtype'], shape=[None])
    for column in columns_list if column['derived'] == 'N' and column['column_role'] != 'label'
    }

    features = {
        key: tf.expand_dims(tensor, -1)
        for key, tensor in feature_placeholders.items()
    }

    return InputFnOps(
        features=features,
        labels=None,
        default_inputs=feature_placeholders
    )

def get_experiment_fn(args):
    def _experiment(run_config, hparams):
        return Experiment(
            estimator=TensorForestEstimator(
                params=ForestHParams(
                    num_trees=args.num_trees,
                    max_nodes=10000,
                    min_split_samples=2,
                    num_features=7,
                    num_classes=args.num_projections,
                    regression=True
                ),
                model_dir=args.job_dir,
                graph_builder_class=RandomForestGraphs,
                config=run_config,
                report_feature_importances=True,
            ),
            train_input_fn=get_input_fn(
                project_name=args.project,
                data_location=args.train_data,
                dataset_size=args.train_size,
                batch_size=args.train_batch_size
            ),
            train_steps=args.train_steps,
            eval_input_fn=get_input_fn(
                project_name=args.project,
                data_location=args.eval_data,
                dataset_size=args.eval_size,
                batch_size=args.eval_batch_size
            ),
            eval_steps=args.eval_steps,
            eval_metrics=get_eval_metrics(),
            export_strategies=[
                make_export_strategy(
                    serving_input_fn,
                    default_output_alternative_key=None,
                    exports_to_keep=1
                )
            ]
        )
    return _experiment


def main():
    args = get_arg_parser().parse_args()

    learn_runner.run(
        experiment_fn=get_experiment_fn(args),
        run_config=RunConfig(model_dir=args.job_dir),
        hparams=HParams(**args.__dict__)
    )

if __name__ == '__main__':
    main()

错误的原因是什么 None has type NoneType, but expected one of: bytes, unicode 以及如何解决它以便为我的模型提供服务?

这是一个已在 tensorflow 1.3 中修复的错误,因此我建议您尽可能升级到 1.3。升级后,您会发现这段代码可以正常运行。

简而言之,问题是 TensorForestEstimator 中的可选 keys_name 参数保留为 None,因此模型没有接收到头部。由于该模型甚至不是单头的,因此该图无法导出。