Missed TensorFlow Dev Summit? Check out the video playlist. Watch recordings

Preprocessing data with TensorFlow Transform

The Feature Engineering Component of TensorFlow Extended (TFX)

This example colab notebook provides a somewhat more advanced example of how TensorFlow Transform (tf.Transform) can be used to preprocess data using exactly the same code for both training a model and serving inferences in production.

TensorFlow Transform is a library for preprocessing input data for TensorFlow, including creating features that require a full pass over the training dataset. For example, using TensorFlow Transform you could:

  • Normalize an input value by using the mean and standard deviation
  • Convert strings to integers by generating a vocabulary over all of the input values
  • Convert floats to integers by assigning them to buckets, based on the observed data distribution

TensorFlow has built-in support for manipulations on a single example or a batch of examples. tf.Transform extends these capabilities to support full passes over the entire training dataset.

The output of tf.Transform is exported as a TensorFlow graph which you can use for both training and serving. Using the same graph for both training and serving can prevent skew, since the same transformations are applied in both stages.

What we're doing in this example

In this example we'll be processing a widely used dataset containing census data, and training a model to do classification. Along the way we'll be transforming the data using tf.Transform.

Python check, imports, and globals

First we'll make sure that we're using Python 3, and then go ahead and install and import the stuff we need.

import sys

# Confirm that we're using Python 3
assert sys.version_info.major is 3, 'Oops, not running Python 3. Use Runtime > Change runtime type'
import os
import pprint

print('Installing TensorFlow')
try:
  # %tensorflow_version only exists in Colab.
  %tensorflow_version 2.x
except Exception:
  pass
import tensorflow as tf
print('TF: {}'.format(tf.__version__))

print('Installing Apache Beam')
!pip install -Uq apache_beam==2.17.0
import apache_beam as beam
print('Beam: {}'.format(beam.__version__))

print('Installing TensorFlow Transform')
!pip install -q tensorflow-transform==0.21
import tensorflow_transform as tft
print('Transform: {}'.format(tft.__version__))

import tensorflow_transform.beam as tft_beam

!wget https://storage.googleapis.com/artifacts.tfx-oss-public.appspot.com/datasets/census/adult.data
!wget https://storage.googleapis.com/artifacts.tfx-oss-public.appspot.com/datasets/census/adult.test

train = './adult.data'
test = './adult.test'
Installing TensorFlow
TF: 2.1.0
Installing Apache Beam
Beam: 2.17.0
Installing TensorFlow Transform
ERROR: tfx-bsl 0.21.2 has requirement avro-python3!=1.9.2.*,!=<2.0.0,>=1.8.1; python_version >= "3.0", but you'll have avro-python3 1.9.2.1 which is incompatible.
Transform: 0.21.0
--2020-02-24 18:49:41--  https://storage.googleapis.com/artifacts.tfx-oss-public.appspot.com/datasets/census/adult.data
Resolving storage.googleapis.com (storage.googleapis.com)... 74.125.203.128, 2404:6800:4008:c07::80
Connecting to storage.googleapis.com (storage.googleapis.com)|74.125.203.128|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 3974305 (3.8M) [application/octet-stream]
Saving to: ‘adult.data’

adult.data          100%[===================>]   3.79M  --.-KB/s    in 0.02s   

2020-02-24 18:49:42 (162 MB/s) - ‘adult.data’ saved [3974305/3974305]

--2020-02-24 18:49:42--  https://storage.googleapis.com/artifacts.tfx-oss-public.appspot.com/datasets/census/adult.test
Resolving storage.googleapis.com (storage.googleapis.com)... 74.125.203.128, 2404:6800:4008:c07::80
Connecting to storage.googleapis.com (storage.googleapis.com)|74.125.203.128|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 2003153 (1.9M) [application/octet-stream]
Saving to: ‘adult.test’

adult.test          100%[===================>]   1.91M  --.-KB/s    in 0.01s   

2020-02-24 18:49:43 (194 MB/s) - ‘adult.test’ saved [2003153/2003153]

Name our columns

We'll create some handy lists for referencing the columns in our dataset.

CATEGORICAL_FEATURE_KEYS = [
    'workclass',
    'education',
    'marital-status',
    'occupation',
    'relationship',
    'race',
    'sex',
    'native-country',
]
NUMERIC_FEATURE_KEYS = [
    'age',
    'capital-gain',
    'capital-loss',
    'hours-per-week',
]
OPTIONAL_NUMERIC_FEATURE_KEYS = [
    'education-num',
]
LABEL_KEY = 'label'

Define our features and schema

Let's define a schema based on what types the columns are in our input. Among other things this will help with importing them correctly.

RAW_DATA_FEATURE_SPEC = dict(
    [(name, tf.io.FixedLenFeature([], tf.string))
     for name in CATEGORICAL_FEATURE_KEYS] +
    [(name, tf.io.FixedLenFeature([], tf.float32))
     for name in NUMERIC_FEATURE_KEYS] +
    [(name, tf.io.VarLenFeature(tf.float32))
     for name in OPTIONAL_NUMERIC_FEATURE_KEYS] +
    [(LABEL_KEY, tf.io.FixedLenFeature([], tf.string))]
)

RAW_DATA_METADATA = tft.tf_metadata.dataset_metadata.DatasetMetadata(
    tft.tf_metadata.dataset_schema.schema_utils.schema_from_feature_spec(RAW_DATA_FEATURE_SPEC))

Setting hyperparameters and basic housekeeping

Constants and hyperparameters used for training. The bucket size includes all listed categories in the dataset description as well as one extra for "?" which represents unknown.

testing = os.getenv("WEB_TEST_BROWSER", False)
if testing:
  TRAIN_NUM_EPOCHS = 1
  NUM_TRAIN_INSTANCES = 1
  TRAIN_BATCH_SIZE = 1
  NUM_TEST_INSTANCES = 1
else:
  TRAIN_NUM_EPOCHS = 16
  NUM_TRAIN_INSTANCES = 32561
  TRAIN_BATCH_SIZE = 128
  NUM_TEST_INSTANCES = 16281

# Names of temp files
TRANSFORMED_TRAIN_DATA_FILEBASE = 'train_transformed'
TRANSFORMED_TEST_DATA_FILEBASE = 'test_transformed'
EXPORTED_MODEL_DIR = 'exported_model_dir'

Cleaning

Create a Beam Transform for cleaning our input data

We'll create a Beam Transform by creating a subclass of Apache Beam's PTransform class and overriding the expand method to specify the actual processing logic. A PTransform represents a data processing operation, or a step, in your pipeline. Every PTransform takes one or more PCollection objects as input, performs a processing function that you provide on the elements of that PCollection, and produces zero or more output PCollection objects.

Our transform class will apply Beam's ParDo on the input PCollection containing our census dataset, producing clean data in an output PCollection.

class MapAndFilterErrors(beam.PTransform):
  """Like beam.Map but filters out errors in the map_fn."""

  class _MapAndFilterErrorsDoFn(beam.DoFn):
    """Count the bad examples using a beam metric."""

    def __init__(self, fn):
      self._fn = fn
      # Create a counter to measure number of bad elements.
      self._bad_elements_counter = beam.metrics.Metrics.counter(
          'census_example', 'bad_elements')

    def process(self, element):
      try:
        yield self._fn(element)
      except Exception:  # pylint: disable=broad-except
        # Catch any exception the above call.
        self._bad_elements_counter.inc(1)

  def __init__(self, fn):
    self._fn = fn

  def expand(self, pcoll):
    return pcoll | beam.ParDo(self._MapAndFilterErrorsDoFn(self._fn))

