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__andcall. 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 matchA 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
- When do you need the Functional API instead of Sequential?
- What does a subclassed model lose compared to a Functional model, and why does that matter for
summary()? - Why is it better to leave the output layer as raw logits and set
from_logits=Truethan to apply a softmax inside the model?
Key takeaways
- Sequential, Functional, and subclassing are the three definition styles — pick the simplest one that fits.
compileplusfitis the standard training loop;evaluateandpredictare inference.tf.kerasis the supported high-level API; new code should not use TF 1.x graph APIs.