liveBook · Manning

GRU

As explained in Deep Learning with Python, Third Edition

A recurrent neural network unit designed to process sequences with gated state updates.

A Gated Recurrent Unit (GRU) is a recurrent layer for sequences. It maintains a state as it processes timesteps, allowing later predictions to use information from earlier inputs. Think of it as a streamlined LSTM: GRU is simpler and cheaper, while LSTM is more powerful. Both are practical choices when the recent past matters more than the distant past. section 13.3.5 section 20.1.6

Forecasting temperature

To increase a temperature forecaster’s capacity, stack two 32-unit GRU layers. Set `return_sequences=True` on the first so the second receives an output at every timestep; let the second return only its final output for a single temperature prediction. With recurrent dropout in both layers and another Dropout layer before the Dense output, this setup reached a test MAE of 2.39 degrees—an 8.8% improvement over the baseline. The extra layer helped, but not dramatically. section 13.3.5

Listing 13.23 Training and evaluating a dropout-regularized, stacked GRU model
inputs = keras.Input(shape=(sequence_length, raw_data.shape[-1]))
x = layers.GRU(32, recurrent_dropout=0.5, return_sequences=True)(inputs)
x = layers.GRU(32, recurrent_dropout=0.5)(x)
x = layers.Dropout(0.5)(x)
outputs = layers.Dense(1)(x)
model = keras.Model(inputs, outputs)

callbacks = [
    keras.callbacks.ModelCheckpoint(
        "jena_stacked_gru_dropout.keras", save_best_only=True
    )
]
model.compile(optimizer="adam", loss="mse", metrics=["mae"])
history = model.fit(
    train_dataset,
    epochs=50,
    validation_data=val_dataset,
    callbacks=callbacks,
)
model = keras.models.load_model("jena_stacked_gru_dropout.keras")
print(f"Test MAE: {model.evaluate(test_dataset)[1]:.2f}")

The forecasting listing shows the two GRU calls, the crucial `return_sequences=True`, regularization, and training and evaluation code together. section 13.3.5

For next-character prediction, the output requirement changes: the model needs a prediction at every character position. An Embedding feeds a single GRU with `return_sequences=True`, followed by Dropout and a Dense softmax over the character vocabulary. Recurrent state carries information from past characters into each prediction. section 15.1.1

Listing 15.4 Building a miniature language model
embedding_dim = 256
hidden_dim = 1024
 
inputs = layers.Input(shape=(sequence_length,), dtype="int", name="token_ids")
x = layers.Embedding(vocabulary_size, embedding_dim)(inputs)
x = layers.GRU(hidden_dim, return_sequences=True)(x)
x = layers.Dropout(0.1)(x)
outputs = layers.Dense(vocabulary_size, activation="softmax")(x)     #1
model = keras.Model(inputs, outputs)

The miniature language model listing shows how Embedding, GRU, Dropout, and Dense produce a probability distribution at each timestep. section 15.1.1

Choose the GRU output to match the job:

Generating one character at a time

Training processes 100-character sequences, with the GRU state handled implicitly. For generation, a one-character model accepts an input state and returns both a character prediction and the updated state; it can reuse the trained model’s weights. Feed a prompt one character at a time to establish the starting state. Then select a predicted character, feed it back with the updated state, and repeat. The demonstrated loop selects the most likely character each time. section 15.1.1 section 15.1.2

Listing 15.6 Modifying the language model for autoregressive inference
inputs = keras.Input(shape=(1,), dtype="int", name="token_ids")       #1
input_state = keras.Input(shape=(hidden_dim,), name="state")
 
x = layers.Embedding(vocabulary_size, embedding_dim)(inputs)
x, output_state = layers.GRU(hidden_dim, return_state=True)(
    x, initial_state=input_state
)
outputs = layers.Dense(vocabulary_size, activation="softmax")(x)
generation_model = keras.Model(
    inputs=(inputs, input_state),
    outputs=(outputs, output_state),
)
generation_model.set_weights(model.get_weights())                 #2

The inference listing makes state an explicit model input and output with `return_state=True`, then copies weights from the trained model. section 15.1.2

The same state-passing idea supports sequence-to-sequence translation. A bidirectional GRU encoder represents the English input; its output initializes a GRU decoder that predicts Spanish tokens. The decoder must use only preceding target tokens—not a bidirectional view of future ones. For these recurrent models, use GRU when its simpler, cheaper design is a useful trade-off against LSTM. section 15.2.2 section 20.1.6

How Deep Learning with Python, Third Edition covers it

How deep it goes
Works through Keras stacking and explicit-state generation, but does not derive GRU gating equations.
Examples
Trains a stacked temperature forecaster and a character-level Shakespeare language model.
What it assumes
Assumes familiarity with Keras layers and sequence inputs; introduces GRU by comparison with LSTM rather than from its gate equations.
What you can do after
Build it from scratch in Keras for stacked forecasting, then adapt trained weights for token-by-token generation.
How it connects
Connects GRU to recurrent state, autoregressive language modeling, and sequence-to-sequence encoder–decoder translation.

Also explained in

Compare how 7 books explain GRU →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Deep Learning with Python, Third Edition. The section links point to the parts of the book it draws on.