Preprocessing with tf.Transform

Create a tf.Transform preprocessing_fn

The preprocessing function is the most important concept of tf.Transform. A preprocessing function is where the transformation of the dataset really happens. It accepts and returns a dictionary of tensors, where a tensor means a Tensor or SparseTensor. There are two main groups of API calls that typically form the heart of a preprocessing function:

  1. TensorFlow Ops: Any function that accepts and returns tensors, which usually means TensorFlow ops. These add TensorFlow operations to the graph that transforms raw data into transformed data one feature vector at a time. These will run for every example, during both training and serving.
  2. TensorFlow Transform Analyzers: Any of the analyzers provided by tf.Transform. Analyzers also accept and return tensors, but unlike TensorFlow ops they only run once, during training, and typically make a full pass over the entire training dataset. They create tensor constants, which are added to your graph. For example, tft.min computes the minimum of a tensor over the training dataset. tf.Transform provides a fixed set of analyzers, but this will be extended in future versions.
def preprocessing_fn(inputs):
  """Preprocess input columns into transformed columns."""
  # Since we are modifying some features and leaving others unchanged, we
  # start by setting `outputs` to a copy of `inputs.
  outputs = inputs.copy()

  # Scale numeric columns to have range [0, 1].
  for key in NUMERIC_FEATURE_KEYS:
    outputs[key] = tft.scale_to_0_1(outputs[key])

  for key in OPTIONAL_NUMERIC_FEATURE_KEYS:
    # This is a SparseTensor because it is optional. Here we fill in a default
    # value when it is missing.
    sparse = tf.sparse.SparseTensor(outputs[key].indices, outputs[key].values,
                                    [outputs[key].dense_shape[0], 1])
    dense = tf.sparse.to_dense(sp_input=sparse, default_value=0.)
    # Reshaping from a batch of vectors of size 1 to a batch to scalars.
    dense = tf.squeeze(dense, axis=1)
    outputs[key] = tft.scale_to_0_1(dense)

    # For all categorical columns except the label column, we generate a
    # vocabulary but do not modify the feature.  This vocabulary is instead
    # used in the trainer, by means of a feature column, to convert the feature
    # from a string to an integer id.
    for key in CATEGORICAL_FEATURE_KEYS:
      tft.vocabulary(inputs[key], vocab_filename=key)

    # For the label column we provide the mapping from string to index.
    table_keys = ['>50K', '<=50K']
    initializer = tf.lookup.KeyValueTensorInitializer(
        keys=table_keys,
        values=tf.cast(tf.range(len(table_keys)), tf.int64),
        key_dtype=tf.string,
        value_dtype=tf.int64)
    table = tf.lookup.StaticHashTable(initializer, default_value=-1)
    outputs[LABEL_KEY] = table.lookup(outputs[LABEL_KEY])

  return outputs

Transform the data

Now we're ready to start transforming our data in an Apache Beam pipeline.

  1. Read in the data using the CSV reader
  2. Clean it using our new MapAndFilterErrors transform
  3. Transform it using a preprocessing pipeline that scales numeric data and converts categorical data from strings to int64 values indices, by creating a vocabulary for each category
  4. Write out the result as a TFRecord of Example protos, which we will use for training a model later
def transform_data(train_data_file, test_data_file, working_dir):
  """Transform the data and write out as a TFRecord of Example protos.

  Read in the data using the CSV reader, and transform it using a
  preprocessing pipeline that scales numeric data and converts categorical data
  from strings to int64 values indices, by creating a vocabulary for each
  category.

  Args:
    train_data_file: File containing training data
    test_data_file: File containing test data
    working_dir: Directory to write transformed data and metadata to
  """

  # The "with" block will create a pipeline, and run that pipeline at the exit
  # of the block.
  with beam.Pipeline() as pipeline:
    with tft_beam.Context(temp_dir=tempfile.mkdtemp()):
      # Create a coder to read the census data with the schema.  To do this we
      # need to list all columns in order since the schema doesn't specify the
      # order of columns in the csv.
      ordered_columns = [
          'age', 'workclass', 'fnlwgt', 'education', 'education-num',
          'marital-status', 'occupation', 'relationship', 'race', 'sex',
          'capital-gain', 'capital-loss', 'hours-per-week', 'native-country',
          'label'
      ]
      converter = tft.coders.CsvCoder(ordered_columns, RAW_DATA_METADATA.schema)

      # Read in raw data and convert using CSV converter.  Note that we apply
      # some Beam transformations here, which will not be encoded in the TF
      # graph since we don't do them from within tf.Transform's methods
      # (AnalyzeDataset, TransformDataset etc.).  These transformations are just
      # to get data into a format that the CSV converter can read, in particular
      # removing spaces after commas.
      #
      # We use MapAndFilterErrors instead of Map to filter out decode errors in
      # convert.decode which should only occur for the trailing blank line.
      raw_data = (
          pipeline
          | 'ReadTrainData' >> beam.io.ReadFromText(train_data_file)
          | 'FixCommasTrainData' >> beam.Map(
              lambda line: line.replace(', ', ','))
          | 'DecodeTrainData' >> MapAndFilterErrors(converter.decode))

      # Combine data and schema into a dataset tuple.  Note that we already used
      # the schema to read the CSV data, but we also need it to interpret
      # raw_data.
      raw_dataset = (raw_data, RAW_DATA_METADATA)
      transformed_dataset, transform_fn = (
          raw_dataset | tft_beam.AnalyzeAndTransformDataset(preprocessing_fn))
      transformed_data, transformed_metadata = transformed_dataset
      transformed_data_coder = tft.coders.ExampleProtoCoder(
          transformed_metadata.schema)

      _ = (
          transformed_data
          | 'EncodeTrainData' >> beam.Map(transformed_data_coder.encode)
          | 'WriteTrainData' >> beam.io.WriteToTFRecord(
              os.path.join(working_dir, TRANSFORMED_TRAIN_DATA_FILEBASE)))

      # Now apply transform function to test data.  In this case we remove the
      # trailing period at the end of each line, and also ignore the header line
      # that is present in the test data file.
      raw_test_data = (
          pipeline
          | 'ReadTestData' >> beam.io.ReadFromText(test_data_file,
                                                   skip_header_lines=1)
          | 'FixCommasTestData' >> beam.Map(
              lambda line: line.replace(', ', ','))
          | 'RemoveTrailingPeriodsTestData' >> beam.Map(lambda line: line[:-1])
          | 'DecodeTestData' >> MapAndFilterErrors(converter.decode))

      raw_test_dataset = (raw_test_data, RAW_DATA_METADATA)

      transformed_test_dataset = (
          (raw_test_dataset, transform_fn) | tft_beam.TransformDataset())
      # Don't need transformed data schema, it's the same as before.
      transformed_test_data, _ = transformed_test_dataset

      _ = (
          transformed_test_data
          | 'EncodeTestData' >> beam.Map(transformed_data_coder.encode)
          | 'WriteTestData' >> beam.io.WriteToTFRecord(
              os.path.join(working_dir, TRANSFORMED_TEST_DATA_FILEBASE)))

      # Will write a SavedModel and metadata to working_dir, which can then
      # be read by the tft.TFTransformOutput class.
      _ = (
          transform_fn
          | 'WriteTransformFn' >> tft_beam.WriteTransformFn(working_dir))

