0Pricing
R Academy · Lesson

Building Sequential Models

Stack Dense layers, apply activations, and compile with loss and optimizer.

Building Sequential Models is a free R Academy lesson on CoddyKit — lesson 2 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the R Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

The Sequential Model

A sequential model is a linear stack of layers where each layer has exactly one input tensor and one output tensor. It is the simplest Keras model type and covers the majority of practical use cases: feedforward classifiers, regressors, and basic CNNs/RNNs.

library(keras)

# An empty sequential model
model <- keras_model_sequential()
print(model)

# Or specify the input shape upfront
model <- keras_model_sequential(input_shape = c(20))
print(model)

layer_dense() — Fully Connected Layer

layer_dense(units, activation) adds a fully connected (dense) layer where every input neuron connects to every output neuron. The units argument sets the output dimensionality. activation applies a nonlinearity: 'relu' is standard for hidden layers.

library(keras)

model <- keras_model_sequential(input_shape = c(30)) |>
  layer_dense(units = 128, activation = 'relu') |>
  layer_dense(units = 64,  activation = 'relu') |>
  layer_dense(units = 1,   activation = 'sigmoid')

# Print architecture
summary(model)

Output Layer Activations

The final layer's activation depends on the task:

  • 'sigmoid': binary classification (outputs 0-1 probability)
  • 'softmax': multi-class classification (outputs probabilities summing to 1)
  • 'linear' or no activation: regression (outputs real-valued predictions)
# Binary classification
binary_model <- keras_model_sequential(input_shape = c(20)) |>
  layer_dense(64, activation = 'relu') |>
  layer_dense(1,  activation = 'sigmoid')   # P(class=1)

# Multi-class (10 classes)
multi_model <- keras_model_sequential(input_shape = c(20)) |>
  layer_dense(64,  activation = 'relu') |>
  layer_dense(10,  activation = 'softmax')  # P per class

# Regression
reg_model <- keras_model_sequential(input_shape = c(20)) |>
  layer_dense(64, activation = 'relu') |>
  layer_dense(1,  activation = 'linear')   # raw value

compile() — Loss, Optimizer, Metrics

compile(loss, optimizer, metrics) configures the learning process. Typical combinations:

  • Binary: loss = 'binary_crossentropy', metrics = 'accuracy'
  • Multi-class: loss = 'categorical_crossentropy'
  • Regression: loss = 'mse', metrics = 'mae'
model |> compile(
  loss      = 'binary_crossentropy',
  optimizer = optimizer_adam(learning_rate = 0.001),
  metrics   = c('accuracy')
)

# Check configuration
model$loss
model$optimizer$get_config()

optimizer_adam()

Adam (Adaptive Moment Estimation) is the default optimizer for most deep learning tasks. It adapts the learning rate per parameter using estimates of first and second moments of the gradients. The default learning rate of 0.001 is a good starting point for most problems.

# Adam with default settings
model |> compile(
  optimizer = 'adam',
  loss = 'binary_crossentropy',
  metrics = 'accuracy'
)

# Customised Adam
model |> compile(
  optimizer = optimizer_adam(
    learning_rate = 0.0005,
    beta_1  = 0.9,
    beta_2  = 0.999,
    epsilon = 1e-7
  ),
  loss    = 'binary_crossentropy',
  metrics = 'accuracy'
)

fit() — Training the Model

fit(model, x, y, epochs, batch_size, validation_split) trains the model. Each epoch is one full pass through the training data. The batch size determines how many samples are processed before each weight update. The function returns a history object.

# Prepare example data
x_train <- matrix(rnorm(1000 * 20), nrow = 1000)
y_train <- sample(c(0, 1), 1000, replace = TRUE)

history <- model |> fit(
  x         = x_train,
  y         = y_train,
  epochs    = 20,
  batch_size = 32,
  validation_split = 0.2,  # reserve 20% for validation
  verbose   = 1
)

plot(history)

Layer Regularization — Dropout

layer_dropout(rate) randomly sets a fraction rate of input units to 0 during training. This prevents neurons from co-adapting too closely, acting as a powerful regulariser. Dropout is only active during training, not during inference.

model <- keras_model_sequential(input_shape = c(784)) |>
  layer_dense(512, activation = 'relu') |>
  layer_dropout(rate = 0.4) |>
  layer_dense(256, activation = 'relu') |>
  layer_dropout(rate = 0.3) |>
  layer_dense(10,  activation = 'softmax')

summary(model)

L1 and L2 Weight Regularization

