Loading the lesson...
In the print dialog, choose "Save as PDF" as the destination.
Software Construction - Lesson 8
Building, inspecting, and training a plain stack of layers with the Sequential model
Sequential modelmodel = keras.Sequential([
keras.Input(shape=(3, 1)),
layers.Dense(2, activation="relu", name="layer1"),
layers.Dense(3, activation="relu", name="layer2"),
layers.Dense(4, name="layer3"),
])Input
shape=(3, 1)
layer1
Dense(2, relu)
layer2
Dense(3, relu)
layer3
Dense(4)
# Pass a list of layers to the constructor
model = keras.Sequential([
layers.Dense(2, activation="relu"),
layers.Dense(3, activation="relu"),
layers.Dense(4),
])
# Or build incrementally
model = keras.Sequential()
model.add(layers.Dense(2, activation="relu"))
model.add(layers.Dense(3, activation="relu"))
model.add(layers.Dense(4))
model.pop() # removes the last layer - behaves like a list of layersmodel.layersname argument, useful for annotating TensorBoard graphslayer = layers.Dense(3)
layer.weights # [] - empty
x = ops.ones((1, 4))
y = layer(x)
layer.weights # now has weights: shape (4, 3) and (3,)Sequential models: without a specified input shape, model.weights is empty until the model first sees datamodel = keras.Sequential()
model.add(keras.Input(shape=(4,)))
model.add(layers.Dense(2, activation="relu"))
model.summary() # works immediately - model is already "built"Input object itself is not part of model.layers, it is not a layermodel.summary()| Layer (type) | Output Shape | Param # |
|---|---|---|
| dense (Dense) | (1, 2) | 10 |
| dense_1 (Dense) | (1, 3) | 9 |
| dense_2 (Dense) | (1, 4) | 16 |
"sequential", Total params: 35model = keras.Sequential()
model.add(keras.Input(shape=(784,)))
model.add(layers.Dense(64, activation="relu"))
model.add(layers.Dense(64, activation="relu"))
model.add(layers.Dense(10, activation="softmax"))
(x_train, y_train), (x_test, y_test) = keras.datasets.mnist.load_data()
x_train = x_train.reshape(60000, 784).astype("float32") / 255
x_test = x_test.reshape(10000, 784).astype("float32") / 255
# Reserve 10,000 samples for validation
x_val, y_val = x_train[-10000:], y_train[-10000:]
x_train, y_train = x_train[:-10000], y_train[:-10000]Training
fit on the training split
Validation
holdout set from training data
Evaluation
scored on the test set
model.compile(
optimizer=keras.optimizers.RMSprop(learning_rate=1e-3),
loss=keras.losses.SparseCategoricalCrossentropy(),
metrics=[keras.metrics.SparseCategoricalAccuracy()],
)
# Shortcut with string identifiers for default settings
model.compile(optimizer="rmsprop",
loss="sparse_categorical_crossentropy",
metrics=["sparse_categorical_accuracy"])| Loss / metric | When to use | Label format |
|---|---|---|
SparseCategoricalCrossentropy / SparseCategoricalAccuracy | Integer labels | 0, 1, 2, ... |
categorical_crossentropy / categorical_accuracy | Multi-class, one-hot labels | [0, 0, 1], [1, 0, 0] |
binary_crossentropy / BinaryAccuracy | Binary classification | [0, 1, 1, 0] |
metrics is a list; a model can track any number of metricshistory = model.fit(
x_train, y_train,
batch_size=64,
epochs=2,
validation_data=(x_val, y_val),
)| Parameter | Description |
|---|---|
x | Input data (NumPy array, Tensor, or Dataset) |
y | Target labels, same format as the model's output |
batch_size | Number of samples per gradient update (default 32) |
epochs | Number of passes through the entire dataset |
validation_data | Tuple (val_x, val_y) evaluated at the end of each epoch |
shuffle | Whether to shuffle training data before each epoch (default True) |
verbose | 0 silent, 1 progress bar, 2 one line per epoch |
batch_size, iterating over the full dataset for epochs passeshistory object records loss and metric values at every epochresults = model.evaluate(x_test, y_test, batch_size=128)
print("test loss, test acc:", results)
predictions = model.predict(x_test[:3]) # probabilities from the last layer
print("predictions shape:", predictions.shape)evaluate() reports loss and metrics on held-out test datapredict() runs inference and returns the model's raw output (for example, class probabilities)Self-Study
Sequential: it supports non-linear topology, shared layers, and multiple inputs or outputsInput
784-dimensional vector
Dense
64 units, relu
Dense
64 units, relu
Dense
10 units, softmax
inputs = keras.Input(shape=(784,))
x = layers.Dense(64, activation="relu")(inputs)
x = layers.Dense(64, activation="relu")(x)
outputs = layers.Dense(10)(x)
model = keras.Model(inputs=inputs, outputs=outputs, name="mnist_model")keras.utils.plot_model(model, "my_model.png", show_shapes=True) visualizes the graphSequential models suit a simple, single-input/single-output stack of layers; use the functional API for branching, sharing, or multi-input/output architecturesInput(shape=...) up front to build immediately and enable summary()compile() wires together an optimizer, a loss function, and metrics to monitor; match the loss to your label format (sparse integer vs one-hot vs binary)fit() trains over batches and epochs, optionally validating each epoch; history records the training curveevaluate() measures final performance on held-out data; predict() returns raw model output for new inputsSequential API cannot expressMahmoud Abas|Keras Sequential model