Using our preprocessed data to train a model

To show how tf.Transform enables us to use the same code for both training and serving, and thus prevent skew, we're going to train a model. To train our model and prepare our trained model for production we need to create input functions. The main difference between our training input function and our serving input function is that training data contains the labels, and production data does not. The arguments and returns are also somewhat different.

Create an input function for training

def _make_training_input_fn(tf_transform_output, transformed_examples,
                            batch_size):
  """Creates an input function reading from transformed data.

  Args:
    tf_transform_output: Wrapper around output of tf.Transform.
    transformed_examples: Base filename of examples.
    batch_size: Batch size.

  Returns:
    The input function for training or eval.
  """
  def input_fn():
    """Input function for training and eval."""
    dataset = tf.data.experimental.make_batched_features_dataset(
        file_pattern=transformed_examples,
        batch_size=batch_size,
        features=tf_transform_output.transformed_feature_spec(),
        reader=tf.data.TFRecordDataset,
        shuffle=True)

    transformed_features = tf.compat.v1.data.make_one_shot_iterator(
        dataset).get_next()

    # Extract features and label from the transformed tensors.
    transformed_labels = transformed_features.pop(LABEL_KEY)

    return transformed_features, transformed_labels

  return input_fn

Create an input function for serving

Let's create an input function that we could use in production, and prepare our trained model for serving.

def _make_serving_input_fn(tf_transform_output):
  """Creates an input function reading from raw data.

  Args:
    tf_transform_output: Wrapper around output of tf.Transform.

  Returns:
    The serving input function.
  """
  raw_feature_spec = RAW_DATA_FEATURE_SPEC.copy()
  # Remove label since it is not available during serving.
  raw_feature_spec.pop(LABEL_KEY)

  def serving_input_fn():
    """Input function for serving."""
    # Get raw features by generating the basic serving input_fn and calling it.
    # Here we generate an input_fn that expects a parsed Example proto to be fed
    # to the model at serving time.  See also
    # tf.estimator.export.build_raw_serving_input_receiver_fn.
    raw_input_fn = tf.estimator.export.build_parsing_serving_input_receiver_fn(
        raw_feature_spec, default_batch_size=None)
    serving_input_receiver = raw_input_fn()

    # Apply the transform function that was used to generate the materialized
    # data.
    raw_features = serving_input_receiver.features
    transformed_features = tf_transform_output.transform_raw_features(
        raw_features)

    return tf.estimator.export.ServingInputReceiver(
        transformed_features, serving_input_receiver.receiver_tensors)

  return serving_input_fn

Wrap our input data in FeatureColumns

Our model will expect our data in TensorFlow FeatureColumns.

def get_feature_columns(tf_transform_output):
  """Returns the FeatureColumns for the model.

  Args:
    tf_transform_output: A `TFTransformOutput` object.

  Returns:
    A list of FeatureColumns.
  """
  # Wrap scalars as real valued columns.
  real_valued_columns = [tf.feature_column.numeric_column(key, shape=())
                         for key in NUMERIC_FEATURE_KEYS]

  # Wrap categorical columns.
  one_hot_columns = [
      tf.feature_column.categorical_column_with_vocabulary_file(
          key=key,
          vocabulary_file=tf_transform_output.vocabulary_file_by_name(
              vocab_filename=key))
      for key in CATEGORICAL_FEATURE_KEYS]

  return real_valued_columns + one_hot_columns

Train, Evaluate, and Export our model

def train_and_evaluate(working_dir, num_train_instances=NUM_TRAIN_INSTANCES,
                       num_test_instances=NUM_TEST_INSTANCES):
  """Train the model on training data and evaluate on test data.

  Args:
    working_dir: Directory to read transformed data and metadata from and to
        write exported model to.
    num_train_instances: Number of instances in train set
    num_test_instances: Number of instances in test set

  Returns:
    The results from the estimator's 'evaluate' method
  """
  tf_transform_output = tft.TFTransformOutput(working_dir)

  run_config = tf.estimator.RunConfig()

  estimator = tf.estimator.LinearClassifier(
      feature_columns=get_feature_columns(tf_transform_output),
      config=run_config,
      loss_reduction=tf.losses.Reduction.SUM)

  # Fit the model using the default optimizer.
  train_input_fn = _make_training_input_fn(
      tf_transform_output,
      os.path.join(working_dir, TRANSFORMED_TRAIN_DATA_FILEBASE + '*'),
      batch_size=TRAIN_BATCH_SIZE)
  estimator.train(
      input_fn=train_input_fn,
      max_steps=TRAIN_NUM_EPOCHS * num_train_instances / TRAIN_BATCH_SIZE)

  # Evaluate model on test dataset.
  eval_input_fn = _make_training_input_fn(
      tf_transform_output,
      os.path.join(working_dir, TRANSFORMED_TEST_DATA_FILEBASE + '*'),
      batch_size=1)

  # Export the model.
  serving_input_fn = _make_serving_input_fn(tf_transform_output)
  exported_model_dir = os.path.join(working_dir, EXPORTED_MODEL_DIR)
  estimator.export_saved_model(exported_model_dir, serving_input_fn)

  return estimator.evaluate(input_fn=eval_input_fn, steps=num_test_instances)

Put it all together

We've created all the stuff we need to preprocess our census data, train a model, and prepare it for serving. So far we've just been getting things ready. It's time to start running!

import tempfile
temp = tempfile.gettempdir()

transform_data(train, test, temp)
results = train_and_evaluate(temp)
pprint.pprint(results)
WARNING:tensorflow:Tensorflow version (2.1.0) found. Note that Tensorflow Transform support for TF 2.0 is currently in beta, and features such as tf.function may not work as intended. 

WARNING:tensorflow:Tensorflow version (2.1.0) found. Note that Tensorflow Transform support for TF 2.0 is currently in beta, and features such as tf.function may not work as intended. 

WARNING:tensorflow:Tensorflow version (2.1.0) found. Note that Tensorflow Transform support for TF 2.0 is currently in beta, and features such as tf.function may not work as intended. 

WARNING:tensorflow:Tensorflow version (2.1.0) found. Note that Tensorflow Transform support for TF 2.0 is currently in beta, and features such as tf.function may not work as intended. 

WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow_core/python/saved_model/signature_def_utils_impl.py:201: build_tensor_info (from tensorflow.python.saved_model.utils_impl) is deprecated and will be removed in a future version.
Instructions for updating:
This function will only be available through the v1 compatibility library as tf.compat.v1.saved_model.utils.build_tensor_info or tf.compat.v1.saved_model.build_tensor_info.

WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow_core/python/saved_model/signature_def_utils_impl.py:201: build_tensor_info (from tensorflow.python.saved_model.utils_impl) is deprecated and will be removed in a future version.
Instructions for updating:
This function will only be available through the v1 compatibility library as tf.compat.v1.saved_model.utils.build_tensor_info or tf.compat.v1.saved_model.build_tensor_info.

