def export(self, estimator, export_path, checkpoint_path, eval_result, is_the_final_export): del is_the_final_export export_result = export.export_eval_savedmodel( estimator=estimator, export_dir_base=export_path, eval_input_receiver_fn=self._eval_input_receiver_fn, serving_input_receiver_fn=self._serving_input_receiver_fn, assets_extra=self._assets_extra, checkpoint_path=checkpoint_path, ) return export_result
def export(self, estimator: tf.estimator.Estimator, export_path: Text, checkpoint_path: Optional[Text], eval_result: Optional[bytes], is_the_final_export: bool) -> bytes: del is_the_final_export export_result = export.export_eval_savedmodel( estimator=estimator, export_dir_base=export_path, eval_input_receiver_fn=self._eval_input_receiver_fn, serving_input_receiver_fn=self._serving_input_receiver_fn, assets_extra=self._assets_extra, checkpoint_path=checkpoint_path, ) return export_result
def export_model_and_eval_model(estimator, serving_input_receiver_fn=None, eval_input_receiver_fn=None, export_path=None, eval_export_path=None): """Export SavedModel and EvalSavedModel. Args: estimator: Estimator to export. serving_input_receiver_fn: Serving input receiver function. eval_input_receiver_fn: Eval input receiver function. export_path: Export path. If None, inference model is not exported. eval_export_path: Eval export path. If None, EvalSavedModel is not exported. Returns: Tuple of (path to the export directory, path to eval export directory). """ export_path_result = None eval_export_path_result = None if export_path and serving_input_receiver_fn: args = dict(export_dir_base=export_path) if isinstance(estimator, tf.contrib.learn.Estimator): args['serving_input_fn'] = serving_input_receiver_fn export_fn = estimator.export_savedmodel else: args['serving_input_receiver_fn'] = serving_input_receiver_fn export_fn = estimator.export_saved_model export_path_result = export_fn(**args) if eval_export_path and eval_input_receiver_fn: eval_export_path_result = export.export_eval_savedmodel( estimator=estimator, export_dir_base=eval_export_path, eval_input_receiver_fn=eval_input_receiver_fn, serving_input_receiver_fn=serving_input_receiver_fn) return export_path_result, eval_export_path_result
def simple_csv_linear_classifier(export_path, eval_export_path): """Trains and exports a simple linear classifier.""" def parse_csv(rows_string_tensor): """Takes the string input tensor and returns a dict of rank-2 tensors.""" csv_columns = ['age', 'language', 'label'] csv_column_defaults = [[0.0], ['unknown'], [0.0]] # Takes a rank-1 tensor and converts it into rank-2 tensor # Example if the data is ['csv,line,1', 'csv,line,2', ..] to # [['csv,line,1'], ['csv,line,2']] which after parsing will result in a # tuple of tensors: [['csv'], ['csv']], [['line'], ['line']], [[1], [2]] row_columns = tf.expand_dims(rows_string_tensor, -1) columns = tf.decode_csv(row_columns, record_defaults=csv_column_defaults) features = dict(zip(csv_columns, columns)) return features def eval_input_receiver_fn(): """Eval input receiver function.""" csv_row = tf.placeholder(dtype=tf.string, shape=[None], name='input_csv_row') features = parse_csv(csv_row) receiver_tensors = {'examples': csv_row} return export.EvalInputReceiver(features=features, receiver_tensors=receiver_tensors, labels=features['label']) def input_fn(): """Train input function.""" return { 'age': tf.constant([[1], [2], [3], [4]]), 'language': tf.SparseTensor( values=['english', 'english', 'chinese', 'chinese'], indices=[[0, 0], [1, 0], [2, 0], [3, 0]], dense_shape=[4, 1]) }, tf.constant([[1], [1], [0], [0]]) language = tf.contrib.layers.sparse_column_with_keys( 'language', ['english', 'chinese']) age = tf.contrib.layers.real_valued_column('age') all_features = [age, language] feature_spec = tf.contrib.layers.create_feature_spec_for_parsing( all_features) classifier = tf.estimator.LinearClassifier(feature_columns=all_features) classifier.train(input_fn=input_fn, steps=1000) export_dir = None eval_export_dir = None if export_path: export_dir = classifier.export_savedmodel( export_dir_base=export_path, serving_input_receiver_fn=tf.estimator.export. build_parsing_serving_input_receiver_fn(feature_spec)) if eval_export_path: eval_export_dir = export.export_eval_savedmodel( estimator=classifier, export_dir_base=eval_export_path, eval_input_receiver_fn=eval_input_receiver_fn) return export_dir, eval_export_dir
def simple_linear_classifier(export_path, eval_export_path): """Trains and exports a simple linear classifier.""" def eval_input_receiver_fn(): """Eval input receiver function.""" serialized_tf_example = tf.placeholder(dtype=tf.string, shape=[None], name='input_example_tensor') language = tf.contrib.layers.sparse_column_with_keys( 'language', ['english', 'chinese']) slice_key = tf.contrib.layers.sparse_column_with_hash_bucket( 'slice_key', 100) age = tf.contrib.layers.real_valued_column('age') label = tf.contrib.layers.real_valued_column('label') all_features = [age, language, label, slice_key] feature_spec = tf.contrib.layers.create_feature_spec_for_parsing( all_features) receiver_tensors = {'examples': serialized_tf_example} features = tf.parse_example(serialized_tf_example, feature_spec) return export.EvalInputReceiver(features=features, receiver_tensors=receiver_tensors, labels=features['label']) def input_fn(): """Train input function.""" return { 'age': tf.constant([[1], [2], [3], [4]]), 'language': tf.SparseTensor( values=['english', 'english', 'chinese', 'chinese'], indices=[[0, 0], [1, 0], [2, 0], [3, 0]], dense_shape=[4, 1]) }, tf.constant([[1], [1], [0], [0]]) language = tf.contrib.layers.sparse_column_with_keys( 'language', ['english', 'chinese']) age = tf.contrib.layers.real_valued_column('age') all_features = [age, language] # slice_key not used in training. feature_spec = tf.contrib.layers.create_feature_spec_for_parsing( all_features) def my_metrics(features, labels, predictions): return { 'my_mean_prediction': tf.metrics.mean(predictions['logistic']), 'my_mean_age': tf.metrics.mean(features['age']), 'my_mean_label': tf.metrics.mean(labels), 'my_mean_age_times_label': tf.metrics.mean(labels * features['age']), } classifier = tf.estimator.LinearClassifier(feature_columns=all_features) classifier = tf.contrib.estimator.add_metrics(classifier, my_metrics) classifier.train(input_fn=input_fn, steps=1000) export_dir = None eval_export_dir = None if export_path: export_dir = classifier.export_savedmodel( export_dir_base=export_path, serving_input_receiver_fn=tf.estimator.export. build_parsing_serving_input_receiver_fn(feature_spec)) if eval_export_path: eval_export_dir = export.export_eval_savedmodel( estimator=classifier, export_dir_base=eval_export_path, eval_input_receiver_fn=eval_input_receiver_fn) return export_dir, eval_export_dir
def simple_fixed_prediction_estimator_extra_fields(export_path, eval_export_path): """Exports a simple fixed prediction estimator that parses extra fields.""" def model_fn(features, labels, mode, params): """Model function for custom estimator.""" del params predictions = features['prediction'] if mode == tf.estimator.ModeKeys.PREDICT: return tf.estimator.EstimatorSpec( mode=mode, predictions={'score': predictions}, export_outputs={ 'score': tf.estimator.export.RegressionOutput(predictions) }) loss = tf.losses.mean_squared_error(predictions, labels) train_op = tf.assign_add(tf.train.get_global_step(), 1) return tf.estimator.EstimatorSpec(mode=mode, loss=loss, train_op=train_op, predictions=predictions) def train_input_fn(): """Train input function.""" return { 'prediction': tf.constant([[1.0], [2.0], [3.0], [4.0]]), }, tf.constant([[1.0], [2.0], [3.0], [4.0]]), def serving_input_receiver_fn(): """Serving input receiver function.""" serialized_tf_example = tf.placeholder(dtype=tf.string, shape=[None], name='input_example_tensor') feature_spec = { 'prediction': tf.FixedLenFeature([1], dtype=tf.float32) } receiver_tensors = {'examples': serialized_tf_example} features = tf.parse_example(serialized_tf_example, feature_spec) return tf.estimator.export.ServingInputReceiver( features, receiver_tensors) def eval_input_receiver_fn(): """Eval input receiver function.""" serialized_tf_example = tf.placeholder(dtype=tf.string, shape=[None], name='input_example_tensor') feature_spec = { 'prediction': tf.FixedLenFeature([1], dtype=tf.float32), 'label': tf.FixedLenFeature([1], dtype=tf.float32), 'fixed_float': tf.FixedLenFeature([1], dtype=tf.float32), 'fixed_string': tf.FixedLenFeature([1], dtype=tf.string), 'var_float': tf.VarLenFeature(dtype=tf.float32), 'var_string': tf.VarLenFeature(dtype=tf.string) } receiver_tensors = {'examples': serialized_tf_example} features = tf.parse_example(serialized_tf_example, feature_spec) return export.EvalInputReceiver(features=features, receiver_tensors=receiver_tensors, labels=features['label']) estimator = tf.estimator.Estimator(model_fn=model_fn) estimator.train(input_fn=train_input_fn, steps=1) export_dir = None eval_export_dir = None if export_path: export_dir = estimator.export_savedmodel( export_dir_base=export_path, serving_input_receiver_fn=serving_input_receiver_fn) if eval_export_path: eval_export_dir = export.export_eval_savedmodel( estimator=estimator, export_dir_base=eval_export_path, eval_input_receiver_fn=eval_input_receiver_fn) return export_dir, eval_export_dir
def simple_fake_sequence_to_prediction(export_path, eval_export_path): """Trains and exports a fake_sequence_to_prediction model.""" input_feature_spec = { 'values_t1': tf.VarLenFeature(dtype=tf.float32), 'values_t2': tf.VarLenFeature(dtype=tf.float32), 'values_t3': tf.VarLenFeature(dtype=tf.float32) } label_feature_spec = dict(input_feature_spec) label_feature_spec['label'] = tf.FixedLenFeature([1], dtype=tf.float32) def _make_embedding_and_sparse_values(features): """Make "embedding" and "sparse_values" features.""" embedding_dim = 3 sparse_dims = 3 sparse_timesteps = 3 # Create a three-dimensional "embedding" based on the value of the feature # The embedding is simply [1, 1, 1] * feature_value # (or [0, 0, 0] if the feature is missing). batch_size = tf.cast(tf.shape(features['values_t1'])[0], dtype=tf.int64) ones = tf.ones(shape=[embedding_dim]) dense_t1 = tf.sparse_tensor_to_dense(features['values_t1']) dense_t2 = tf.sparse_tensor_to_dense(features['values_t2']) dense_t3 = tf.sparse_tensor_to_dense(features['values_t3']) embedding_t1 = ones * dense_t1 embedding_t2 = ones * dense_t2 embedding_t3 = ones * dense_t3 embeddings = tf.stack([embedding_t1, embedding_t2, embedding_t3], axis=1) features['embedding'] = embeddings del features['values_t1'] del features['values_t2'] del features['values_t3'] # Make the "sparse_values" feature. sparse_values = tf.squeeze( tf.concat([ dense_t1, dense_t1**2, dense_t1**3, dense_t2, dense_t2**2, dense_t2**3, dense_t3, dense_t3**2, dense_t3**3 ], axis=0)) sparse_total_elems = batch_size * sparse_dims * sparse_timesteps seq = tf.range(0, sparse_total_elems, dtype=tf.int64) batch_num = seq % batch_size timestep = tf.div(seq, batch_size * sparse_dims) offset = tf.div(seq, batch_size) % sparse_dims sparse_indices = tf.stack([batch_num, timestep, offset], axis=1) features['sparse_values'] = tf.SparseTensor( indices=sparse_indices, values=sparse_values, dense_shape=[batch_size, sparse_timesteps, sparse_dims]) def model_fn(features, labels, mode, params): """Model function for custom estimator.""" del params dense_values = tf.sparse_tensor_to_dense(features['sparse_values'], validate_indices=False) a = tf.Variable(1.0, dtype=tf.float32, name='a') b = tf.Variable(2.0, dtype=tf.float32, name='b') c = tf.Variable(3.0, dtype=tf.float32, name='c') d = tf.Variable(4.0, dtype=tf.float32, name='d') e = tf.Variable(5.0, dtype=tf.float32, name='e') f = tf.Variable(6.0, dtype=tf.float32, name='f') predictions = ( a * tf.reduce_sum(features['embedding'][:, 0, :], axis=1) + b * tf.reduce_sum(features['embedding'][:, 1, :], axis=1) + c * tf.reduce_sum(features['embedding'][:, 2, :], axis=1) + d * tf.reduce_sum(dense_values[:, 0, :], axis=1) + e * tf.reduce_sum(dense_values[:, 1, :], axis=1) + f * tf.reduce_sum(dense_values[:, 2, :], axis=1)) if mode == tf.estimator.ModeKeys.PREDICT: return tf.estimator.EstimatorSpec( mode=mode, predictions={'score': predictions}, export_outputs={ 'score': tf.estimator.export.RegressionOutput(predictions) }) loss = tf.losses.mean_squared_error( labels, tf.expand_dims(predictions, axis=-1)) optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.0001) train_op = optimizer.minimize(loss=loss, global_step=tf.train.get_global_step()) return tf.estimator.EstimatorSpec(mode=mode, loss=loss, train_op=train_op, eval_metric_ops={ 'mean_squared_error': tf.metrics.mean_squared_error( labels, tf.expand_dims(predictions, axis=-1)), 'mean_prediction': tf.metrics.mean(predictions), }, predictions=predictions) def train_input_fn(): """Train input function.""" def make_example_with_label(values_t1=None, values_t2=None, values_t3=None): """Make example with label.""" effective_t1 = 0.0 effective_t2 = 0.0 effective_t3 = 0.0 args = {} if values_t1 is not None: args['values_t1'] = float(values_t1) effective_t1 = values_t1 if values_t2 is not None: args['values_t2'] = float(values_t2) effective_t2 = values_t2 if values_t3 is not None: args['values_t3'] = float(values_t3) effective_t3 = values_t3 label = (3 * effective_t1 + 6 * effective_t2 + 9 * effective_t3 + 4 * (effective_t1 + effective_t1**2 + effective_t1**3) + 5 * (effective_t2 + effective_t2**2 + effective_t2**3) + 6 * (effective_t3 + effective_t3**2 + effective_t3**3)) args['label'] = float(label) return util.make_example(**args) examples = [ make_example_with_label(values_t1=1.0), make_example_with_label(values_t2=1.0), make_example_with_label(values_t3=1.0), make_example_with_label(values_t1=2.0, values_t2=3.0), make_example_with_label(values_t1=5.0, values_t3=7.0), make_example_with_label(values_t2=11.0, values_t3=13.0), make_example_with_label(values_t1=2.0, values_t2=3.0, values_t3=5.0), ] serialized_examples = [x.SerializeToString() for x in examples] features = tf.parse_example(serialized_examples, label_feature_spec) _make_embedding_and_sparse_values(features) label = features.pop('label') return features, label def serving_input_receiver_fn(): """Serving input receiver function.""" serialized_tf_example = tf.placeholder(dtype=tf.string, shape=[None], name='input_example_tensor') receiver_tensors = {'examples': serialized_tf_example} features = tf.parse_example(serialized_tf_example, input_feature_spec) _make_embedding_and_sparse_values(features) return tf.estimator.export.ServingInputReceiver( features, receiver_tensors) def eval_input_receiver_fn(): """Eval input receiver function.""" serialized_tf_example = tf.placeholder(dtype=tf.string, shape=[None], name='input_example_tensor') receiver_tensors = {'examples': serialized_tf_example} features = tf.parse_example(serialized_tf_example, label_feature_spec) _make_embedding_and_sparse_values(features) return export.EvalInputReceiver(features=features, receiver_tensors=receiver_tensors, labels=features['label']) estimator = tf.estimator.Estimator(model_fn=model_fn) estimator.train(input_fn=train_input_fn, steps=10) export_dir = None eval_export_dir = None if export_path: export_dir = estimator.export_saved_model( export_dir_base=export_path, serving_input_receiver_fn=serving_input_receiver_fn) if eval_export_path: eval_export_dir = export.export_eval_savedmodel( estimator=estimator, export_dir_base=eval_export_path, eval_input_receiver_fn=eval_input_receiver_fn) return export_dir, eval_export_dir
def simple_custom_estimator(export_path, eval_export_path): """Trains and exports a simple custom estimator.""" def model_fn(features, labels, mode, params): """Model function for custom estimator.""" del params m = tf.Variable(0.0, dtype=tf.float32, name='m') c = tf.Variable(0.0, dtype=tf.float32, name='c') predictions = m * features['age'] + c if mode == tf.estimator.ModeKeys.PREDICT: return tf.estimator.EstimatorSpec( mode=mode, predictions={'score': predictions}, export_outputs={ 'score': tf.estimator.export.RegressionOutput(predictions) }) loss = tf.losses.mean_squared_error(labels, predictions) eval_metric_ops = { 'mean_absolute_error': tf.metrics.mean_absolute_error(tf.cast(labels, tf.float64), tf.cast(predictions, tf.float64)), 'mean_prediction': tf.metrics.mean(predictions), 'mean_label': tf.metrics.mean(labels), } optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.001) train_op = optimizer.minimize(loss=loss, global_step=tf.train.get_global_step()) return tf.estimator.EstimatorSpec(mode=mode, loss=loss, train_op=train_op, eval_metric_ops=eval_metric_ops, predictions=predictions) def train_input_fn(): """Train input function.""" return { 'age': tf.constant([[1.0], [2.0], [3.0], [4.0]]), }, tf.constant([[4.0], [7.0], [10.0], [13.0]]), def serving_input_receiver_fn(): """Serving input receiver function.""" serialized_tf_example = tf.placeholder(dtype=tf.string, shape=[None], name='input_example_tensor') feature_spec = {'age': tf.FixedLenFeature([1], dtype=tf.float32)} receiver_tensors = {'examples': serialized_tf_example} features = tf.parse_example(serialized_tf_example, feature_spec) return tf.estimator.export.ServingInputReceiver( features, receiver_tensors) def eval_input_receiver_fn(): """Eval input receiver function.""" serialized_tf_example = tf.placeholder(dtype=tf.string, shape=[None], name='input_example_tensor') feature_spec = { 'age': tf.FixedLenFeature([1], dtype=tf.float32), 'label': tf.FixedLenFeature([1], dtype=tf.float32) } receiver_tensors = {'examples': serialized_tf_example} features = tf.parse_example(serialized_tf_example, feature_spec) return export.EvalInputReceiver(features=features, receiver_tensors=receiver_tensors, labels=features['label']) estimator = tf.estimator.Estimator(model_fn=model_fn) estimator.train(input_fn=train_input_fn, steps=1000) export_dir = None eval_export_dir = None if export_path: export_dir = estimator.export_savedmodel( export_dir_base=export_path, serving_input_receiver_fn=serving_input_receiver_fn) if eval_export_path: eval_export_dir = export.export_eval_savedmodel( estimator=estimator, export_dir_base=eval_export_path, eval_input_receiver_fn=eval_input_receiver_fn) return export_dir, eval_export_dir
def simple_multi_head(export_path, eval_export_path): """Trains and exports a simple multi-headed model.""" def eval_input_receiver_fn(): """Eval input receiver function.""" serialized_tf_example = tf.placeholder(dtype=tf.string, shape=[None], name='input_example_tensor') language = tf.contrib.layers.sparse_column_with_keys( 'language', ['english', 'chinese', 'other']) age = tf.contrib.layers.real_valued_column('age') english_label = tf.contrib.layers.real_valued_column('english_label') chinese_label = tf.contrib.layers.real_valued_column('chinese_label') other_label = tf.contrib.layers.real_valued_column('other_label') all_features = [ age, language, english_label, chinese_label, other_label ] feature_spec = tf.contrib.layers.create_feature_spec_for_parsing( all_features) receiver_tensors = {'examples': serialized_tf_example} features = tf.parse_example(serialized_tf_example, feature_spec) labels = { 'english_head': features['english_label'], 'chinese_head': features['chinese_label'], 'other_head': features['other_label'], } return export.EvalInputReceiver(features=features, receiver_tensors=receiver_tensors, labels=labels) def input_fn(): """Train input function.""" labels = { 'english_head': tf.constant([[1], [1], [0], [0], [0], [0]]), 'chinese_head': tf.constant([[0], [0], [1], [1], [0], [0]]), 'other_head': tf.constant([[0], [0], [0], [0], [1], [1]]) } features = { 'age': tf.constant([[1], [2], [3], [4], [5], [6]]), 'language': tf.SparseTensor(values=[ 'english', 'english', 'chinese', 'chinese', 'other', 'other' ], indices=[[0, 0], [1, 0], [2, 0], [3, 0], [4, 0], [5, 0]], dense_shape=[6, 1]), } return features, labels language = tf.contrib.layers.sparse_column_with_keys( 'language', ['english', 'chinese', 'other']) age = tf.contrib.layers.real_valued_column('age') all_features = [age, language] feature_spec = tf.contrib.layers.create_feature_spec_for_parsing( all_features) english_head = tf.contrib.learn.multi_class_head(n_classes=2, label_name='english_head', head_name='english_head') chinese_head = tf.contrib.learn.multi_class_head(n_classes=2, label_name='chinese_head', head_name='chinese_head') other_head = tf.contrib.learn.multi_class_head(n_classes=2, label_name='other_head', head_name='other_head') estimator = tf.contrib.learn.DNNLinearCombinedEstimator( head=tf.contrib.learn.multi_head( heads=[english_head, chinese_head, other_head]), dnn_feature_columns=[], dnn_optimizer=tf.train.AdagradOptimizer(learning_rate=0.01), dnn_hidden_units=[], linear_feature_columns=[language, age], linear_optimizer=tf.train.FtrlOptimizer(learning_rate=0.05)) estimator.fit(input_fn=input_fn, steps=1000) export_dir = None eval_export_dir = None if export_path: export_dir = estimator.export_savedmodel( export_dir_base=export_path, serving_input_fn=tf.contrib.learn.build_parsing_serving_input_fn( feature_spec), default_output_alternative_key='english_head') if eval_export_path: eval_export_dir = export.export_eval_savedmodel( estimator=estimator, export_dir_base=eval_export_path, eval_input_receiver_fn=eval_input_receiver_fn) return export_dir, eval_export_dir