Build & train a Keras model — taxi fare (linear regression)

Source notebook

This walkthrough follows Google’s Machine Learning Crash Course lab: Linear regression — taxi fare (Colab). The notebook uses Chicago taxi data: predict FARE from trip features. We start with one input: TRIP_MILES.

Code1


import numpy as np
import tensorflow as tf
from tensorflow import keras
from tensorflow.keras import layers

# Feature
# Machine Learning\Terms.html#Features (x)
X = np.array([1.0, 2.0, 3.0, 4.0], dtype=float)

# Label
# Machine Learning\Terms.html#Label (y)
y = np.array([2.0, 4.0, 6.0, 8.0], dtype=float)

# Machine Learning\Libraries\keras\Layers_and_APIs.html
model = keras.Sequential([
    layers.Input(1),      # 1 feature(x) (TRIP_MILES)
    layers.Dense(1)       # Layer with 1 neuron. 1 label(y)
])

# Machine Learning\Libraries\keras\Layers_and_APIs.html
# Configure the model for training
# learning_rate=0.01 is a hyperparameter for gradient descent Terms.html#Gradient Descent
model.compile(
    optimizer=keras.optimizers.SGD(learning_rate=0.01), # Gradient Descent settings
    loss='mean_squared_error'                          # Loss function
)

# Machine Learning\Libraries\keras\Layers_and_APIs.html
# Train the model
model.fit(X, y, epochs=500, verbose=0)

# Machine Learning\Libraries\keras\Layers_and_APIs.html
# Use the trained model to make predictions
print(model.predict(np.array([5.0])))
      

Code2


def create_model(
    settings: ml_edu.experiment.ExperimentSettings,
    metrics: list[keras.metrics.Metric],
) -> keras.Model:
    inputs = {
        name: keras.Input(shape=(1,), name=name)
        for name in settings.input_features
    }
    concatenated_inputs = keras.layers.Concatenate()(list(inputs.values()))
    outputs = keras.layers.Dense(units=1)(concatenated_inputs)
    model = keras.Model(inputs=inputs, outputs=outputs)
    model.compile(
        optimizer=keras.optimizers.RMSprop(learning_rate=settings.learning_rate),
        loss="mean_squared_error",
        metrics=metrics,
    )
    return model

def train_model(
    experiment_name: str,
    model: keras.Model,
    dataset: pd.DataFrame,
    label_name: str,
    settings: ml_edu.experiment.ExperimentSettings,
) -> ml_edu.experiment.Experiment:

    features = {name: dataset[name].values for name in settings.input_features}
    label = dataset[label_name].values
    history = model.fit(
        x=features,
        y=label,
        batch_size=settings.batch_size,
        epochs=settings.number_epochs,
    )
    return ml_edu.experiment.Experiment(
        name=experiment_name,
        settings=settings,
        model=model,
        epochs=history.epoch,
        metrics_history=pd.DataFrame(history.history),
    )


settings_1 = ml_edu.experiment.ExperimentSettings(
    learning_rate=0.001,
    number_epochs=20,
    batch_size=50,
    input_features=["TRIP_MILES"],
)

metrics = [keras.metrics.RootMeanSquaredError(name="rmse")]
model_1 = create_model(settings_1, metrics)
experiment_1 = train_model(
    "one_feature", model_1, training_df, "FARE", settings_1
)
ml_edu.results.plot_experiment_metrics(experiment_1, ["rmse"])
ml_edu.results.plot_model_predictions(experiment_1, training_df, "FARE")
      

What this code does

This is linear regression using keras. Model tries to predict fares/label(y) using trip_miles/feature(x)

fare(y) ≈ w × trip_miles(x) + b
      

Keras implements that with a single Dense(units=1) layer (no activation = linear). Training minimizes mean squared error between predicted and actual fare.

What you need before this code runs

Item Role
keras / tf.keras Build and train the neural network API
pandas (pd) training_df — DataFrame with columns like TRIP_MILES, FARE
ml_edu Google’s helper package in the Colab notebook — ExperimentSettings, Experiment, plotting utilities
training_df Preprocessed taxi dataset (created earlier in the notebook)
ExperimentSettings Holds hyperparameters: learning rate, epochs, batch size, input feature names
metrics List of Keras metrics to track during training (here: RMSE)