INFO:tensorflow:Assets added to graph.

INFO:tensorflow:Assets added to graph.

INFO:tensorflow:No assets to write.

INFO:tensorflow:No assets to write.

WARNING:tensorflow:Issue encountered when serializing tft_mapper_use.
Type is unsupported, or the types of the items don't match field type in CollectionDef. Note this is a warning and probably safe to ignore.
'Counter' object has no attribute 'name'

WARNING:tensorflow:Issue encountered when serializing tft_mapper_use.
Type is unsupported, or the types of the items don't match field type in CollectionDef. Note this is a warning and probably safe to ignore.
'Counter' object has no attribute 'name'

WARNING:tensorflow:Issue encountered when serializing tft_analyzer_use.
Type is unsupported, or the types of the items don't match field type in CollectionDef. Note this is a warning and probably safe to ignore.
'Counter' object has no attribute 'name'

WARNING:tensorflow:Issue encountered when serializing tft_analyzer_use.
Type is unsupported, or the types of the items don't match field type in CollectionDef. Note this is a warning and probably safe to ignore.
'Counter' object has no attribute 'name'

INFO:tensorflow:SavedModel written to: /tmp/tmpq3n0wbtl/tftransform_tmp/d61fd2eebed34ceb954037da1fdb6f7d/saved_model.pb

INFO:tensorflow:SavedModel written to: /tmp/tmpq3n0wbtl/tftransform_tmp/d61fd2eebed34ceb954037da1fdb6f7d/saved_model.pb

INFO:tensorflow:Assets added to graph.

INFO:tensorflow:Assets added to graph.

INFO:tensorflow:No assets to write.

INFO:tensorflow:No assets to write.

WARNING:tensorflow:Issue encountered when serializing tft_mapper_use.
Type is unsupported, or the types of the items don't match field type in CollectionDef. Note this is a warning and probably safe to ignore.
'Counter' object has no attribute 'name'

WARNING:tensorflow:Issue encountered when serializing tft_mapper_use.
Type is unsupported, or the types of the items don't match field type in CollectionDef. Note this is a warning and probably safe to ignore.
'Counter' object has no attribute 'name'

WARNING:tensorflow:Issue encountered when serializing tft_analyzer_use.
Type is unsupported, or the types of the items don't match field type in CollectionDef. Note this is a warning and probably safe to ignore.
'Counter' object has no attribute 'name'

WARNING:tensorflow:Issue encountered when serializing tft_analyzer_use.
Type is unsupported, or the types of the items don't match field type in CollectionDef. Note this is a warning and probably safe to ignore.
'Counter' object has no attribute 'name'

INFO:tensorflow:SavedModel written to: /tmp/tmpq3n0wbtl/tftransform_tmp/00252c42c400432ca25233333d3d7be8/saved_model.pb

INFO:tensorflow:SavedModel written to: /tmp/tmpq3n0wbtl/tftransform_tmp/00252c42c400432ca25233333d3d7be8/saved_model.pb

WARNING:tensorflow:Tensorflow version (2.1.0) found. Note that Tensorflow Transform support for TF 2.0 is currently in beta, and features such as tf.function may not work as intended. 

WARNING:tensorflow:Tensorflow version (2.1.0) found. Note that Tensorflow Transform support for TF 2.0 is currently in beta, and features such as tf.function may not work as intended. 

WARNING:tensorflow:Tensorflow version (2.1.0) found. Note that Tensorflow Transform support for TF 2.0 is currently in beta, and features such as tf.function may not work as intended. 

WARNING:tensorflow:Tensorflow version (2.1.0) found. Note that Tensorflow Transform support for TF 2.0 is currently in beta, and features such as tf.function may not work as intended. 

INFO:tensorflow:Saver not created because there are no variables in the graph to restore

INFO:tensorflow:Saver not created because there are no variables in the graph to restore

INFO:tensorflow:Saver not created because there are no variables in the graph to restore

INFO:tensorflow:Saver not created because there are no variables in the graph to restore

INFO:tensorflow:Assets added to graph.

INFO:tensorflow:Assets added to graph.

INFO:tensorflow:Assets written to: /tmp/tmpq3n0wbtl/tftransform_tmp/24eb845d436c4d4a8f303b9cb05ab3d1/assets

INFO:tensorflow:Assets written to: /tmp/tmpq3n0wbtl/tftransform_tmp/24eb845d436c4d4a8f303b9cb05ab3d1/assets

INFO:tensorflow:SavedModel written to: /tmp/tmpq3n0wbtl/tftransform_tmp/24eb845d436c4d4a8f303b9cb05ab3d1/saved_model.pb

INFO:tensorflow:SavedModel written to: /tmp/tmpq3n0wbtl/tftransform_tmp/24eb845d436c4d4a8f303b9cb05ab3d1/saved_model.pb

WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef"
value: "\n\014\n\nConst_11:0\022\tworkclass"


WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef"
value: "\n\014\n\nConst_11:0\022\tworkclass"


WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef"
value: "\n\014\n\nConst_13:0\022\teducation"


WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef"
value: "\n\014\n\nConst_13:0\022\teducation"


WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef"
value: "\n\014\n\nConst_15:0\022\016marital-status"


WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef"
value: "\n\014\n\nConst_15:0\022\016marital-status"


WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef"
value: "\n\014\n\nConst_17:0\022\noccupation"


WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef"
value: "\n\014\n\nConst_17:0\022\noccupation"


WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef"
value: "\n\014\n\nConst_19:0\022\014relationship"


WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef"
value: "\n\014\n\nConst_19:0\022\014relationship"


WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef"
value: "\n\014\n\nConst_21:0\022\004race"


WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef"
value: "\n\014\n\nConst_21:0\022\004race"


WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef"
value: "\n\014\n\nConst_23:0\022\003sex"


WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef"
value: "\n\014\n\nConst_23:0\022\003sex"


WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef"
value: "\n\014\n\nConst_25:0\022\016native-country"


WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef"
value: "\n\014\n\nConst_25:0\022\016native-country"


INFO:tensorflow:Saver not created because there are no variables in the graph to restore

INFO:tensorflow:Saver not created because there are no variables in the graph to restore

WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef"
value: "\n\014\n\nConst_11:0\022\tworkclass"


WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef"
value: "\n\014\n\nConst_11:0\022\tworkclass"


WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef"
value: "\n\014\n\nConst_13:0\022\teducation"


WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef"
value: "\n\014\n\nConst_13:0\022\teducation"


WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef"
value: "\n\014\n\nConst_15:0\022\016marital-status"


WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef"
value: "\n\014\n\nConst_15:0\022\016marital-status"


WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef"
value: "\n\014\n\nConst_17:0\022\noccupation"


WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef"
value: "\n\014\n\nConst_17:0\022\noccupation"


WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef"
value: "\n\014\n\nConst_19:0\022\014relationship"


WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef"
value: "\n\014\n\nConst_19:0\022\014relationship"


WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef"
value: "\n\014\n\nConst_21:0\022\004race"


WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef"
value: "\n\014\n\nConst_21:0\022\004race"


WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef"
value: "\n\014\n\nConst_23:0\022\003sex"


WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef"
value: "\n\014\n\nConst_23:0\022\003sex"


WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef"
value: "\n\014\n\nConst_25:0\022\016native-country"


WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef"
value: "\n\014\n\nConst_25:0\022\016native-country"


INFO:tensorflow:Saver not created because there are no variables in the graph to restore

INFO:tensorflow:Saver not created because there are no variables in the graph to restore
WARNING:root:Couldn't find python-snappy so the implementation of _TFRecordUtil._masked_crc32c is not as fast as it could be.

WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef"
value: "\n\014\n\nConst_11:0\022\tworkclass"


WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef"
value: "\n\014\n\nConst_11:0\022\tworkclass"


WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef"
value: "\n\014\n\nConst_13:0\022\teducation"


WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef"
value: "\n\014\n\nConst_13:0\022\teducation"


WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef"
value: "\n\014\n\nConst_15:0\022\016marital-status"


WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef"
value: "\n\014\n\nConst_15:0\022\016marital-status"


WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef"
value: "\n\014\n\nConst_17:0\022\noccupation"


WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef"
value: "\n\014\n\nConst_17:0\022\noccupation"


WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef"
value: "\n\014\n\nConst_19:0\022\014relationship"


WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef"
value: "\n\014\n\nConst_19:0\022\014relationship"


WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef"
value: "\n\014\n\nConst_21:0\022\004race"


WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef"
value: "\n\014\n\nConst_21:0\022\004race"


WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef"
value: "\n\014\n\nConst_23:0\022\003sex"


WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef"
value: "\n\014\n\nConst_23:0\022\003sex"


WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef"
value: "\n\014\n\nConst_25:0\022\016native-country"


WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef"
value: "\n\014\n\nConst_25:0\022\016native-country"


INFO:tensorflow:Saver not created because there are no variables in the graph to restore

INFO:tensorflow:Saver not created because there are no variables in the graph to restore

INFO:tensorflow:vocabulary_size = 9 in workclass is inferred from the number of elements in the vocabulary_file /tmp/transform_fn/assets/workclass.

INFO:tensorflow:vocabulary_size = 9 in workclass is inferred from the number of elements in the vocabulary_file /tmp/transform_fn/assets/workclass.

INFO:tensorflow:vocabulary_size = 16 in education is inferred from the number of elements in the vocabulary_file /tmp/transform_fn/assets/education.

INFO:tensorflow:vocabulary_size = 16 in education is inferred from the number of elements in the vocabulary_file /tmp/transform_fn/assets/education.

INFO:tensorflow:vocabulary_size = 7 in marital-status is inferred from the number of elements in the vocabulary_file /tmp/transform_fn/assets/marital-status.

INFO:tensorflow:vocabulary_size = 7 in marital-status is inferred from the number of elements in the vocabulary_file /tmp/transform_fn/assets/marital-status.

INFO:tensorflow:vocabulary_size = 15 in occupation is inferred from the number of elements in the vocabulary_file /tmp/transform_fn/assets/occupation.

INFO:tensorflow:vocabulary_size = 15 in occupation is inferred from the number of elements in the vocabulary_file /tmp/transform_fn/assets/occupation.

INFO:tensorflow:vocabulary_size = 6 in relationship is inferred from the number of elements in the vocabulary_file /tmp/transform_fn/assets/relationship.

INFO:tensorflow:vocabulary_size = 6 in relationship is inferred from the number of elements in the vocabulary_file /tmp/transform_fn/assets/relationship.

INFO:tensorflow:vocabulary_size = 5 in race is inferred from the number of elements in the vocabulary_file /tmp/transform_fn/assets/race.

INFO:tensorflow:vocabulary_size = 5 in race is inferred from the number of elements in the vocabulary_file /tmp/transform_fn/assets/race.

INFO:tensorflow:vocabulary_size = 2 in sex is inferred from the number of elements in the vocabulary_file /tmp/transform_fn/assets/sex.

INFO:tensorflow:vocabulary_size = 2 in sex is inferred from the number of elements in the vocabulary_file /tmp/transform_fn/assets/sex.

INFO:tensorflow:vocabulary_size = 42 in native-country is inferred from the number of elements in the vocabulary_file /tmp/transform_fn/assets/native-country.

INFO:tensorflow:vocabulary_size = 42 in native-country is inferred from the number of elements in the vocabulary_file /tmp/transform_fn/assets/native-country.

WARNING:tensorflow:Using temporary folder as model directory: /tmp/tmpvn3c76q9

WARNING:tensorflow:Using temporary folder as model directory: /tmp/tmpvn3c76q9

INFO:tensorflow:Using config: {'_model_dir': '/tmp/tmpvn3c76q9', '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_save_checkpoints_secs': 600, '_session_config': allow_soft_placement: true
graph_options {
  rewrite_options {
    meta_optimizer_iterations: ONE
  }
}
, '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_log_step_count_steps': 100, '_train_distribute': None, '_device_fn': None, '_protocol': None, '_eval_distribute': None, '_experimental_distribute': None, '_experimental_max_worker_delay_secs': None, '_session_creation_timeout_secs': 7200, '_service': None, '_cluster_spec': ClusterSpec({}), '_task_type': 'worker', '_task_id': 0, '_global_id_in_cluster': 0, '_master': '', '_evaluation_master': '', '_is_chief': True, '_num_ps_replicas': 0, '_num_worker_replicas': 1}

INFO:tensorflow:Using config: {'_model_dir': '/tmp/tmpvn3c76q9', '_tf_random_seed': None, '_save_summary_steps': 100, '_save_checkpoints_steps': None, '_save_checkpoints_secs': 600, '_session_config': allow_soft_placement: true
graph_options {
  rewrite_options {
    meta_optimizer_iterations: ONE
  }
}
, '_keep_checkpoint_max': 5, '_keep_checkpoint_every_n_hours': 10000, '_log_step_count_steps': 100, '_train_distribute': None, '_device_fn': None, '_protocol': None, '_eval_distribute': None, '_experimental_distribute': None, '_experimental_max_worker_delay_secs': None, '_session_creation_timeout_secs': 7200, '_service': None, '_cluster_spec': ClusterSpec({}), '_task_type': 'worker', '_task_id': 0, '_global_id_in_cluster': 0, '_master': '', '_evaluation_master': '', '_is_chief': True, '_num_ps_replicas': 0, '_num_worker_replicas': 1}

WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow_core/python/ops/resource_variable_ops.py:1635: calling BaseResourceVariable.__init__ (from tensorflow.python.ops.resource_variable_ops) with constraint is deprecated and will be removed in a future version.
Instructions for updating:
If using Keras pass *_constraint arguments to layers.

WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow_core/python/ops/resource_variable_ops.py:1635: calling BaseResourceVariable.__init__ (from tensorflow.python.ops.resource_variable_ops) with constraint is deprecated and will be removed in a future version.
Instructions for updating:
If using Keras pass *_constraint arguments to layers.

WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow_core/python/training/training_util.py:236: Variable.initialized_value (from tensorflow.python.ops.variables) is deprecated and will be removed in a future version.
Instructions for updating:
Use Variable.read_value. Variables in 2.X are initialized automatically both in eager and graph (inside tf.defun) contexts.

WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow_core/python/training/training_util.py:236: Variable.initialized_value (from tensorflow.python.ops.variables) is deprecated and will be removed in a future version.
Instructions for updating:
Use Variable.read_value. Variables in 2.X are initialized automatically both in eager and graph (inside tf.defun) contexts.

INFO:tensorflow:Calling model_fn.

INFO:tensorflow:Calling model_fn.

WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow_core/python/feature_column/feature_column_v2.py:518: Layer.add_variable (from tensorflow.python.keras.engine.base_layer) is deprecated and will be removed in a future version.
Instructions for updating:
Please use `layer.add_weight` method instead.

WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow_core/python/feature_column/feature_column_v2.py:518: Layer.add_variable (from tensorflow.python.keras.engine.base_layer) is deprecated and will be removed in a future version.
Instructions for updating:
Please use `layer.add_weight` method instead.

WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow_core/python/keras/optimizer_v2/ftrl.py:143: calling Constant.__init__ (from tensorflow.python.ops.init_ops) with dtype is deprecated and will be removed in a future version.
Instructions for updating:
Call initializer instance with the dtype argument instead of passing it to the constructor

WARNING:tensorflow:From /tmpfs/src/tf_docs_env/lib/python3.6/site-packages/tensorflow_core/python/keras/optimizer_v2/ftrl.py:143: calling Constant.__init__ (from tensorflow.python.ops.init_ops) with dtype is deprecated and will be removed in a future version.
Instructions for updating:
Call initializer instance with the dtype argument instead of passing it to the constructor

INFO:tensorflow:Done calling model_fn.

INFO:tensorflow:Done calling model_fn.

INFO:tensorflow:Create CheckpointSaverHook.

INFO:tensorflow:Create CheckpointSaverHook.

INFO:tensorflow:Graph was finalized.

INFO:tensorflow:Graph was finalized.

INFO:tensorflow:Running local_init_op.

INFO:tensorflow:Running local_init_op.

INFO:tensorflow:Done running local_init_op.

INFO:tensorflow:Done running local_init_op.

INFO:tensorflow:Saving checkpoints for 0 into /tmp/tmpvn3c76q9/model.ckpt.

INFO:tensorflow:Saving checkpoints for 0 into /tmp/tmpvn3c76q9/model.ckpt.

INFO:tensorflow:loss = 88.72284, step = 0

INFO:tensorflow:loss = 88.72284, step = 0

INFO:tensorflow:global_step/sec: 89.6449

INFO:tensorflow:global_step/sec: 89.6449

INFO:tensorflow:loss = 42.527027, step = 100 (1.117 sec)

INFO:tensorflow:loss = 42.527027, step = 100 (1.117 sec)

INFO:tensorflow:global_step/sec: 135.203

INFO:tensorflow:global_step/sec: 135.203

INFO:tensorflow:loss = 38.974457, step = 200 (0.740 sec)

INFO:tensorflow:loss = 38.974457, step = 200 (0.740 sec)

INFO:tensorflow:global_step/sec: 133.595

INFO:tensorflow:global_step/sec: 133.595

INFO:tensorflow:loss = 47.43437, step = 300 (0.748 sec)

INFO:tensorflow:loss = 47.43437, step = 300 (0.748 sec)

INFO:tensorflow:global_step/sec: 138.003

INFO:tensorflow:global_step/sec: 138.003

INFO:tensorflow:loss = 34.12556, step = 400 (0.725 sec)

INFO:tensorflow:loss = 34.12556, step = 400 (0.725 sec)

INFO:tensorflow:global_step/sec: 137.888

INFO:tensorflow:global_step/sec: 137.888

INFO:tensorflow:loss = 42.49637, step = 500 (0.725 sec)

INFO:tensorflow:loss = 42.49637, step = 500 (0.725 sec)

INFO:tensorflow:global_step/sec: 134.74

INFO:tensorflow:global_step/sec: 134.74

INFO:tensorflow:loss = 40.648438, step = 600 (0.742 sec)

INFO:tensorflow:loss = 40.648438, step = 600 (0.742 sec)

INFO:tensorflow:global_step/sec: 137.887

INFO:tensorflow:global_step/sec: 137.887

INFO:tensorflow:loss = 47.19397, step = 700 (0.726 sec)

INFO:tensorflow:loss = 47.19397, step = 700 (0.726 sec)

INFO:tensorflow:global_step/sec: 127.706

INFO:tensorflow:global_step/sec: 127.706

INFO:tensorflow:loss = 42.183193, step = 800 (0.783 sec)

INFO:tensorflow:loss = 42.183193, step = 800 (0.783 sec)

INFO:tensorflow:global_step/sec: 135.462

INFO:tensorflow:global_step/sec: 135.462

INFO:tensorflow:loss = 44.42933, step = 900 (0.738 sec)

INFO:tensorflow:loss = 44.42933, step = 900 (0.738 sec)

INFO:tensorflow:global_step/sec: 137.593

INFO:tensorflow:global_step/sec: 137.593

INFO:tensorflow:loss = 40.835323, step = 1000 (0.727 sec)

INFO:tensorflow:loss = 40.835323, step = 1000 (0.727 sec)

INFO:tensorflow:global_step/sec: 135.45

INFO:tensorflow:global_step/sec: 135.45

INFO:tensorflow:loss = 52.125065, step = 1100 (0.738 sec)

INFO:tensorflow:loss = 52.125065, step = 1100 (0.738 sec)

INFO:tensorflow:global_step/sec: 138.413

INFO:tensorflow:global_step/sec: 138.413

INFO:tensorflow:loss = 45.659092, step = 1200 (0.723 sec)

INFO:tensorflow:loss = 45.659092, step = 1200 (0.723 sec)

INFO:tensorflow:global_step/sec: 137.423

INFO:tensorflow:global_step/sec: 137.423

INFO:tensorflow:loss = 43.212368, step = 1300 (0.727 sec)

INFO:tensorflow:loss = 43.212368, step = 1300 (0.727 sec)

INFO:tensorflow:global_step/sec: 132.671

INFO:tensorflow:global_step/sec: 132.671

INFO:tensorflow:loss = 32.971313, step = 1400 (0.754 sec)

INFO:tensorflow:loss = 32.971313, step = 1400 (0.754 sec)

INFO:tensorflow:global_step/sec: 135.912

INFO:tensorflow:global_step/sec: 135.912

INFO:tensorflow:loss = 42.14589, step = 1500 (0.736 sec)

INFO:tensorflow:loss = 42.14589, step = 1500 (0.736 sec)

INFO:tensorflow:global_step/sec: 136.174

INFO:tensorflow:global_step/sec: 136.174

INFO:tensorflow:loss = 38.87826, step = 1600 (0.734 sec)

INFO:tensorflow:loss = 38.87826, step = 1600 (0.734 sec)

INFO:tensorflow:global_step/sec: 137.64

INFO:tensorflow:global_step/sec: 137.64

INFO:tensorflow:loss = 43.75579, step = 1700 (0.727 sec)

INFO:tensorflow:loss = 43.75579, step = 1700 (0.727 sec)

