An embedding layer turns integer token IDs into dense vectors. Think of it as a dictionary: each ID identifies a word or character, and the layer returns that token’s vector. The vectors start with random values and change through backpropagation as the model trains, making them useful for its particular task. section 14.5.3
Listing 14.22 Building an LSTM sequence model with an Embedding layer
hidden_dim <- 64L
inputs <- keras_input(shape = c(max_length), dtype = "int32")
outputs <- inputs |>
layer_embedding(input_dim = max_tokens,
output_dim = hidden_dim,
mask_zero = TRUE) |>
layer_bidirectional(layer_lstm(units = hidden_dim)) |>
layer_dropout(0.5) |>
layer_dense(1, activation = "sigmoid")
model <- keras_model(inputs, outputs, name = "lstm_with_embedding")
model |> compile(optimizer = "adam",
loss = "binary_crossentropy",
metrics = "accuracy")
Start with this R/Keras sentiment-classification model. Integer sequences pass through `layer_embedding()` before a bidirectional LSTM makes the prediction. section 14.5.3
Three details make the example easier to read:
- `input_dim` sets how many integer IDs the layer can look up; `output_dim` sets the length of each returned vector. An input shaped `(batch_size, sequence_length)` becomes `(batch_size, sequence_length, embedding_size)`. section 14.5.3
- `mask_zero = TRUE` is used with padded sequences so the model can distinguish padding from the tokens being modeled. section 14.5.3
- The embedding space is task-dependent: vectors learned for movie-review sentiment need not be ideal for legal-document classification. section 14.5.3
Listing 14.26 Building a CBOW model
hidden_dim <- 64 cbow_embedding <- layer_embedding( input_dim = max_tokens, output_dim = hidden_dim ) inputs <- keras_input(shape = c(2 * context_size), dtype = "int32") outputs <- inputs |> cbow_embedding() |> layer_global_average_pooling_1d() |> layer_dense(max_tokens, activation = "softmax") cbow_model <- keras_model(inputs, outputs) cbow_model |> compile( optimizer = "adam", loss = "sparse_categorical_crossentropy", metrics = "sparse_categorical_accuracy" )cbow_model Model: "functional" ┌─────────────────────────────────┬────────────────────────┬───────────────┐ │ Layer (type) │ Output Shape │ Param # │ ├─────────────────────────────────┼────────────────────────┼───────────────┤ │ input_layer_4 (InputLayer) │ (None, 8) │ 0 │ ├─────────────────────────────────┼────────────────────────┼───────────────┤ │ embedding_1 (Embedding) │ (None, 8, 64) │ 1,920,000 │ ├─────────────────────────────────┼────────────────────────┼───────────────┤ │ global_average_pooling1d │ (None, 64) │ 0 │ │ (GlobalAveragePooling1D) │ │ │ ├─────────────────────────────────┼────────────────────────┼───────────────┤ │ dense_4 (Dense) │ (None, 30000) │ 1,950,000 │ └─────────────────────────────────┴────────────────────────┴───────────────┘ Total params: 3,870,000 (14.76 MB) Trainable params: 3,870,000 (14.76 MB) Non-trainable params: 0 (0.00 B)
For an alternative training setup, this CBOW model embeds eight surrounding words, averages their vectors, and predicts the missing middle word. It can train embedding weights from text without sentiment labels. section 14.5.4
Embeddings also work with character IDs. A character-level language model maps each input character to a 256-dimensional vector before a GRU predicts the next character at each position. section 15.1.1