Regularize individual layers using kernel_regularizer to penalise large weights. L2 (ridge) penalises the sum of squared weights; L1 (lasso) penalises absolute values and induces sparsity. Both are available via regularizer_l2() and regularizer_l1().

model <- keras_model_sequential(input_shape = c(100)) |>
  layer_dense(
    units = 64,
    activation = 'relu',
    kernel_regularizer = regularizer_l2(l = 0.01)
  ) |>
  layer_dense(
    units = 32,
    activation = 'relu',
    kernel_regularizer = regularizer_l1_l2(l1 = 1e-4, l2 = 1e-3)
  ) |>
  layer_dense(1, activation = 'sigmoid')

summary(model)

Batch Normalization

layer_batch_normalization() normalises the activations of the previous layer for each mini-batch. This stabilises training, allows higher learning rates, and acts as a mild regulariser. Place it after layer_dense() and before the activation function, or after activation — both are used in practice.

model <- keras_model_sequential(input_shape = c(100)) |>
  layer_dense(256, use_bias = FALSE) |>
  layer_batch_normalization() |>
  layer_activation('relu') |>
  layer_dense(128, use_bias = FALSE) |>
  layer_batch_normalization() |>
  layer_activation('relu') |>
  layer_dense(1, activation = 'sigmoid')

summary(model)

evaluate() and predict()

evaluate(model, x_test, y_test) computes the loss and metrics on test data. predict(model, x_new) generates raw predictions — probabilities for classification. Both accept numeric matrices and return consistent, R-native values.

x_test <- matrix(rnorm(200 * 20), nrow = 200)
y_test <- sample(c(0, 1), 200, replace = TRUE)

# Evaluate on test set
test_metrics <- model |> evaluate(x_test, y_test, verbose = 0)
cat('Test Loss:', test_metrics['loss'])
cat('Test Accuracy:', test_metrics['accuracy'])

# Generate predictions
prob_preds <- model |> predict(x_test)
class_preds <- ifelse(prob_preds > 0.5, 1, 0)
table(class_preds, y_test)

Saving and Loading Models

Save a compiled and trained model with save_model_tf(model, 'path') (TF SavedModel format, recommended) or save_model_hdf5(model, 'model.h5'). Reload with load_model_tf() or load_model_hdf5(). The loaded model retains compilation settings and can immediately predict or continue training.

# Save in TensorFlow SavedModel format (recommended)
save_model_tf(model, '/tmp/my_dense_model')

# Reload
loaded <- load_model_tf('/tmp/my_dense_model')

# Confirm predictions match
new_preds <- loaded |> predict(x_test)
all.equal(prob_preds, new_preds)  # TRUE

Quick Check

When building a sequential model for a 5-class classification problem, what activation function and number of units should the output layer use?

Sequential Models Recap

Key takeaways from Building Sequential Models:

  • keras_model_sequential() creates a linear stack of layers.
  • layer_dense(units, activation) is the core fully connected layer.
  • Output activation: 'sigmoid' (binary), 'softmax' (multi-class), 'linear' (regression).
  • compile(loss, optimizer, metrics) configures the learning process.
  • fit(model, x, y, epochs, batch_size, validation_split) trains the model.
  • Regularisation: layer_dropout(rate), regularizer_l2(), layer_batch_normalization().
  • Save with save_model_tf(); load with load_model_tf().
library(keras)

model <- keras_model_sequential(input_shape = c(30)) |>
  layer_dense(128, activation = 'relu') |>
  layer_dropout(0.4) |>
  layer_dense(64, activation = 'relu') |>
  layer_dropout(0.3) |>
  layer_dense(1, activation = 'sigmoid')

model |> compile(
  optimizer = optimizer_adam(0.001),
  loss      = 'binary_crossentropy',
  metrics   = 'accuracy'
)

history <- model |> fit(
  x_train, y_train,
  epochs = 30, batch_size = 64,
  validation_split = 0.2, verbose = 0
)
plot(history)

Frequently asked questions

Is the “Building Sequential Models” lesson free?

Yes — the full text of “Building Sequential Models” is free to read here on the web, and the R Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the R Academy course, upgrade to CoddyKit PRO.

What will I learn in “Building Sequential Models”?

Stack Dense layers, apply activations, and compile with loss and optimizer. You practise R Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start R Academy?

No prior experience is required. R Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 2 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Building Sequential Models” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this R Academy lesson?

Yes. Every R Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. Setting Up Keras and TensorFlow in R
  2. Building Sequential Models
  3. Convolutional Neural Networks Basics
  4. Training, Validation, and Preventing Overfitting
← Back to R Academy