TFX + Apache Airflow + TensorFlow Serving
An end-to-end Machine Learning pipeline built using TensorFlow Extended (TFX) and Apache Airflow to predict whether an individual's income exceeds $50K per year based on census data.
This repository contains a production-ready MLOps pipeline orchestrated with Apache Airflow.
The workflow handles:
- Data ingestion
- Feature preprocessing using
tf.Transform - Deep neural network training with Keras embeddings
- Model evaluation
- Model serving with TensorFlow Serving
- Experiment tracking with TensorBoard
-
Automated Data Ingestion Loads raw census data dynamically using TFX
ExampleGen. -
Feature Preprocessing (
tf.Transform) Applies Z-score normalization to continuous numeric features and dynamic vocabulary lookups with Out-of-Vocabulary (OOV) buckets for categorical variables. -
Deep Neural Network Architecture Built using the Keras Functional API with custom embedding layers, Batch Normalization, and Dropout to reduce overfitting.
-
Pipeline Orchestration Workflow steps are automatically managed and scheduled using Apache Airflow DAGs.
-
Experiment Tracking Tracks loss, accuracy, and AUC metrics in real time using TensorBoard.
-
Model Serving Exports the trained model for deployment using TensorFlow Serving.
The model uses early stopping monitored on validation AUC (val_auc).
Final results on the validation split:
| Metric | Result |
|---|---|
| Validation AUC | 91.65% |
| Validation Accuracy | 85.51% |
| Validation Loss | 0.3097 |
| Precision | ~69.68% |
| Recall | ~70.92% |
The following numerical features are normalized using Z-score normalization:
ageeducation_numcapital_gaincapital_losshours_per_week
The following categorical features are encoded using embedding layers:
workclassmarital_statusoccupationrelationshipracesexnative_country
Embedding layers use:
input_dim = vocab_size + 2
The additional vocabulary capacity accounts for special/OOV values.
Numeric Inputs ββββββββββββββββ
β
Categorical Inputs β Embeddings
β
βΌ
Concatenated Features
β
βΌ
Dense Layer (128)
β
Batch Normalization
β
Dropout (0.3)
β
βΌ
Dense Layer (64)
β
Batch Normalization
β
Dropout (0.2)
β
βΌ
Dense Layer (32)
β
Dropout (0.1)
β
βΌ
Sigmoid Output (1)
β
βΌ
>50K / <=50K Income
-
Batch Normalization
-
Dropout
0.30.20.1
The model produces a single binary output using a Sigmoid activation:
>50K
<=50K
Important: The Python bytecode in
__pycache__targets CPython 3.7.
The versions specified in requirements.txt represent the last mutually compatible configuration for this project:
TFX 1.9.1
Airflow 2.3.4
TensorFlow 2.9.3
Python 3.7
Use a Python 3.7 virtual environment.
Newer TFX releases may no longer support the same Airflow orchestration setup, while newer Airflow releases have dropped Python 3.7 support.
adult_census_tfx/
β
βββ adult_pipeline_definition.py
β βββ create_pipeline() shared by both runners
β
βββ adult_pipeline_airflow.py
β βββ Airflow DAG entry point
β
βββ adult_pipeline_local.py
β βββ LocalDagRunner for rapid iteration without Airflow
β
βββ adult_trainer_module.py
β βββ preprocessing_fn + run_fn (Transform/Trainer)
β
βββ requirements.txt
β βββ Dependency specifications
β
βββ eda_analysis.ipynb
β βββ Dataset correlation and EDA notebook
β
βββ tfma_analysis.ipynb
β βββ TFMA fairness analysis and evaluation scaffold
β
βββ data/
βββ adult.csv
βββ Preprocessed census dataset
If you already created a virtual environment such as tfx-env or tfx-airflow-env, activate it:
source tfx-env/bin/activateIf you have not created the environment yet:
python3.7 -m venv tfx-env
source tfx-env/bin/activate
pip install -r requirements.txtVerify the Python version:
python --versionExpected:
Python 3.7.x
Set the Airflow home directory:
export AIRFLOW_HOME=~/airflowInitialize the Airflow database:
airflow db initCreate the DAG directory:
mkdir -p $AIRFLOW_HOME/dagsCreate a symbolic link to the repository:
ln -s $(pwd) $AIRFLOW_HOME/dags/adult_census_tfxCreate an Airflow administrator account:
airflow users create \
--username admin \
--password admin \
--firstname Team \
--lastname COMP315 \
--role Admin \
--email admin@example.comStart the Airflow webserver:
airflow webserver -p 8080 &Start the Airflow scheduler:
airflow scheduler &Open the Airflow web interface:
http://localhost:8080
Then:
- Log in using the Airflow administrator account.
- Locate the
adult_census_tfxDAG. - Toggle the DAG to Unpaused.
- Trigger a new DAG run.
- Monitor the pipeline components from the Airflow interface.
Pipeline execution outputs and the metadata database will be persisted under:
~/COMP315/airflow_pipeline_outputs/
Build the project Docker image:
docker build -t adult-census-tfx:latest .Serve the exported model using TensorFlow Serving:
docker run -d \
-p 8501:8501 \
-v ~/COMP315/airflow_pipeline_outputs/adult_census_tfx_output/Pusher/model/latest:/models/adult_census \
-e MODEL_NAME=adult_census \
tensorflow/serving:latestCheck that the model is available:
curl http://localhost:8501/v1/models/adult_censusA successful response should contain information about the loaded adult_census model.
The EDA notebook provides standalone dataset analysis, including:
- Feature correlations
- Missing-value analysis
- Baseline feature distributions
- Dataset exploration
The TFMA notebook evaluates:
- Model slices
- Evaluation metrics
- Fairness metrics
- Model performance using MLMD-generated artifacts
Before running the notebook, update:
EVAL_RESULT_PATHwith the local artifact URI generated during the Airflow pipeline execution.
Launch TensorBoard using the pipeline execution outputs:
tensorboard --logdir ~/COMP315/airflow_pipeline_outputs/Open TensorBoard in your browser:
http://localhost:6006
You can monitor metrics such as:
- Training loss
- Validation loss
- Training accuracy
- Validation accuracy
- AUC
- Validation AUC
| Technology | Purpose |
|---|---|
| Python 3.7 | Development environment |
| TensorFlow 2.9.3 | Deep learning framework |
| TensorFlow Extended (TFX) 1.9.1 | ML pipeline framework |
| TensorFlow Transform | Feature preprocessing |
| Apache Airflow 2.3.4 | Pipeline orchestration |
| TFMA | Model evaluation and fairness analysis |
| Keras | Neural network architecture |
| TensorBoard | Experiment tracking |
| Docker | Containerization |
| TensorFlow Serving | Model deployment |
βββββββββββββββββββ
β Census Data β
ββββββββββ¬βββββββββ
β
βΌ
βββββββββββββββββββ
β ExampleGen β
ββββββββββ¬βββββββββ
β
βΌ
βββββββββββββββββββ
β tf.Transformβ
β Preprocessing β
ββββββββββ¬βββββββββ
β
βΌ
βββββββββββββββββββ
β Trainer β
β Keras + TF β
ββββββββββ¬βββββββββ
β
βΌ
βββββββββββββββββββ
β TFMA β
β Model Evaluationβ
ββββββββββ¬βββββββββ
β
βΌ
βββββββββββββββββββ
β Pusher β
β Model Export β
ββββββββββ¬βββββββββ
β
βΌ
βββββββββββββββββββ
β TensorFlow β
β Serving β
βββββββββββββββββββ
The trained model achieves a 91.65% validation AUC and 85.51% validation accuracy, demonstrating strong performance in distinguishing individuals earning more than $50K annually from those earning $50K or less.
The project also demonstrates an end-to-end MLOps workflow, from raw data ingestion and preprocessing through model training, evaluation, orchestration, experiment tracking, and deployment.
Paolo Adame, Kelly Cyusa, Hojun Kim
Adult Census Income Classification β TFX & Apache Airflow Pipeline