Skip to content

The Universal Workflow of Machine Learning

What you’ll learn

  • the three phases every ML project passes through: define, develop, deploy
  • why data quality and problem framing usually matter more than model choice
  • target leaking, sampling bias, and concept drift — three ways a project quietly fails
  • the “beat a baseline, then overfit, then regularize” loop for developing a model
  • what changes once a model ships: monitoring, A/B testing, and retraining

Why you need a workflow, not just a model

Most tutorials — including much of this site — jump straight to “here’s a model, here’s model.fit()model.fit().” That’s fine for learning the mechanics, but it skips the two hardest, most time-consuming parts of a real project: figuring out what you’re actually trying to predict, and deciding what happens after the model works. François Chollet’s universal workflow of machine learning is a checklist that covers the whole lifecycle, not just the training loop:

diagram The universal workflow of ML mermaid
Three phases, each feeding the next — and concept drift feeding back into a new round of data collection.

1. Define the task

Before touching Keras, you need to know three things: what your inputs and targets actually are, what type of ML problem you’re facing (binary classification? regression? ranking?), and how you’ll measure success.

  • Frame the problem. What data is available, and what are you predicting from it? Not every problem is solvable — if the inputs genuinely don’t contain enough information to predict the target (say, forecasting a stock’s next move from its price history alone), no amount of model tuning will fix that.
  • Collect a dataset, and be honest about how expensive this step really is. Chollet’s rule of thumb: if you have an extra 50 hours to spend on a project, they’re usually better spent collecting more data than tuning the model further.
  • Understand your data before you model it — look at samples, plot histograms of numeric features, check class balance, and specifically watch for target leaking: a feature that (directly or indirectly) reveals the answer, and that won’t be available at prediction time in production.
  • Choose a measure of success that lines up with the real business goal — accuracy, ROC AUC, precision/recall — because every technical decision from here on is guided by whatever metric you pick.

2. Develop a model

Once you know what you’re predicting and how you’ll score it, model development follows a predictable loop:

  1. Prepare the data — vectorize it, normalize it into small, homogeneous ranges, and decide how to handle missing values.
  2. Pick an evaluation protocol — simple hold-out, K-fold, or iterated K-fold (the next page on this site walks through all three).
  3. Beat a common-sense baseline — a random classifier, or “always predict the majority class.” If you can’t beat that, something about the problem framing or the data is broken, and no architecture will save you.
  4. Scale up until it overfits — add layers, widen them, train longer. You need to see the model overfit at least once, so you know your capacity ceiling is high enough.
  5. Regularize and tune — now pull it back: add Dropout, L1/L2 penalties, early stopping, or a smaller architecture, guided entirely by validation performance, never the test set.
Picking a last-layer activation and loss from the problem type
PROBLEM_TYPE_TO_HEAD = {
    "binary_classification": ("sigmoid", "binary_crossentropy"),
    "multiclass_single_label": ("softmax", "categorical_crossentropy"),
    "multiclass_multilabel": ("sigmoid", "binary_crossentropy"),
}
 
def head_for(problem_type):
    activation, loss = PROBLEM_TYPE_TO_HEAD[problem_type]
    print(f"{problem_type}: activation={activation}, loss={loss}")
 
head_for("multiclass_single_label")
Picking a last-layer activation and loss from the problem type
PROBLEM_TYPE_TO_HEAD = {
    "binary_classification": ("sigmoid", "binary_crossentropy"),
    "multiclass_single_label": ("softmax", "categorical_crossentropy"),
    "multiclass_multilabel": ("sigmoid", "binary_crossentropy"),
}
 
def head_for(problem_type):
    activation, loss = PROBLEM_TYPE_TO_HEAD[problem_type]
    print(f"{problem_type}: activation={activation}, loss={loss}")
 
head_for("multiclass_single_label")

This is exactly the “develop a model that overfits, then regularize” loop this phase’s other pages give you the tools for: Batch Normalization, Regularization & Dropout, and Learning Rate Scheduling are all techniques you reach for during step 5, once step 4 has proven the model can fit.

3. Deploy the model

A model that scores well on the test set isn’t done — it’s ready for its next job:

  • Set expectations with stakeholders. “98% accuracy” means very little to a non-specialist; talking about false-positive and false-negative rates, and what they cost the business, communicates far more.
  • Ship an inference-only version. Production rarely runs your training-time Python object directly — it’s exported to TensorFlow Serving (a REST API), TensorFlow Lite (mobile/embedded), or TensorFlow.js (in-browser), often after weight pruning or quantization to shrink it.
  • Monitor it in the wild. Track the model’s real-world impact (A/B test against the old system if you can), and periodically audit its predictions against freshly annotated data.
  • Plan to retrain. Every model faces concept drift — the statistical properties of production data shift over time, so today’s well-fit model slowly decays. Keep collecting data, especially examples the current model gets wrong.

🧪 Try It Yourself

Exercise 1 – Beat a Common-Sense Baseline

Exercise 2 – Choose the Right Last-Layer Activation

Exercise 3 – Spot and Drop a Leaking Feature

Next

Continue to Evaluating Models: Generalization and Validation — step 2 of the workflow (“develop a model”) only works if you can trust the number it hands you back.

If this helped you, consider buying me a coffee ☕

Buy me a coffee

Was this page helpful?

Let us know how we did