def test_continuous_train_and_eval_with_predicate_fn(self): for est in self._estimators_for_tests(eval_dict={'global_step': 100}): eval_metrics = 'eval_metrics' if not isinstance( est, core_estimator.Estimator) else None export_strategy = saved_model_export_utils.make_export_strategy( est, None if isinstance(est, core_estimator.Estimator) else 'export_input', exports_to_keep=None) ex = experiment.Experiment( est, train_input_fn='train_input', eval_input_fn='eval_input', eval_metrics=eval_metrics, train_steps=100000000000, # a value will make `ex` never stops. eval_steps=100, export_strategies=export_strategy) def predicate_fn(eval_result): del eval_result # unused. for fn signature. return False ex.continuous_train_and_eval(continuous_eval_predicate_fn=predicate_fn) self.assertEqual(0, est.fit_count) self.assertEqual(0, est.eval_count) self.assertEqual(0, est.export_count)
def _make_experiment_fn(output_dir): """Creates experiment for DNNBoostedTreeCombinedRegressor.""" (x_train, y_train), (x_test, y_test) = tf.keras.datasets.boston_housing.load_data() train_input_fn = tf.compat.v1.estimator.inputs.numpy_input_fn( x={"x": x_train}, y=y_train, batch_size=FLAGS.batch_size, num_epochs=None, shuffle=True) eval_input_fn = tf.compat.v1.estimator.inputs.numpy_input_fn( x={"x": x_test}, y=y_test, num_epochs=1, shuffle=False) feature_columns = [ feature_column.real_valued_column("x", dimension=_BOSTON_NUM_FEATURES) ] feature_spec = tf.contrib.layers.create_feature_spec_for_parsing( feature_columns) serving_input_fn = input_fn_utils.build_parsing_serving_input_fn( feature_spec) export_strategies = [ saved_model_export_utils.make_export_strategy(serving_input_fn) ] return tf.contrib.learn.Experiment(estimator=_get_estimator( output_dir, feature_columns), train_input_fn=train_input_fn, eval_input_fn=eval_input_fn, train_steps=None, eval_steps=FLAGS.num_eval_steps, eval_metrics=None, export_strategies=export_strategies)
def test_checkpoint_and_export(self): model_dir = tempfile.mkdtemp() config = run_config_lib.RunConfig(save_checkpoints_steps=3) est = dnn.DNNClassifier( n_classes=3, feature_columns=[ feature_column.real_valued_column('feature', dimension=4) ], hidden_units=[3, 3], model_dir=model_dir, config=config) exp_strategy = saved_model_export_utils.make_export_strategy( est, 'export_input', exports_to_keep=None) ex = experiment.Experiment( est, train_input_fn=test_data.iris_input_multiclass_fn, eval_input_fn=test_data.iris_input_multiclass_fn, export_strategies=(exp_strategy,), train_steps=8, checkpoint_and_export=True, eval_delay_secs=0) with test.mock.patch.object(ex, '_maybe_export'): with test.mock.patch.object(ex, '_call_evaluate'): ex.train_and_evaluate() # Eval and export are called after steps 1, 4, 7, and 8 (after training # is completed). self.assertEqual(ex._maybe_export.call_count, 4) self.assertEqual(ex._call_evaluate.call_count, 4)
def test_continuous_train_and_eval(self): for est in self._estimators_for_tests(eval_dict={'global_step': 100}): if isinstance(est, core_estimator.Estimator): eval_metrics = None saving_listeners = 'saving_listeners' else: eval_metrics = 'eval_metrics' saving_listeners = None noop_hook = _NoopHook() export_strategy = saved_model_export_utils.make_export_strategy( est, None if isinstance(est, core_estimator.Estimator) else 'export_input', exports_to_keep=None) ex = experiment.Experiment( est, train_input_fn='train_input', eval_input_fn='eval_input', eval_metrics=eval_metrics, eval_hooks=[noop_hook], train_steps=100, eval_steps=100, export_strategies=export_strategy, saving_listeners=saving_listeners) ex.continuous_train_and_eval() self.assertEqual(1, est.fit_count) self.assertEqual(1, est.eval_count) self.assertEqual(1, est.export_count) self.assertEqual([noop_hook], est.eval_hooks)
def test_train_and_evaluate(self): for est in self._estimators_for_tests(): eval_metrics = 'eval_metrics' if not isinstance( est, core_estimator.Estimator) else None noop_hook = _NoopHook() export_strategy = saved_model_export_utils.make_export_strategy( est, None if isinstance(est, core_estimator.Estimator) else 'export_input', exports_to_keep=None) ex = experiment.Experiment( est, train_input_fn='train_input', eval_input_fn='eval_input', eval_metrics=eval_metrics, eval_hooks=[noop_hook], train_steps=100, eval_steps=100, export_strategies=export_strategy) ex.train_and_evaluate() self.assertEqual(1, est.fit_count) self.assertEqual(1, est.eval_count) self.assertEqual(1, est.export_count) self.assertEqual(1, len(est.monitors)) self.assertEqual([noop_hook], est.eval_hooks) self.assertTrue(isinstance(est.monitors[0], session_run_hook.SessionRunHook))
def test_export_strategies_reset(self): for est in self._estimators_for_tests(): eval_metrics = 'eval_metrics' if not isinstance( est, core_estimator.Estimator) else None export_strategy_1 = saved_model_export_utils.make_export_strategy( est, None if isinstance(est, core_estimator.Estimator) else 'export_1', exports_to_keep=None) ex = experiment.Experiment( est, train_input_fn='train_input', eval_input_fn='eval_input', eval_metrics=eval_metrics, train_steps=100, eval_steps=100, export_strategies=(export_strategy_1,)) ex.train_and_evaluate() self.assertEqual(1, est.export_count) # After reset with empty list (None), the count does not change and the # user provided export strategy list should remain intact. old_es = ex.reset_export_strategies() ex.train_and_evaluate() self.assertAllEqual([export_strategy_1], old_es) self.assertEqual(1, est.export_count) # After reset with list, the count should increase with the number of # items. export_strategy_2 = saved_model_export_utils.make_export_strategy( est, None if isinstance(est, core_estimator.Estimator) else 'export_2', exports_to_keep=None) export_strategy_3 = saved_model_export_utils.make_export_strategy( est, None if isinstance(est, core_estimator.Estimator) else 'export_3', exports_to_keep=None) old_es = ex.reset_export_strategies( [export_strategy_2, export_strategy_3]) ex.train_and_evaluate() self.assertAllEqual([], old_es) self.assertEqual(3, est.export_count)
def test_default_output_alternative_key_core_estimator(self): est = TestCoreEstimator() export_strategy = saved_model_export_utils.make_export_strategy( est, default_output_alternative_key='export_key', exports_to_keep=None) ex = experiment.Experiment( est, train_input_fn='train_input', eval_input_fn='eval_input', train_steps=100, eval_steps=100, export_strategies=export_strategy) with self.assertRaisesRegexp( ValueError, 'default_output_alternative_key is not supported'): ex.train_and_evaluate()
def test_test(self): for est in self._estimators_for_tests(): exp_strategy = saved_model_export_utils.make_export_strategy( est, None if isinstance(est, core_estimator.Estimator) else 'export_input', exports_to_keep=None) if isinstance(est, core_estimator.Estimator): eval_metrics = None saving_listeners = 'saving_listeners' else: eval_metrics = 'eval_metrics' saving_listeners = None ex = experiment.Experiment( est, train_input_fn='train_input', eval_input_fn='eval_input', export_strategies=(exp_strategy,), eval_metrics=eval_metrics, saving_listeners=saving_listeners) ex.test() self.assertEqual(1, est.fit_count) self.assertEqual(1, est.eval_count) self.assertEqual(1, est.export_count)
def make_custom_export_strategy(name, convert_fn, feature_columns, export_input_fn, use_core_columns=False, feature_engineering_fn=None, default_output_alternative_key=None): """Makes custom exporter of GTFlow tree format. Args: name: A string, for the name of the export strategy. convert_fn: A function that converts the tree proto to desired format and saves it to the desired location. Can be None to skip conversion. feature_columns: A list of feature columns. export_input_fn: A function that takes no arguments and returns an `InputFnOps`. use_core_columns: A boolean, whether core feature columns were used. feature_engineering_fn: Feature eng function to be called on the input. default_output_alternative_key: the name of the head to serve when an incoming serving request does not explicitly request a specific head. Not needed for single-headed models. Returns: An `ExportStrategy`. """ base_strategy = saved_model_export_utils.make_export_strategy( serving_input_fn=export_input_fn, strip_default_attrs=True, default_output_alternative_key=default_output_alternative_key) input_fn = export_input_fn() features = input_fn.features if feature_engineering_fn is not None: features, _ = feature_engineering_fn(features, labels=None) (sorted_feature_names, dense_floats, sparse_float_indices, _, _, sparse_int_indices, _, _) = gbdt_batch.extract_features( features, feature_columns, use_core_columns) def export_fn(estimator, export_dir, checkpoint_path=None, eval_result=None): """A wrapper to export to SavedModel, and convert it to other formats.""" result_dir = base_strategy.export(estimator, export_dir, checkpoint_path, eval_result) with ops.Graph().as_default() as graph: with tf_session.Session(graph=graph) as sess: saved_model_loader.load( sess, [tag_constants.SERVING], result_dir) # Note: This is GTFlow internal API and might change. ensemble_model = graph.get_operation_by_name( "ensemble_model/TreeEnsembleSerialize") _, dfec_str = sess.run(ensemble_model.outputs) dtec = tree_config_pb2.DecisionTreeEnsembleConfig() dtec.ParseFromString(dfec_str) # Export the result in the same folder as the saved model. if convert_fn: convert_fn(dtec, sorted_feature_names, len(dense_floats), len(sparse_float_indices), len(sparse_int_indices), result_dir, eval_result) feature_importances = _get_feature_importances( dtec, sorted_feature_names, len(dense_floats), len(sparse_float_indices), len(sparse_int_indices)) sorted_by_importance = sorted( feature_importances.items(), key=lambda x: -x[1]) assets_dir = os.path.join( compat.as_bytes(result_dir), compat.as_bytes("assets.extra")) gfile.MakeDirs(assets_dir) with gfile.GFile(os.path.join( compat.as_bytes(assets_dir), compat.as_bytes("feature_importances")), "w") as f: f.write("\n".join("%s, %f" % (k, v) for k, v in sorted_by_importance)) return result_dir return export_strategy.ExportStrategy( name, export_fn, strip_default_attrs=True)