Learn R Programming

kerasnip

The goal of kerasnip is to provide a seamless bridge between the keras and tidymodels frameworks. It allows for the dynamic creation of parsnip model specifications for Keras models, making them fully compatible with tidymodels workflows.

Installation

You can install the development version of kerasnip from GitHub with:

# install.packages("pak")
pak::pak("davidrsch/kerasnip")

Example

Example 1: Building a Sequential MLP

This example shows the core workflow for building a simple, linear stack of layers using create_keras_sequential_spec().

library(kerasnip)
library(tidymodels)
library(keras3)

# 1. Define Keras layer blocks
# The first block initializes the model.
input_block <- function(model, input_shape) {
  keras_model_sequential(input_shape = input_shape)
}
# Subsequent blocks add layers.
dense_block <- function(model, units = 32) {
  model |> layer_dense(units = units, activation = "relu")
}
# The final block creates the output layer.
output_block <- function(model) {
  model |>
    layer_dense(units = 1)
}

# 2. Create a spec from the layer blocks
# This creates a new model function, `basic_mlp()`, in your environment.
create_keras_sequential_spec(
  model_name = "basic_mlp",
  layer_blocks = list(
    input = input_block,
    dense = dense_block,
    output = output_block
  ),
  mode = "regression"
)

# 3. Use the generated spec to define a model.
# We can set the number of dense layers (`num_dense`) and their parameters (`dense_units`).
spec <- basic_mlp(
  num_dense = 2,
  dense_units = 64,
  fit_epochs = 10,
  learn_rate = 0.01
) |>
  set_engine("keras")

# 4. Fit the model within a tidymodels workflow
rec <- recipe(mpg ~ ., data = mtcars) |>
  step_normalize(all_numeric_predictors())

wf <- workflow(rec, spec)

set.seed(123)
fit_obj <- fit(wf, data = mtcars)

# 5. Make predictions
predict(fit_obj, new_data = mtcars[1:5, ])
#> # A tibble: 5 × 1
#>   .pred
#>   <dbl>
#> 1  21.3
#> 2  21.3
#> 3  22.8
#> 4  21.4
#> 5  18.7

Example 2: Building a Functional "Fork-Join" Model

For complex, non-linear architectures, use create_keras_functional_spec(). This example builds a model where the input is forked into two paths, which are then concatenated.

library(kerasnip)
library(tidymodels)
library(keras3)

# 1. Define blocks. For the functional API, blocks are nodes in a graph.
input_block <- function(input_shape) layer_input(shape = input_shape)
path_block <- function(tensor, units = 16) tensor |> layer_dense(units = units)
concat_block <- function(input_a, input_b) layer_concatenate(list(input_a, input_b))
output_block <- function(tensor) layer_dense(tensor, units = 1)

# 2. Create the spec. The graph is defined by block names and their arguments.
create_keras_functional_spec(
  model_name = "forked_mlp",
  layer_blocks = list(
    main_input = input_block,
    path_a = inp_spec(path_block, "main_input"),
    path_b = inp_spec(path_block, "main_input"),
    concatenated = inp_spec(concat_block, c(input_a = "path_a", input_b = "path_b")),
    output = inp_spec(output_block, "concatenated")
  ),
  mode = "regression"
)

# 3. Use the new spec. Arguments are prefixed with their block name.
spec <- forked_mlp(path_a_units = 16, path_b_units = 8, fit_epochs = 10) |>
  set_engine("keras")

# Fit and predict as usual
set.seed(123)
fit(spec, mpg ~ ., data = mtcars) |>
  predict(new_data = mtcars[1:5, ])
#> # A tibble: 5 × 1
#>   .pred
#>   <dbl>
#> 1  19.4
#> 2  19.5
#> 3  21.9
#> 4  18.6
#> 5  17.9

Example 3: Tuning a Sequential MLP Architecture

This example demonstrates how to tune the number of dense layers and the rate of a final dropout layer, showcasing how to tune both architecture and block hyperparameters simultaneously.

library(kerasnip)
library(tidymodels)
library(keras3)

