Author: fchollet
View on TensorFlow.org
|
Run in Google Colab
|
View source on GitHub
|
View on keras.io
|
Setup
import numpy as np
import tensorflow as tf
from tensorflow import keras
from keras import layers
Introduction
The Keras functional API is a way to create models that are more flexible
than the keras.Sequential API. The functional API can handle models
with non-linear topology, shared layers, and even multiple inputs or outputs.
The main idea is that a deep learning model is usually a directed acyclic graph (DAG) of layers. So the functional API is a way to build graphs of layers.
Consider the following model:
This is a basic graph with three layers. To build this model using the functional API, start by creating an input node:
inputs = keras.Input(shape=(784,))
The shape of the data is set as a 784-dimensional vector. The batch size is always omitted since only the shape of each sample is specified.
If, for example, you have an image input with a shape of (32, 32, 3),
you would use:
# Just for demonstration purposes.
img_inputs = keras.Input(shape=(32, 32, 3))
The inputs that is returned contains information about the shape and dtype
of the input data that you feed to your model.
Here's the shape:
inputs.shape
TensorShape([None, 784])
Here's the dtype:
inputs.dtype
tf.float32
You create a new node in the graph of layers by calling a layer on this inputs
object:
dense = layers.Dense(64, activation="relu")
x = dense(inputs)
The "layer call" action is like drawing an arrow from "inputs" to this layer
you created.
You're "passing" the inputs to the dense layer, and you get x as the output.
Let's add a few more layers to the graph of layers:
x = layers.Dense(64, activation="relu")(x)
outputs = layers.Dense(10)(x)
At this point, you can create a Model by specifying its inputs and outputs
in the graph of layers:
model = keras.Model(inputs=inputs, outputs=outputs, name="mnist_model")
Let's check out what the model summary looks like:
model.summary()
Model: "mnist_model"
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
input_1 (InputLayer) [(None, 784)] 0
dense (Dense) (None, 64) 50240
dense_1 (Dense) (None, 64) 4160
dense_2 (Dense) (None, 10) 650
=================================================================
Total params: 55050 (215.04 KB)
Trainable params: 55050 (215.04 KB)
Non-trainable params: 0 (0.00 Byte)
_________________________________________________________________
You can also plot the model as a graph:
keras.utils.plot_model(model, "my_first_model.png")

And, optionally, display the input and output shapes of each layer in the plotted graph:
keras.utils.plot_model(model, "my_first_model_with_shape_info.png", show_shapes=True)

This figure and the code are almost identical. In the code version, the connection arrows are replaced by the call operation.
A "graph of layers" is an intuitive mental image for a deep learning model, and the functional API is a way to create models that closely mirrors this.
Training, evaluation, and inference
Training, evaluation, and inference work exactly in the same way for models
built using the functional API as for Sequential models.
The Model class offers a built-in training loop (the fit() method)
and a built-in evaluation loop (the evaluate() method). Note
that you can easily customize these loops
to implement training routines beyond supervised learning
(e.g. GANs).
Here, load the MNIST image data, reshape it into vectors, fit the model on the data (while monitoring performance on a validation split), then evaluate the model on the test data:
(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
model.compile(
loss=keras.losses.SparseCategoricalCrossentropy(from_logits=True),
optimizer=keras.optimizers.RMSprop(),
metrics=[keras.metrics.SparseCategoricalAccuracy()],
)
history = model.fit(x_train, y_train, batch_size=64, epochs=2, validation_split=0.2)
test_scores = model.evaluate(x_test, y_test, verbose=2)
print("Test loss:", test_scores[0])
print("Test accuracy:", test_scores[1])
Epoch 1/2 750/750 [==============================] - 4s 3ms/step - loss: 0.3556 - sparse_categorical_accuracy: 0.8971 - val_loss: 0.1962 - val_sparse_categorical_accuracy: 0.9422 Epoch 2/2 750/750 [==============================] - 2s 2ms/step - loss: 0.1612 - sparse_categorical_accuracy: 0.9527 - val_loss: 0.1461 - val_sparse_categorical_accuracy: 0.9592 313/313 - 0s - loss: 0.1492 - sparse_categorical_accuracy: 0.9556 - 463ms/epoch - 1ms/step Test loss: 0.14915992319583893 Test accuracy: 0.9556000232696533
For further reading, see the training and evaluation guide.
Save and serialize
Saving the model and serialization work the same way for models built using
the functional API as they do for Sequential models. The standard way
to save a functional model is to call
View on TensorFlow.org
Run in Google Colab
View source on GitHub
View on keras.io