INFO:tensorflow:global_step/sec: 137.195

INFO:tensorflow:global_step/sec: 137.195

INFO:tensorflow:loss = 36.857105, step = 1800 (0.728 sec)

INFO:tensorflow:loss = 36.857105, step = 1800 (0.728 sec)

INFO:tensorflow:global_step/sec: 138.421

INFO:tensorflow:global_step/sec: 138.421

INFO:tensorflow:loss = 39.2769, step = 1900 (0.723 sec)

INFO:tensorflow:loss = 39.2769, step = 1900 (0.723 sec)

INFO:tensorflow:global_step/sec: 135.221

INFO:tensorflow:global_step/sec: 135.221

INFO:tensorflow:loss = 42.389717, step = 2000 (0.739 sec)

INFO:tensorflow:loss = 42.389717, step = 2000 (0.739 sec)

INFO:tensorflow:global_step/sec: 134.692

INFO:tensorflow:global_step/sec: 134.692

INFO:tensorflow:loss = 33.44703, step = 2100 (0.742 sec)

INFO:tensorflow:loss = 33.44703, step = 2100 (0.742 sec)

INFO:tensorflow:global_step/sec: 137.559

INFO:tensorflow:global_step/sec: 137.559

INFO:tensorflow:loss = 56.24582, step = 2200 (0.727 sec)

INFO:tensorflow:loss = 56.24582, step = 2200 (0.727 sec)

INFO:tensorflow:global_step/sec: 135.272

INFO:tensorflow:global_step/sec: 135.272

INFO:tensorflow:loss = 43.708702, step = 2300 (0.739 sec)

INFO:tensorflow:loss = 43.708702, step = 2300 (0.739 sec)

INFO:tensorflow:global_step/sec: 135.415

INFO:tensorflow:global_step/sec: 135.415

INFO:tensorflow:loss = 40.199203, step = 2400 (0.738 sec)

INFO:tensorflow:loss = 40.199203, step = 2400 (0.738 sec)

INFO:tensorflow:global_step/sec: 137.898

INFO:tensorflow:global_step/sec: 137.898

INFO:tensorflow:loss = 37.231125, step = 2500 (0.725 sec)

INFO:tensorflow:loss = 37.231125, step = 2500 (0.725 sec)

INFO:tensorflow:global_step/sec: 137.37

INFO:tensorflow:global_step/sec: 137.37

INFO:tensorflow:loss = 44.53855, step = 2600 (0.728 sec)

INFO:tensorflow:loss = 44.53855, step = 2600 (0.728 sec)

INFO:tensorflow:global_step/sec: 138.513

INFO:tensorflow:global_step/sec: 138.513

INFO:tensorflow:loss = 43.540504, step = 2700 (0.722 sec)

INFO:tensorflow:loss = 43.540504, step = 2700 (0.722 sec)

INFO:tensorflow:global_step/sec: 136.577

INFO:tensorflow:global_step/sec: 136.577

INFO:tensorflow:loss = 46.320267, step = 2800 (0.732 sec)

INFO:tensorflow:loss = 46.320267, step = 2800 (0.732 sec)

INFO:tensorflow:global_step/sec: 122.648

INFO:tensorflow:global_step/sec: 122.648

INFO:tensorflow:loss = 38.94274, step = 2900 (0.816 sec)

INFO:tensorflow:loss = 38.94274, step = 2900 (0.816 sec)

INFO:tensorflow:global_step/sec: 130.974

INFO:tensorflow:global_step/sec: 130.974

INFO:tensorflow:loss = 48.406227, step = 3000 (0.763 sec)

INFO:tensorflow:loss = 48.406227, step = 3000 (0.763 sec)

INFO:tensorflow:global_step/sec: 137.393

INFO:tensorflow:global_step/sec: 137.393

INFO:tensorflow:loss = 37.249023, step = 3100 (0.728 sec)

INFO:tensorflow:loss = 37.249023, step = 3100 (0.728 sec)

INFO:tensorflow:global_step/sec: 138.718

INFO:tensorflow:global_step/sec: 138.718

INFO:tensorflow:loss = 30.367504, step = 3200 (0.721 sec)

INFO:tensorflow:loss = 30.367504, step = 3200 (0.721 sec)

INFO:tensorflow:global_step/sec: 137.343

INFO:tensorflow:global_step/sec: 137.343

INFO:tensorflow:loss = 36.423523, step = 3300 (0.728 sec)

INFO:tensorflow:loss = 36.423523, step = 3300 (0.728 sec)

INFO:tensorflow:global_step/sec: 137.35

INFO:tensorflow:global_step/sec: 137.35

INFO:tensorflow:loss = 53.913994, step = 3400 (0.728 sec)

INFO:tensorflow:loss = 53.913994, step = 3400 (0.728 sec)

INFO:tensorflow:global_step/sec: 139.907

INFO:tensorflow:global_step/sec: 139.907

INFO:tensorflow:loss = 45.978683, step = 3500 (0.715 sec)

INFO:tensorflow:loss = 45.978683, step = 3500 (0.715 sec)

INFO:tensorflow:global_step/sec: 139.229

INFO:tensorflow:global_step/sec: 139.229

INFO:tensorflow:loss = 39.210682, step = 3600 (0.718 sec)

INFO:tensorflow:loss = 39.210682, step = 3600 (0.718 sec)

INFO:tensorflow:global_step/sec: 139.424

INFO:tensorflow:global_step/sec: 139.424

INFO:tensorflow:loss = 45.84509, step = 3700 (0.717 sec)

INFO:tensorflow:loss = 45.84509, step = 3700 (0.717 sec)

INFO:tensorflow:global_step/sec: 135.949

INFO:tensorflow:global_step/sec: 135.949

INFO:tensorflow:loss = 43.196827, step = 3800 (0.735 sec)

INFO:tensorflow:loss = 43.196827, step = 3800 (0.735 sec)

INFO:tensorflow:global_step/sec: 137.88

INFO:tensorflow:global_step/sec: 137.88

INFO:tensorflow:loss = 35.705696, step = 3900 (0.725 sec)

INFO:tensorflow:loss = 35.705696, step = 3900 (0.725 sec)

INFO:tensorflow:global_step/sec: 137.85

INFO:tensorflow:global_step/sec: 137.85

INFO:tensorflow:loss = 29.844383, step = 4000 (0.726 sec)

INFO:tensorflow:loss = 29.844383, step = 4000 (0.726 sec)

INFO:tensorflow:Saving checkpoints for 4071 into /tmp/tmpvn3c76q9/model.ckpt.

INFO:tensorflow:Saving checkpoints for 4071 into /tmp/tmpvn3c76q9/model.ckpt.

INFO:tensorflow:Loss for final step: 42.353493.

INFO:tensorflow:Loss for final step: 42.353493.

WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef"
value: "\n\014\n\nConst_11:0\022\tworkclass"


WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef"
value: "\n\014\n\nConst_11:0\022\tworkclass"


WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef"
value: "\n\014\n\nConst_13:0\022\teducation"


WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef"
value: "\n\014\n\nConst_13:0\022\teducation"


WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef"
value: "\n\014\n\nConst_15:0\022\016marital-status"


WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef"
value: "\n\014\n\nConst_15:0\022\016marital-status"


WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef"
value: "\n\014\n\nConst_17:0\022\noccupation"


WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef"
value: "\n\014\n\nConst_17:0\022\noccupation"


WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef"
value: "\n\014\n\nConst_19:0\022\014relationship"


WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef"
value: "\n\014\n\nConst_19:0\022\014relationship"


WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef"
value: "\n\014\n\nConst_21:0\022\004race"


WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef"
value: "\n\014\n\nConst_21:0\022\004race"


WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef"
value: "\n\014\n\nConst_23:0\022\003sex"


WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef"
value: "\n\014\n\nConst_23:0\022\003sex"


WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef"
value: "\n\014\n\nConst_25:0\022\016native-country"


WARNING:tensorflow:Expected binary or unicode string, got type_url: "type.googleapis.com/tensorflow.AssetFileDef"
value: "\n\014\n\nConst_25:0\022\016native-country"


INFO:tensorflow:Saver not created because there are no variables in the graph to restore

INFO:tensorflow:Saver not created because there are no variables in the graph to restore

INFO:tensorflow:Calling model_fn.

INFO:tensorflow:Calling model_fn.

INFO:tensorflow:Done calling model_fn.

INFO:tensorflow:Done calling model_fn.

INFO:tensorflow:Signatures INCLUDED in export for Classify: ['serving_default', 'classification']

INFO:tensorflow:Signatures INCLUDED in export for Classify: ['serving_default', 'classification']

INFO:tensorflow:Signatures INCLUDED in export for Regress: ['regression']

INFO:tensorflow:Signatures INCLUDED in export for Regress: ['regression']

INFO:tensorflow:Signatures INCLUDED in export for Predict: ['predict']

INFO:tensorflow:Signatures INCLUDED in export for Predict: ['predict']

INFO:tensorflow:Signatures INCLUDED in export for Train: None

INFO:tensorflow:Signatures INCLUDED in export for Train: None

INFO:tensorflow:Signatures INCLUDED in export for Eval: None

INFO:tensorflow:Signatures INCLUDED in export for Eval: None

INFO:tensorflow:Restoring parameters from /tmp/tmpvn3c76q9/model.ckpt-4071

INFO:tensorflow:Restoring parameters from /tmp/tmpvn3c76q9/model.ckpt-4071

INFO:tensorflow:Assets added to graph.

INFO:tensorflow:Assets added to graph.

INFO:tensorflow:Assets written to: /tmp/exported_model_dir/temp-b'1582570234'/assets

INFO:tensorflow:Assets written to: /tmp/exported_model_dir/temp-b'1582570234'/assets

INFO:tensorflow:SavedModel written to: /tmp/exported_model_dir/temp-b'1582570234'/saved_model.pb

INFO:tensorflow:SavedModel written to: /tmp/exported_model_dir/temp-b'1582570234'/saved_model.pb

INFO:tensorflow:Calling model_fn.

INFO:tensorflow:Calling model_fn.

INFO:tensorflow:Done calling model_fn.

INFO:tensorflow:Done calling model_fn.

INFO:tensorflow:Starting evaluation at 2020-02-24T18:50:36Z

INFO:tensorflow:Starting evaluation at 2020-02-24T18:50:36Z

INFO:tensorflow:Graph was finalized.

INFO:tensorflow:Graph was finalized.

INFO:tensorflow:Restoring parameters from /tmp/tmpvn3c76q9/model.ckpt-4071

INFO:tensorflow:Restoring parameters from /tmp/tmpvn3c76q9/model.ckpt-4071

INFO:tensorflow:Running local_init_op.

INFO:tensorflow:Running local_init_op.

INFO:tensorflow:Done running local_init_op.

INFO:tensorflow:Done running local_init_op.

INFO:tensorflow:Evaluation [1628/16281]

INFO:tensorflow:Evaluation [1628/16281]

INFO:tensorflow:Evaluation [3256/16281]

INFO:tensorflow:Evaluation [3256/16281]

INFO:tensorflow:Evaluation [4884/16281]

INFO:tensorflow:Evaluation [4884/16281]

INFO:tensorflow:Evaluation [6512/16281]

INFO:tensorflow:Evaluation [6512/16281]

INFO:tensorflow:Evaluation [8140/16281]

INFO:tensorflow:Evaluation [8140/16281]

INFO:tensorflow:Evaluation [9768/16281]

INFO:tensorflow:Evaluation [9768/16281]

INFO:tensorflow:Evaluation [11396/16281]

INFO:tensorflow:Evaluation [11396/16281]

INFO:tensorflow:Evaluation [13024/16281]

INFO:tensorflow:Evaluation [13024/16281]

INFO:tensorflow:Evaluation [14652/16281]

INFO:tensorflow:Evaluation [14652/16281]

INFO:tensorflow:Evaluation [16280/16281]

INFO:tensorflow:Evaluation [16280/16281]

INFO:tensorflow:Evaluation [16281/16281]

INFO:tensorflow:Evaluation [16281/16281]

INFO:tensorflow:Inference Time : 115.13543s

INFO:tensorflow:Inference Time : 115.13543s

INFO:tensorflow:Finished evaluation at 2020-02-24-18:52:31

INFO:tensorflow:Finished evaluation at 2020-02-24-18:52:31

INFO:tensorflow:Saving dict for global step 4071: accuracy = 0.84964067, accuracy_baseline = 0.76377374, auc = 0.9016459, auc_precision_recall = 0.9671172, average_loss = 0.32451206, global_step = 4071, label/mean = 0.76377374, loss = 0.32451206, precision = 0.87401694, prediction/mean = 0.77111423, recall = 0.9383997

INFO:tensorflow:Saving dict for global step 4071: accuracy = 0.84964067, accuracy_baseline = 0.76377374, auc = 0.9016459, auc_precision_recall = 0.9671172, average_loss = 0.32451206, global_step = 4071, label/mean = 0.76377374, loss = 0.32451206, precision = 0.87401694, prediction/mean = 0.77111423, recall = 0.9383997

INFO:tensorflow:Saving 'checkpoint_path' summary for global step 4071: /tmp/tmpvn3c76q9/model.ckpt-4071

INFO:tensorflow:Saving 'checkpoint_path' summary for global step 4071: /tmp/tmpvn3c76q9/model.ckpt-4071

{'accuracy': 0.84964067,
 'accuracy_baseline': 0.76377374,
 'auc': 0.9016459,
 'auc_precision_recall': 0.9671172,
 'average_loss': 0.32451206,
 'global_step': 4071,
 'label/mean': 0.76377374,
 'loss': 0.32451206,
 'precision': 0.87401694,
 'prediction/mean': 0.77111423,
 'recall': 0.9383997}

What we did

In this example we used tf.Transform to preprocess a dataset of census data, and train a model with the cleaned and transformed data. We also created an input function that we could use when we deploy our trained model in a production environment to perform inference. By using the same code for both training and inference we avoid any issues with data skew. Along the way we learned about creating an Apache Beam transform to perform the transformation that we needed for cleaning the data, and wrapped our data in TensorFlow FeatureColumns. This is just a small piece of what TensorFlow Transform can do! We encourage you to dive into tf.Transform and discover what it can do for you.