# 1. Define Keras layer blocks for a tunable MLP
input_block <- function(model, input_shape) {
  keras_model_sequential(input_shape = input_shape)
}
dense_block <- function(model, units = 32) {
  model |> layer_dense(units = units, activation = "relu")
}
dropout_block <- function(model, rate = 0.2) {
  model |> layer_dropout(rate = rate)
}
output_block <- function(model) {
  model |> layer_dense(units = 1)
}

# 2. Create a spec from the layer blocks
create_keras_sequential_spec(
  model_name = "tunable_mlp",
  layer_blocks = list(
    input = input_block,
    dense = dense_block,
    dropout = dropout_block,
    output = output_block
  ),
  mode = "regression"
)

# 3. Define a tunable model specification
tune_spec <- tunable_mlp(
  num_dense = tune(),
  dense_units = tune(),
  num_dropout = 1,
  dropout_rate = tune(),
  fit_epochs = 10
) |>
  set_engine("keras")

# 4. Set up and run a tuning workflow
rec <- recipe(mpg ~ ., data = mtcars) |>
  step_normalize(all_numeric_predictors())

wf_tune <- workflow(rec, tune_spec)

# Define the tuning grid.
params <- extract_parameter_set_dials(wf_tune) |>
  update(
    num_dense = dials::num_terms(c(1, 3)),
    dense_units = dials::hidden_units(c(8, 64)),
    dropout_rate = dials::dropout(c(0.1, 0.5))
  )
grid <- grid_regular(params, levels = 2)

# 5. Run the tuning
set.seed(456)
folds <- vfold_cv(mtcars, v = 3)

tune_res <- tune_grid(
  wf_tune,
  resamples = folds,
  grid = grid,
  control = control_grid(verbose = FALSE)
)

# 6. Show the best architecture
show_best(tune_res, metric = "rmse")
#> # A tibble: 5 × 7
#>   num_dense dense_units dropout_rate .metric .estimator .mean .config
#>       <int>       <int>        <dbl> <chr>   <chr>      <dbl> <chr>
#> 1         1          64          0.1 rmse    standard    2.92 Preprocessor1_Model02
#> 2         1          64          0.5 rmse    standard    3.02 Preprocessor1_Model08
#> 3         3          64          0.1 rmse    standard    3.15 Preprocessor1_Model04
#> 4         1           8          0.1 rmse    standard    3.20 Preprocessor1_Model01
#> 5         3           8          0.1 rmse    standard    3.22 Preprocessor1_Model03

Copy Link

Version

Install

install.packages('kerasnip')

Monthly Downloads

198

Version

0.1.0

License

MIT + file LICENSE

Maintainer

David Díaz

Last Published

December 6th, 2025

Functions in kerasnip (0.1.0)

inp_spec

Remap Layer Block Arguments for Model Specification
keras_objects

Dynamically Discovered Keras Objects
step_collapse

Collapse Predictors into a single list-column
remove_keras_spec

Remove a Keras Model Specification and its Registrations
register_keras_optimizer

Register a Custom Keras Optimizer
loss_function_keras

Dials Parameter for Keras Loss Functions
keras_evaluate

Evaluate a Kerasnip Model
process_x_sequential

Process Predictor Input for Keras
register_keras_metric

Register a Custom Keras Metric
register_keras_loss

Register a Custom Keras Loss
process_x_functional

Process Predictor Input for Keras (Functional API)
create_keras_functional_spec

Create a Custom Keras Functional API Model Specification for Tidymodels
extract_keras_history

Extract Keras Training History
extract_keras_model

Extract Keras Model from a Fitted Kerasnip Object
extract_valid_grid

Extract Valid Grid from Compilation Results
compile_keras_grid

Compile Keras Models Over a Grid of Hyperparameters
create_keras_sequential_spec

Create a Custom Keras Sequential Model Specification for Tidymodels
generic_functional_fit

Internal Fitting Engine for Functional API Models
generic_sequential_fit

Internal Fitting Engine for Sequential API Models
model_exists

Check if a Kerasnip Model Specification Exists
process_y_functional

Process Outcome Input for Keras (Functional API)
process_y_sequential

Process Outcome Input for Keras
optimizer_function

Dials Parameter for Keras Optimizers
inform_errors

Inform About Compilation Errors
get_model_env

Get Parsnip's Model Environment