In Colab, earlier cells install dependencies, load CSV data, and build training_df. This page focuses on model creation and training only.

create_model() — build the graph

Uses the Functional API (multiple named inputs → one output), not Sequential.


def create_model(
    settings: ml_edu.experiment.ExperimentSettings,
    metrics: list[keras.metrics.Metric],
) -> keras.Model:
    # One Input layer per feature name in settings (here: only 'TRIP_MILES')
    # shape=(1,) = one number per example; name= used for the dict key in fit()
    inputs = {
        name: keras.Input(shape=(1,), name=name)
        for name in settings.input_features
    }

    # Merge all feature tensors into one vector (needed when you add more features)
    concatenated_inputs = keras.layers.Concatenate()(list(inputs.values()))

    # Single neuron, linear activation (default) → scalar prediction (fare)
    outputs = keras.layers.Dense(units=1)(concatenated_inputs)

    # Functional API: explicit inputs dict + output tensor
    model = keras.Model(inputs=inputs, outputs=outputs)

    # compile = choose optimizer, loss, and metrics for training
    model.compile(
        optimizer=keras.optimizers.RMSprop(learning_rate=settings.learning_rate),
        loss="mean_squared_error",
        metrics=metrics,
    )

    return model
      

Line-by-line notes

train_model() — fit on data


def train_model(
    experiment_name: str,
    model: keras.Model,
    dataset: pd.DataFrame,
    label_name: str,
    settings: ml_edu.experiment.ExperimentSettings,
) -> ml_edu.experiment.Experiment:
    """Train the model by feeding it data."""

    # Build dict of feature columns — keys must match Input layer names
    features = {name: dataset[name].values for name in settings.input_features}
    label = dataset[label_name].values

    # fit = gradient descent loop for number_epochs passes over the data
    history = model.fit(
        x=features,
        y=label,
        batch_size=settings.batch_size,
        epochs=settings.number_epochs,
    )

    return ml_edu.experiment.Experiment(
        name=experiment_name,
        settings=settings,
        model=model,
        epochs=history.epoch,
        metrics_history=pd.DataFrame(history.history),
    )
      

Line-by-line notes

Run the experiment


settings_1 = ml_edu.experiment.ExperimentSettings(
    learning_rate=0.001,
    number_epochs=20,
    batch_size=50,
    input_features=["TRIP_MILES"],
)

metrics = [keras.metrics.RootMeanSquaredError(name="rmse")]

model_1 = create_model(settings_1, metrics)
experiment_1 = train_model(
    "one_feature", model_1, training_df, "FARE", settings_1
)

# Colab helpers — plot loss/RMSE over epochs and predicted vs actual fare
ml_edu.results.plot_experiment_metrics(experiment_1, ["rmse"])
ml_edu.results.plot_model_predictions(experiment_1, training_df, "FARE")
      

Hyperparameters in this run

Setting Value Meaning
learning_rate 0.001 Step size for RMSprop weight updates
number_epochs 20 How many times to iterate over full dataset
batch_size 50 Examples per gradient step
input_features ['TRIP_MILES'] Single predictor — miles driven
label FARE What we predict (dollars)
rmse metric Root mean squared error — typical error in fare units

Concepts glossary (everything this code touches)

Term Meaning
Model The computation graph: inputs → layers → output
Layer Input, Concatenate, Dense — see Keras layers
compile Attach optimizer, loss function, metrics before training
fit Train: feed features + labels, update weights for epochs
Optimizer (RMSprop) Algorithm that adjusts weights using gradients of the loss
Loss (MSE) What the optimizer minimizes; penalizes large prediction errors
Metric (RMSE) Reported each epoch for monitoring; not always the same as loss
Functional API Model(inputs=..., outputs=...) — supports dict inputs and branching
Experiment Colab ml_edu wrapper storing settings, model, and history for plots

Flow diagram


training_df['TRIP_MILES']  ──►  Input(name='TRIP_MILES')
                                      │
                                      ▼
                                 Concatenate
                                      │
                                      ▼
                              Dense(units=1)  ──►  predicted FARE
                                      ▲
training_df['FARE']  ────────────────┘  (compare via MSE, backprop updates weights)

settings: lr=0.001, batch=50, epochs=20
      

Try in Colab: Open notebook at create_model section →