Skip to main content
Fanout
Keras API
Curriculum overview

TensorFlow Fundamentals · lesson 05/27

Keras API

tf.keras is the high-level API TensorFlow ships and the one you should use for new code on TF 2.x. It offers three ways to define a model — Sequential, Functional, and subclassing — plus one training loop through compile and fit. This lesson is the map; the other lessons in this module fill in each region.

The idea

Everything in Keras is a Layer or a Model, and both are callable on tensors. There are three ways to build a network, in increasing order of flexibility:

  • Sequential — a plain stack with one input and one output. Ideal for CNNs and MLPs.
  • Functional — you call layers on symbolic tensors and wire the graph yourself. Needed for multi-input, multi-output, or branching models.
  • Subclassing — you write a class with __init__ and call. Needed for loops, conditionals, or custom training steps.

Training is three method calls: compile attaches an optimizer, a loss, and metrics; fit runs the loop; evaluate and predict score and infer.

Worked example

A Functional model with two inputs — an image [None, 28, 28, 1] and a scalar tag [None, 1] — that concatenates features before classification:

import tensorflow as tf

img_in = tf.keras.Input(shape=(28, 28, 1), name="image")
tag_in = tf.keras.Input(shape=(1,), name="tag")

x = tf.keras.layers.Conv2D(16, 3, activation="relu")(img_in)   # [None, 26, 26, 16]
x = tf.keras.layers.GlobalAveragePooling2D()(x)                # [None, 16]
x = tf.keras.layers.Concatenate()([x, tag_in])                 # [None, 17]
out = tf.keras.layers.Dense(10)(x)                             # [None, 10]

model = tf.keras.Model(inputs=[img_in, tag_in], outputs=out)
model.compile(optimizer="adam",
              loss=tf.keras.losses.SparseCategoricalCrossentropy(from_logits=True),
              metrics=["accuracy"])
model.fit({"image": x_img, "tag": x_tag}, y, epochs=3, batch_size=64)

Pass inputs as a dict keyed by the Input names; Keras matches them by name, and a key mismatch silently trains on the wrong tensor.

In code

Subclassing is the escape hatch when the graph itself depends on data:

class Residual(tf.keras.Model):
    def __init__(self, units):
        super().__init__()
        self.a = tf.keras.layers.Dense(units, activation="relu")
        self.b = tf.keras.layers.Dense(units)

    def call(self, x):
        return x + self.b(self.a(x))  # input and output shapes must match

A subclassed model has no pre-built graph, so model.summary() needs the model to have been called once on real or dummy data. Everything else — compile, fit, and saving — works the same way.

Check yourself

  1. When do you need the Functional API instead of Sequential?
  2. What does a subclassed model lose compared to a Functional model, and why does that matter for summary()?
  3. Why is it better to leave the output layer as raw logits and set from_logits=True than to apply a softmax inside the model?

Key takeaways

  • Sequential, Functional, and subclassing are the three definition styles — pick the simplest one that fits.
  • compile plus fit is the standard training loop; evaluate and predict are inference.
  • tf.keras is the supported high-level API; new code should not use TF 1.x graph APIs.