The Census Income Data Set contains over 48,000 samples with attributes including age, occupation, education, and income (a binary label, either >50K
or <=50K
). The dataset is split into roughly 32,000 training and 16,000 testing samples.
Here, we use the wide and deep model to predict the income labels. The wide model is able to memorize interactions with data with a large number of features but not able to generalize these learned interactions on new data. The deep model generalizes well but is unable to learn exceptions within the data. The wide and deep model combines the two models and is able to generalize while learning exceptions.
For the purposes of this example code, the Census Income Data Set was chosen to allow the model to train in a reasonable amount of time. You'll notice that the deep model performs almost as well as the wide and deep model on this dataset. The wide and deep model truly shines on larger data sets with high-cardinality features, where each feature has millions/billions of unique possible values (which is the specialty of the wide model).
Finally, a key point. As a modeler and developer, think about how this dataset is used and the potential benefits and harm a model's predictions can cause. A model like this could reinforce societal biases and disparities. Is a feature relevant to the problem you want to solve, or will it introduce bias? For more information, read about ML fairness.
The code sample in this directory uses the high level tf.estimator.Estimator
API. This API is great for fast iteration and quickly adapting models to your own datasets without major code overhauls. It allows you to move from single-worker training to distributed training, and it makes it easy to export model binaries for prediction.
The input function for the Estimator
uses tf.contrib.data.TextLineDataset
, which creates a Dataset
object. The Dataset
API makes it easy to apply transformations (map, batch, shuffle, etc.) to the data. Read more here.
The Estimator
and Dataset
APIs are both highly encouraged for fast development and efficient training.
First make sure you've added the models folder to your Python path; otherwise you may encounter an error like ImportError: No module named official.wide_deep
.
The Census Income Data Set that this sample uses for training is hosted by the UC Irvine Machine Learning Repository. We have provided a script that downloads and cleans the necessary files.
python census_dataset.py
This will download the files to /tmp/census_data
. To change the directory, set the --data_dir
flag.
You can run the code locally as follows:
python census_main.py
The model is saved to /tmp/census_model
by default, which can be changed using the --model_dir
flag.
To run the wide or deep-only models, set the --model_type
flag to wide
or deep
. Other flags are configurable as well; see census_main.py
for details.
The final accuracy should be over 83% with any of the three model types.
You can also experiment with -inter
and -intra
flag to explore inter/intra op parallelism for potential better performance as follows:
python census_main.py --inter=<int> --intra=<int>
Please note the above optional inter/intra op does not affect model accuracy. These are TensorFlow framework configurations that only affect execution time. For more details regarding the above inter/intra flags, please refer to Optimizing_for_CPU or TensorFlow config.proto source code.
Run TensorBoard to inspect the details about the graph and training progression.
tensorboard --logdir=/tmp/census_model
You can export the model into Tensorflow SavedModel format by using the argument --export_dir
:
python census_main.py --export_dir /tmp/wide_deep_saved_model
After the model finishes training, use saved_model_cli
to inspect and execute the SavedModel.
Try the following commands to inspect the SavedModel:
Replace ${TIMESTAMP}
with the folder produced (e.g. 1524249124)
# List possible tag_sets. Only one metagraph is saved, so there will be one option.
saved_model_cli show --dir /tmp/wide_deep_saved_model/${TIMESTAMP}/
# Show SignatureDefs for tag_set=serve. SignatureDefs define the outputs to show.
saved_model_cli show --dir /tmp/wide_deep_saved_model/${TIMESTAMP}/ \
--tag_set serve --all
Let's use the model to predict the income group of two examples:
saved_model_cli run --dir /tmp/wide_deep_saved_model/${TIMESTAMP}/ \
--tag_set serve --signature_def="predict" \
--input_examples='examples=[{"age":[46.], "education_num":[10.], "capital_gain":[7688.], "capital_loss":[0.], "hours_per_week":[38.]}, {"age":[24.], "education_num":[13.], "capital_gain":[0.], "capital_loss":[0.], "hours_per_week":[50.]}]'
This will print out the predicted classes and class probabilities. Class 0 is the <=50k group and 1 is the >50k group.
If you are interested in distributed training, take a look at Distributed TensorFlow.
You can also run this model on Cloud ML Engine, which provides hyperparameter tuning to maximize your model's results and enables deploying your model for prediction.