def testBuildIteratorInInputFn(self): def _input_fn(): ds = dataset_ops.Dataset.range(10) iterator = ds.make_one_shot_iterator() return iterator.get_next() est = estimator.Estimator(model_fn=self._model_fn) est.train(_input_fn, steps=2, hooks=[self._build_iterator_saver_hook(est)]) self.assertSequenceEqual(self._read_vars(est.model_dir), (2, 1)) est.train(_input_fn, steps=2, hooks=[self._build_iterator_saver_hook(est)]) self.assertSequenceEqual(self._read_vars(est.model_dir), (4, 3))
def setUp(self): super(GroupwiseRankingEstimatorTest, self).setUp() ops.reset_default_graph() self._model_dir = test.get_temp_dir() gfile.MakeDirs(self._model_dir) model_fn = model.make_groupwise_ranking_fn( _group_score_fn, group_size=2, transform_fn=feature.make_identity_transform_fn( ['context', 'weight']), ranking_head=head.create_ranking_head( loss_fn=losses.make_loss_fn( losses.RankingLossKey.PAIRWISE_HINGE_LOSS, weights_feature_name='weight'), optimizer=training.AdagradOptimizer(learning_rate=0.1))) self._estimator = estimator.Estimator(model_fn, self._model_dir)
def test_input_fn_can_return_just_features(self): def _model_fn(features, labels, mode): _, _ = features, labels return model_fn_lib.EstimatorSpec( mode, loss=constant_op.constant(0.), train_op=constant_op.constant(0.), predictions=constant_op.constant([[10.]])) est = estimator.Estimator(model_fn=_model_fn) est.train(dummy_input_fn, steps=1) def _only_features(): return {'x': constant_op.constant([[0.]])} self.assertEqual([10.], next(est.predict(_only_features)))
def test_yield_rows_of_dict(self): def _model_fn(features, labels, mode): _, _ = features, labels return model_fn_lib.EstimatorSpec( mode, loss=constant_op.constant(0.), train_op=constant_op.constant(0.), predictions={ 'y1': constant_op.constant([[10.], [12]]), 'y2': constant_op.constant([[0.], [2.]]) }) est = estimator.Estimator(model_fn=_model_fn) est.train(dummy_input_fn, steps=1) results = est.predict(dummy_input_fn) self.assertDictEqual({'y1': [10.], 'y2': [0.]}, next(results)) self.assertDictEqual({'y1': [12.], 'y2': [2.]}, next(results))
def testDoNotRestore(self): def _input_fn(): return dataset_ops.Dataset.range(10) est = estimator.Estimator(model_fn=self._model_fn) est.train(_input_fn, steps=2, hooks=[self._build_iterator_saver_hook(est)]) self.assertSequenceEqual(self._read_vars(est.model_dir), (2, 1)) est.train(_input_fn, steps=2, hooks=[self._build_iterator_saver_hook(est)]) self.assertSequenceEqual(self._read_vars(est.model_dir), (4, 3)) # Hook not provided, input pipeline was not restored. est.train(_input_fn, steps=2) self.assertSequenceEqual(self._read_vars(est.model_dir), (6, 1))
def test_warn_if_no_queue_runner(self): def _model_fn(features, labels, mode): _, _ = features, labels return model_fn_lib.EstimatorSpec( mode, loss=constant_op.constant(0.), train_op=constant_op.constant(0.), predictions=constant_op.constant([[10.]])) est = estimator.Estimator(model_fn=_model_fn) est.train(dummy_input_fn, steps=1) with test.mock.patch.object(logging, 'warning') as mock_log: next(est.predict(dummy_input_fn)) self.assertRegexpMatches( str(mock_log.call_args), 'Input graph does not contain a QueueRunner.')
def test_return_given_predict_keys(self): def _model_fn(features, labels, mode): _, _ = features, labels return model_fn_lib.EstimatorSpec( mode, loss=constant_op.constant(0.), train_op=constant_op.constant(0.), predictions={ 'y1': constant_op.constant([[10.]]), 'y2': constant_op.constant([[12.]]) }) est = estimator.Estimator(model_fn=_model_fn) est.train(dummy_input_fn, steps=1) results = next(est.predict(dummy_input_fn, predict_keys=['y1'])) self.assertIn('y1', results) self.assertNotIn('y2', results)
def test_predict_keys_does_not_exists(self): def _model_fn(features, labels, mode): _, _ = features, labels return model_fn_lib.EstimatorSpec( mode, loss=constant_op.constant(0.), train_op=constant_op.constant(0.), predictions={ 'y1': constant_op.constant([[10.]]), 'y2': constant_op.constant([[12.]]) }) est = estimator.Estimator(model_fn=_model_fn) est.train(dummy_input_fn, steps=1) with self.assertRaisesRegexp( ValueError, 'Expected to run at least one output from'): next(est.predict(dummy_input_fn, predict_keys=['y3']))
def test_batch_size_mismatch(self): def _model_fn(features, labels, mode): _, _ = features, labels return model_fn_lib.EstimatorSpec( mode, loss=constant_op.constant(0.), train_op=constant_op.constant(0.), predictions={ 'y1': constant_op.constant([[10.]]), 'y2': constant_op.constant([[12.], [13]]) }) est = estimator.Estimator(model_fn=_model_fn) est.train(dummy_input_fn, steps=1) with self.assertRaisesRegexp( ValueError, 'Batch length of predictions should be same'): next(est.predict(dummy_input_fn))
def _test_export_all_saved_models(self, input_receiver_fn_map): tmpdir = tempfile.mkdtemp() est = estimator.Estimator(model_fn=_model_fn_with_x_y) est.train(input_fn=_x_y_input_fn, steps=1) # Perform the export. export_dir_base = os.path.join(compat.as_bytes(tmpdir), compat.as_bytes('export')) export_dir = contrib_export.export_all_saved_models( est, export_dir_base, input_receiver_fn_map) # Check that all the files are in the right places. self.assertTrue(gfile.Exists(export_dir_base)) self._validate_exported_files(export_dir) return export_dir, tmpdir
def test_scaffold_is_used(self): self.is_init_fn_called = False def _init_fn(scaffold, sess): _, _ = scaffold, sess self.is_init_fn_called = True def _model_fn_scaffold(features, labels, mode): _, _ = features, labels return model_fn_lib.EstimatorSpec( mode=mode, loss=constant_op.constant(0.), train_op=constant_op.constant(0.), scaffold=training.Scaffold(init_fn=_init_fn)) est = estimator.Estimator(model_fn=_model_fn_scaffold) est.fit(dummy_input_fn, steps=1) self.assertTrue(self.is_init_fn_called)
def test_scaffold_is_used(self): def _model_fn_scaffold(features, labels, mode): _, _ = features, labels variables.Variable(1., name='weight') real_saver = saver.Saver() self.mock_saver = test.mock.Mock(wraps=real_saver, saver_def=real_saver.saver_def) return model_fn_lib.EstimatorSpec( mode=mode, predictions=constant_op.constant([[1.]]), loss=constant_op.constant(0.), train_op=constant_op.constant(0.), scaffold=training.Scaffold(saver=self.mock_saver)) est = estimator.Estimator(model_fn=_model_fn_scaffold) est.train(dummy_input_fn, steps=1) next(est.predict(dummy_input_fn)) self.assertTrue(self.mock_saver.restore.called)
def testTrain(self): shutil.rmtree("testlogs", True) opts = utils.create_ipu_config() utils.configure_ipu_system(opts) run_cfg = run_config.RunConfig() classifier = estimator.Estimator(model_fn=model_fn, config=run_cfg, model_dir="testlogs") classifier.train(input_fn=input_fn, steps=16) event_file = glob.glob("testlogs/event*") self.assertTrue(len(event_file) == 1)
def test_loss_metric_is_reported(self): def _model_fn_with_incremental_loss(features, labels, mode): _, _ = features, labels local_weight = variables.Variable( 0., name='local_weight', collections=[ops.GraphKeys.LOCAL_VARIABLES]) # Loss will be 2, 4, 6, ... loss = 2 * state_ops.assign_add(local_weight, 1.) return model_fn_lib.EstimatorSpec( mode, loss=loss, train_op=state_ops.assign_add(training.get_global_step(), 1)) est = estimator.Estimator(model_fn=_model_fn_with_incremental_loss) est.train(dummy_input_fn, steps=1) scores = est.evaluate(dummy_input_fn, steps=5) self.assertIn(model_fn_lib.MetricKeys.LOSS, scores) # Average loss will be (2 + 4 + 6 + 8 + 10)/5=6 self.assertAlmostEqual(6., scores[model_fn_lib.MetricKeys.LOSS])
def test_scaffold_is_used_for_local_init(self): tmpdir = tempfile.mkdtemp() def _model_fn_scaffold(features, labels, mode): _, _ = features, labels my_int = variables.Variable(1, name='my_int', collections=[ops.GraphKeys.LOCAL_VARIABLES]) scores = constant_op.constant([3.]) with ops.control_dependencies( [variables.local_variables_initializer(), data_flow_ops.tables_initializer()]): assign_op = state_ops.assign(my_int, 12345) # local_initSop must be an Operation, not a Tensor. custom_local_init_op = control_flow_ops.group(assign_op) return model_fn_lib.EstimatorSpec( mode=mode, predictions=constant_op.constant([[1.]]), loss=constant_op.constant(0.), train_op=constant_op.constant(0.), scaffold=training.Scaffold(local_init_op=custom_local_init_op), export_outputs={'test': export.ClassificationOutput(scores)}) est = estimator.Estimator(model_fn=_model_fn_scaffold) est.train(dummy_input_fn, steps=1) feature_spec = {'x': parsing_ops.VarLenFeature(dtype=dtypes.int64), 'y': parsing_ops.VarLenFeature(dtype=dtypes.int64)} serving_input_receiver_fn = export.build_parsing_serving_input_receiver_fn( feature_spec) # Perform the export. export_dir_base = os.path.join( compat.as_bytes(tmpdir), compat.as_bytes('export')) export_dir = est.export_savedmodel(export_dir_base, serving_input_receiver_fn) # Restore, to validate that the custom local_init_op runs. with ops.Graph().as_default() as graph: with session.Session(graph=graph) as sess: loader.load(sess, [tag_constants.SERVING], export_dir) my_int = graph.get_tensor_by_name('my_int:0') my_int_value = sess.run(my_int) self.assertEqual(12345, my_int_value)
def test_export_savedmodel_with_saveables_proto_roundtrip(self): tmpdir = tempfile.mkdtemp() est = estimator.Estimator( model_fn=_model_fn_with_saveables_for_export_tests) est.train(input_fn=dummy_input_fn, steps=1) feature_spec = {'x': parsing_ops.VarLenFeature(dtype=dtypes.int64), 'y': parsing_ops.VarLenFeature(dtype=dtypes.int64)} serving_input_receiver_fn = export.build_parsing_serving_input_receiver_fn( feature_spec) # Perform the export. export_dir_base = os.path.join( compat.as_bytes(tmpdir), compat.as_bytes('export')) export_dir = est.export_savedmodel( export_dir_base, serving_input_receiver_fn) # Check that all the files are in the right places. self.assertTrue(gfile.Exists(export_dir_base)) self.assertTrue(gfile.Exists(export_dir)) self.assertTrue(gfile.Exists(os.path.join( compat.as_bytes(export_dir), compat.as_bytes('saved_model.pb')))) self.assertTrue(gfile.Exists(os.path.join( compat.as_bytes(export_dir), compat.as_bytes('variables')))) self.assertTrue(gfile.Exists(os.path.join( compat.as_bytes(export_dir), compat.as_bytes('variables/variables.index')))) self.assertTrue(gfile.Exists(os.path.join( compat.as_bytes(export_dir), compat.as_bytes('variables/variables.data-00000-of-00001')))) # Restore, to validate that the export was well-formed. with ops.Graph().as_default() as graph: with session.Session(graph=graph) as sess: loader.load(sess, [tag_constants.SERVING], export_dir) graph_ops = [x.name for x in graph.get_operations()] self.assertTrue('input_example_tensor' in graph_ops) self.assertTrue('ParseExample/ParseExample' in graph_ops) self.assertTrue('save/LookupTableImport' in graph_ops) # Clean up. gfile.DeleteRecursively(tmpdir)
def test_hooks_are_used(self): class _StepCounterHook(session_run_hook.SessionRunHook): """Hooks that counts the number of times it is called.""" def __init__(self): self._steps = 0 def before_run(self, run_context): del run_context self._steps += 1 @property def steps(self): return self._steps step_counter_hook = _StepCounterHook() est = estimator.Estimator(model_fn=_model_fn_with_eval_metric_ops) est.fit(dummy_input_fn, steps=1) est.evaluate(dummy_input_fn, steps=5, hooks=[step_counter_hook]) self.assertEqual(5, step_counter_hook.steps)
def test_hooks_are_used(self): def _model_fn(features, labels, mode): _, _ = features, labels return model_fn_lib.EstimatorSpec( mode, loss=constant_op.constant(0.), train_op=constant_op.constant(0.), predictions=constant_op.constant([[10.], [12.]])) step_counter_hook = _StepCounterHook() est = estimator.Estimator(model_fn=_model_fn) est.train(dummy_input_fn, steps=1) results = est.predict(dummy_input_fn, hooks=[step_counter_hook]) self.assertEqual(0, step_counter_hook.steps) # not called yet next(results) self.assertEqual(1, step_counter_hook.steps) # first call next(results) self.assertEqual(1, step_counter_hook.steps) # it's in same batch next(results) self.assertEqual(2, step_counter_hook.steps) # next batch
def test_tuple_metrics(self): def _model_fn(features, labels, mode): del features # unused del labels return model_fn_lib.EstimatorSpec( mode, train_op=control_flow_ops.no_op(), loss=constant_op.constant(1.), eval_metric_ops={ 'nested_metric': ( ((constant_op.constant(2.), constant_op.constant(1)), constant_op.constant(3., dtype=dtypes.float64)), control_flow_ops.no_op())}) est = estimator.Estimator(model_fn=_model_fn) est.train(dummy_input_fn, steps=1) evaluation = est.evaluate(dummy_input_fn, steps=1) ((two_float, one_integer), three_double) = evaluation['nested_metric'] self.assertAlmostEqual(2., two_float) self.assertEqual(1, one_integer) self.assertAlmostEqual(3., three_double)
def test_features_labels_mode(self): given_features = {'test-features': [[1], [1]]} given_labels = {'test-labels': [[1], [1]]} def _input_fn(): return given_features, given_labels def _model_fn(features, labels, mode): self.features, self.labels, self.mode = features, labels, mode return model_fn_lib.EstimatorSpec( mode=mode, loss=constant_op.constant(0.), train_op=constant_op.constant(0.), predictions=constant_op.constant(0.)) est = estimator.Estimator(model_fn=_model_fn) est.train(_input_fn, steps=1) self.assertEqual(given_features, self.features) self.assertEqual(given_labels, self.labels) self.assertEqual(model_fn_lib.ModeKeys.TRAIN, self.mode)
def test_export_savedmodel_extra_assets(self): tmpdir = tempfile.mkdtemp() est = estimator.Estimator(model_fn=_model_fn_for_export_tests) est.train(input_fn=dummy_input_fn, steps=1) feature_spec = { 'x': parsing_ops.VarLenFeature(dtype=dtypes.int64), 'y': parsing_ops.VarLenFeature(dtype=dtypes.int64) } serving_input_receiver_fn = export.build_parsing_serving_input_receiver_fn( feature_spec) # Create a fake asset. extra_file_name = os.path.join(compat.as_bytes(tmpdir), compat.as_bytes('my_extra_file')) extra_file = gfile.GFile(extra_file_name, mode='w') extra_file.write(_EXTRA_FILE_CONTENT) extra_file.close() # Perform the export. assets_extra = {'some/sub/directory/my_extra_file': extra_file_name} export_dir_base = os.path.join(compat.as_bytes(tmpdir), compat.as_bytes('export')) export_dir = est.export_savedmodel(export_dir_base, serving_input_receiver_fn, assets_extra=assets_extra) # Check that the asset files are in the right places. expected_extra_path = os.path.join( compat.as_bytes(export_dir), compat.as_bytes('assets.extra/some/sub/directory/my_extra_file')) self.assertTrue( gfile.Exists( os.path.join(compat.as_bytes(export_dir), compat.as_bytes('assets.extra')))) self.assertTrue(gfile.Exists(expected_extra_path)) self.assertEqual( compat.as_bytes(_EXTRA_FILE_CONTENT), compat.as_bytes(gfile.GFile(expected_extra_path).read())) # cleanup gfile.DeleteRecursively(tmpdir)
def test_training_hooks_are_used(self): chief_hook = test.mock.MagicMock( wraps=training.SessionRunHook(), spec=training.SessionRunHook) hook = test.mock.MagicMock( wraps=training.SessionRunHook(), spec=training.SessionRunHook) def _model_fn_hooks(features, labels, mode): _, _ = features, labels return model_fn_lib.EstimatorSpec( mode=mode, loss=constant_op.constant(0.), train_op=constant_op.constant(0.), training_chief_hooks=[chief_hook], training_hooks=[hook]) est = estimator.Estimator(model_fn=_model_fn_hooks) self.assertFalse(chief_hook.begin.called) self.assertFalse(hook.begin.called) est.fit(dummy_input_fn, steps=1) self.assertTrue(chief_hook.begin.called) self.assertTrue(hook.begin.called)
def test_chief_only_hook_should_not_be_called_on_non_chief(self): chief_hook = test.mock.MagicMock( wraps=training.SessionRunHook(), spec=training.SessionRunHook) hook = test.mock.MagicMock( wraps=training.SessionRunHook(), spec=training.SessionRunHook) def _model_fn_hooks(features, labels, mode): _, _ = features, labels return model_fn_lib.EstimatorSpec( mode=mode, loss=constant_op.constant(0.), train_op=constant_op.constant(0.), training_chief_hooks=[chief_hook], training_hooks=[hook]) class NonChiefRunConfig(run_config.RunConfig): # pylint: disable=g-wrong-blank-lines @property def is_chief(self): # pylint: disable=g-wrong-blank-lines return False # Mocking the SessionManager.wait_for_session, so that worker doesn't wait # for chief. def get_initialized_session(*args, **kwargs): scaffold = training.Scaffold().finalize() sess = session.Session(*args, **kwargs) sess.run(scaffold.init_op) return sess with test.mock.patch.object( training.SessionManager, 'wait_for_session', side_effect=get_initialized_session): est = estimator.Estimator( model_fn=_model_fn_hooks, config=NonChiefRunConfig()) self.assertFalse(chief_hook.begin.called) self.assertFalse(hook.begin.called) est.fit(dummy_input_fn, steps=1) self.assertFalse(chief_hook.begin.called) self.assertTrue(hook.begin.called)
def _export_estimator(self, train=True, evaluate=True, predict=True, model_fn=model_fn_diff_modes): est = estimator.Estimator(model_fn, self._get_tmp_dir()) est.train(input_fn=dummy_input_fn, steps=10) input_receiver_fn_map = {} if train: input_receiver_fn_map[model_fn_lib.ModeKeys.TRAIN] = ( dummy_supervised_receiver_fn()) if evaluate: input_receiver_fn_map[model_fn_lib.ModeKeys.EVAL] = ( dummy_supervised_receiver_fn()) if predict: input_receiver_fn_map[model_fn_lib.ModeKeys.PREDICT] = ( dummy_serving_receiver_fn()) export_base_path = self._get_tmp_dir() export_dir = contrib_export.export_all_saved_models( est, export_base_path, input_receiver_fn_map) return export_dir
def test_graph_initialization_global_step_and_random_seed(self): expected_random_seed = run_config.RunConfig().tf_random_seed def _model_fn(features, labels, mode): _, _, _ = features, labels, mode self.assertIsNotNone(training.get_global_step()) self.assertEqual(expected_random_seed, ops.get_default_graph().seed) return model_fn_lib.EstimatorSpec( mode=mode, loss=constant_op.constant(0.), train_op=constant_op.constant(0.), predictions=constant_op.constant([[0.]]), export_outputs={ 'test': export_output.ClassificationOutput( constant_op.constant([[0.]])) }) def serving_input_receiver_fn(): return export.ServingInputReceiver( {'test-features': constant_op.constant([[1], [1]])}, array_ops.placeholder(dtype=dtypes.string)) est = estimator.Estimator(model_fn=_model_fn) est.train(dummy_input_fn, steps=1) est.export_savedmodel(tempfile.mkdtemp(), serving_input_receiver_fn)
def DNNRegressorWithLayerAnnotations( # pylint: disable=invalid-name hidden_units, feature_columns, model_dir=None, label_dimension=1, weight_column=None, optimizer='Adagrad', activation_fn=nn.relu, dropout=None, input_layer_partitioner=None, config=None, warm_start_from=None, loss_reduction=losses.Reduction.SUM, ): """A regressor for TensorFlow DNN models with layer annotations. This regressor is fuctionally identical to estimator.DNNRegressor as far as training and evaluating models is concerned. The key difference is that this classifier adds additional layer annotations, which can be used for computing Integrated Gradients. Integrated Gradients is a method for attributing a classifier's predictions to its input features (https://arxiv.org/pdf/1703.01365.pdf). Given an input instance, the method assigns attribution scores to individual features in proportion to the feature's importance to the classifier's prediction. See estimator.DNNRegressor for example code for training and evaluating models using this regressor. This regressor is checkpoint-compatible with estimator.DNNRegressor and therefore the following should work seamlessly: # Instantiate ordinary estimator as usual. estimator = tf.estimator.DNNRegressor( config, feature_columns, hidden_units, ...) # Train estimator, export checkpoint. tf.estimator.train_and_evaluate(estimator, ...) # Instantiate estimator with annotations with the same configuration as the # ordinary estimator. estimator_with_annotations = ( tf.contrib.estimator.DNNRegressorWithLayerAnnotations( config, feature_columns, hidden_units, ...)) # Call export_savedmodel with the same arguments as the ordinary estimator, # using the checkpoint produced for the ordinary estimator. estimator_with_annotations.export_saved_model( export_dir_base, serving_input_receiver, ... checkpoint_path='/path/to/ordinary/estimator/checkpoint/model.ckpt-1234') Args: hidden_units: Iterable of number hidden units per layer. All layers are fully connected. Ex. `[64, 32]` means first layer has 64 nodes and second one has 32. feature_columns: An iterable containing all the feature columns used by the model. All items in the set should be instances of classes derived from `_FeatureColumn`. model_dir: Directory to save model parameters, graph and etc. This can also be used to load checkpoints from the directory into a estimator to continue training a previously saved model. label_dimension: Number of regression targets per example. This is the size of the last dimension of the labels and logits `Tensor` objects (typically, these have shape `[batch_size, label_dimension]`). weight_column: A string or a `_NumericColumn` created by `tf.feature_column.numeric_column` defining feature column representing weights. It is used to down weight or boost examples during training. It will be multiplied by the loss of the example. If it is a string, it is used as a key to fetch weight tensor from the `features`. If it is a `_NumericColumn`, raw tensor is fetched by key `weight_column.key`, then weight_column.normalizer_fn is applied on it to get weight tensor. optimizer: An instance of `tf.Optimizer` used to train the model. Defaults to Adagrad optimizer. activation_fn: Activation function applied to each layer. If `None`, will use `tf.nn.relu`. dropout: When not `None`, the probability we will drop out a given coordinate. input_layer_partitioner: Optional. Partitioner for input layer. Defaults to `min_max_variable_partitioner` with `min_slice_size` 64 << 20. config: `RunConfig` object to configure the runtime settings. warm_start_from: A string filepath to a checkpoint to warm-start from, or a `WarmStartSettings` object to fully configure warm-starting. If the string filepath is provided instead of a `WarmStartSettings`, then all weights are warm-started, and it is assumed that vocabularies and Tensor names are unchanged. loss_reduction: One of `tf.losses.Reduction` except `NONE`. Describes how to reduce training loss over batch. Defaults to `SUM`. Returns: DNNRegressor with layer annotations. """ original = dnn.DNNRegressor( hidden_units=hidden_units, feature_columns=feature_columns, model_dir=model_dir, label_dimension=label_dimension, weight_column=weight_column, optimizer=optimizer, activation_fn=activation_fn, dropout=dropout, input_layer_partitioner=input_layer_partitioner, config=config, warm_start_from=warm_start_from, loss_reduction=loss_reduction, ) def _model_fn(features, labels, mode, config): with _monkey_patch( feature_column_lib, '_internal_input_layer', make_input_layer_with_layer_annotations( feature_column_lib._internal_input_layer)): # pylint: disable=protected-access return original.model_fn(features, labels, mode, config) return estimator.Estimator( model_fn=_model_fn, model_dir=model_dir, config=config, warm_start_from=warm_start_from)
def model_to_estimator(keras_model=None, keras_model_path=None, custom_objects=None, model_dir=None, config=None): """Constructs an `Estimator` instance from given keras model. For usage example, please see @{$guide/estimators$creating_estimators_from_keras_models}. Args: keras_model: A compiled Keras model object. This argument is mutually exclusive with `keras_model_path`. keras_model_path: Path to a compiled Keras model saved on disk, in HDF5 format, which can be generated with the `save()` method of a Keras model. This argument is mutually exclusive with `keras_model`. custom_objects: Dictionary for custom objects. model_dir: Directory to save `Estimator` model parameters, graph, summary files for TensorBoard, etc. config: `RunConfig` to config `Estimator`. Returns: An Estimator from given keras model. Raises: ValueError: if neither keras_model nor keras_model_path was given. ValueError: if both keras_model and keras_model_path was given. ValueError: if the keras_model_path is a GCS URI. ValueError: if keras_model has not been compiled. """ if not (keras_model or keras_model_path): raise ValueError( 'Either `keras_model` or `keras_model_path` needs to be provided.') if keras_model and keras_model_path: raise ValueError( 'Please specity either `keras_model` or `keras_model_path`, ' 'but not both.') if not keras_model: if keras_model_path.startswith( 'gs://') or 'storage.googleapis.com' in keras_model_path: raise ValueError( '%s is not a local path. Please copy the model locally first.' % keras_model_path) logging.info('Loading models from %s', keras_model_path) keras_model = models.load_model(keras_model_path) else: logging.info('Using the Keras model provided.') keras_model = keras_model if not hasattr(keras_model, 'optimizer') or not keras_model.optimizer: raise ValueError('The given keras model has not been compiled yet. ' 'Please compile the model with `model.compile()` ' 'before calling `model_to_estimator()`.') config = estimator_lib.maybe_overwrite_model_dir_and_session_config( config, model_dir) keras_model_fn = _create_keras_model_fn(keras_model, custom_objects) if _any_weight_initialized(keras_model): # Warn if config passed to estimator tries to update GPUOptions. If a # session has already been created, the GPUOptions passed to the first # session sticks. if config.session_config.HasField('gpu_options'): logging.warning( 'The Keras backend session has already been set. ' 'The _session_config passed to model_to_estimator will not be used.' ) else: # Pass the config into keras backend's default session. sess = session.Session(config=config.session_config) K.set_session(sess) warm_start_path = None if keras_model._is_graph_network: warm_start_path = _save_first_checkpoint(keras_model, custom_objects, config) elif keras_model.built: logging.warning( 'You are creating an Estimator from a Keras model manually ' 'subclassed from `Model`, that was already called on some ' 'inputs (and thus already had weights). We are currently ' 'unable to preserve the model\'s state (its weights) as ' 'part of the estimator in this case. Be warned that the ' 'estimator has been created using a freshly initialized ' 'version of your model.\n' 'Note that this doesn\'t affect the state of the model ' 'instance you passed as `keras_model` argument.') estimator = estimator_lib.Estimator(keras_model_fn, config=config, warm_start_from=warm_start_path) return estimator
def test_complete_flow(self): n_classes = 3 input_dimension = 2 batch_size = 12 data = np.linspace(0., n_classes - 1., batch_size * input_dimension, dtype=np.float32) x_data = data.reshape(batch_size, input_dimension) categorical_data = np.random.random_integers(0, len(x_data), size=len(x_data)) y_data = np.reshape(self._as_label(data[:batch_size]), (batch_size, 1)) train_input_fn = numpy_io.numpy_input_fn(x={ 'x': x_data, 'categories': categorical_data }, y=y_data, batch_size=batch_size, num_epochs=None, shuffle=True) eval_input_fn = numpy_io.numpy_input_fn(x={ 'x': x_data, 'categories': categorical_data }, y=y_data, batch_size=batch_size, shuffle=False) predict_input_fn = numpy_io.numpy_input_fn(x={ 'x': x_data, 'categories': categorical_data }, batch_size=batch_size, shuffle=False) feature_columns = [ feature_column.numeric_column('x', shape=(input_dimension, )), feature_column.embedding_column( feature_column.categorical_column_with_vocabulary_list( 'categories', vocabulary_list=np.linspace(0., len(x_data), len(x_data), dtype=np.int64)), 1) ] estimator = dnn.DNNClassifier(hidden_units=(2, 2), feature_columns=feature_columns, n_classes=n_classes, model_dir=self._model_dir) def optimizer_fn(): return optimizers.get_optimizer_instance('Adagrad', learning_rate=0.05) estimator = estimator_lib.Estimator( model_fn=replicate_model_fn.replicate_model_fn( estimator.model_fn, optimizer_fn, devices=['/gpu:0', '/gpu:1', '/gpu:2']), model_dir=estimator.model_dir, config=estimator.config, params=estimator.params) num_steps = 10 estimator.train(train_input_fn, steps=num_steps) scores = estimator.evaluate(eval_input_fn) self.assertEqual(num_steps, scores[ops_lib.GraphKeys.GLOBAL_STEP]) self.assertIn('loss', six.iterkeys(scores)) predicted_proba = np.array([ x[prediction_keys.PredictionKeys.PROBABILITIES] for x in estimator.predict(predict_input_fn) ]) self.assertAllEqual((batch_size, n_classes), predicted_proba.shape) feature_spec = feature_column.make_parse_example_spec(feature_columns) serving_input_receiver_fn = export.build_parsing_serving_input_receiver_fn( feature_spec) export_dir = estimator.export_savedmodel(tempfile.mkdtemp(), serving_input_receiver_fn) self.assertTrue(gfile.Exists(export_dir))
def test_model_fn_must_be_provided(self): with self.assertRaisesRegexp(ValueError, 'model_fn.* must be'): estimator.Estimator(model_fn=None)
def test_config_must_be_a_run_config(self): with self.assertRaisesRegexp(ValueError, 'an instance of RunConfig'): estimator.Estimator(model_fn=None, config='NotARunConfig')