The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.

Fitting models with neuralnetwork

neuralnetwork fits multilayer perceptrons for tabular regression and classification. The examples below use base R data sets and keep the training runs short enough for R CMD check, but the same calls work with your own data frames and matrices.

library(neuralnetwork)

Multiclass classification

Start with the formula interface. For small tabular data, hidden = "auto" and optimizer = "auto" are enough for a first fit.

fit_class <- nn_fit(
  Species ~ .,
  data = iris,
  hidden = "auto",
  optimizer = "auto",
  epochs = 10,
  validation_split = 0.2,
  seed = 1,
  verbose = FALSE
)

fit_class
#> neuralnetwork model
#>   Task:       classification
#>   Layers:     4 -> 4 -> 3
#>   Optimizer:  lbfgs | activation: tanh | backend: rcpp
#>   Loss:       cross_entropy
#>   Trained:    13 function evaluations
#>   Convergence: code 1 | message: NEW_X
#>   Final:      train loss 0.014447 | accuracy 0.99167
#>               validation loss 0.38622 | validation accuracy 0.9

The printed model reports the task, architecture, optimizer, loss, backend, training length, and final training or validation metrics.

Use predict() for classes or probabilities.

predict(fit_class, iris[1:5, ], type = "class")
#> [1] setosa setosa setosa setosa setosa
#> Levels: setosa versicolor virginica
round(predict(fit_class, iris[1:5, ], type = "prob"), 3)
#>      setosa versicolor virginica
#> [1,]      1          0         0
#> [2,]      1          0         0
#> [3,]      1          0         0
#> [4,]      1          0         0
#> [5,]      1          0         0

nn_evaluate() returns metrics for the fitted task. Multiclass classification includes accuracy, balanced accuracy, macro precision, macro recall, macro F1, and log loss.

ev_class <- nn_evaluate(fit_class, iris)
ev_class
#> neuralnetwork evaluation
#> Metrics:
#>             metric    value
#>           accuracy  0.97333
#>  balanced_accuracy  0.97333
#>    macro_precision  0.97359
#>       macro_recall  0.97333
#>           macro_f1   0.9734
#>           log_loss 0.088802
#> 
#> Confusion matrix:
#>             estimate
#> truth        setosa versicolor virginica
#>   setosa         49          1         0
#>   versicolor      0         48         2
#>   virginica       0          1        49

For imbalanced classification, balanced accuracy or F1 is usually more useful than raw accuracy. For probability forecasts, inspect log loss as well.

Binary classification and weights

Two-class outcomes use a one-output sigmoid model internally. The public prediction API still returns a two-column probability matrix.

iris_binary <- subset(iris, Species != "virginica")
row_weight <- ifelse(iris_binary$Species == "versicolor", 1.5, 1)

fit_binary <- nn_fit(
  Species ~ .,
  data = iris_binary,
  hidden = c(6, 3),
  optimizer = "adam",
  epochs = 8,
  batch_size = 16,
  learning_rate = 0.01,
  sample_weight = row_weight,
  class_weight = "balanced",
  gradient_clip = 5,
  validation_split = 0.2,
  seed = 2,
  verbose = FALSE
)

round(predict(fit_binary, iris_binary[1:5, ], type = "prob"), 3)
#>      setosa versicolor
#> [1,]  0.561      0.439
#> [2,]  0.605      0.395
#> [3,]  0.538      0.462
#> [4,]  0.569      0.431
#> [5,]  0.551      0.449
nn_evaluate(fit_binary, iris_binary)
#> neuralnetwork evaluation
#> Metrics:
#>             metric   value
#>           accuracy    0.95
#>  balanced_accuracy    0.95
#>    macro_precision 0.95018
#>       macro_recall    0.95
#>           macro_f1 0.94999
#>           log_loss 0.56381
#>        sensitivity    0.94
#>        specificity    0.96
#>          precision 0.95918
#>             recall    0.94
#>                 f1 0.94949
#> 
#> Confusion matrix:
#>             estimate
#> truth        setosa versicolor
#>   setosa         48          2
#>   versicolor      3         47

Regression

Regression follows the same shape. By default, regression targets are scaled for training and predictions are returned on the original scale.

fit_reg <- nn_fit(
  mpg ~ wt + hp + disp,
  data = mtcars,
  hidden = c(8, 4),
  optimizer = "adam",
  epochs = 25,
  batch_size = 8,
  learning_rate = 0.01,
  validation_split = 0.2,
  seed = 3,
  verbose = FALSE
)

fit_reg
#> neuralnetwork model
#>   Task:       regression
#>   Layers:     3 -> 8 -> 4 -> 1
#>   Optimizer:  adam | activation: sigmoid | backend: rcpp
#>   Loss:       squared_error
#>   Trained:    25 epochs | best epoch: 23
#>   Final:      train loss 0.11705 | rmse 3.0527
#>               validation loss 0.031615 | validation rmse 1.5865
round(predict(fit_reg, mtcars[1:5, ]), 2)
#> [1] 23.12 22.42 24.74 19.54 16.42
nn_evaluate(fit_reg, mtcars)
#> neuralnetwork evaluation
#> Metrics:
#>  metric   value
#>    rmse  3.0025
#>     mae   2.281
#>     rsq 0.74381

Robust regression

Squared error is the default regression loss. If a few observations may be unusually influential, use Huber loss.

mtcars_outlier <- mtcars
mtcars_outlier$mpg[1] <- mtcars_outlier$mpg[1] + 40

fit_huber <- nn_fit(
  mpg ~ wt + hp,
  data = mtcars_outlier,
  hidden = 4,
  optimizer = "adam",
  loss = "huber",
  huber_delta = 1,
  epochs = 20,
  batch_size = 8,
  learning_rate = 0.01,
  seed = 4,
  verbose = FALSE
)

summary(fit_huber)
#> neuralnetwork summary
#>   Task:       regression
#>   Layers:     2 -> 4 -> 1
#>   Optimizer:  adam | activation: sigmoid | backend: rcpp
#>   Loss:       huber (delta=1)
#>   Epochs:     20 | best epoch: 20
#> 
#> Final training row:
#>  epoch train_loss validation_loss train_metric validation_metric gradient_norm
#>     20    0.18135              NA       7.6733                NA       0.41666
#>  learning_rate backtracked
#>           0.01       FALSE

Training controls

The training loop supports dropout, L2 regularization, gradient clipping, learning-rate decay, validation splits, early stopping, and callbacks. This example stops after two epochs so the callback behavior is visible without making the vignette slow.

epochs_seen <- 0L

fit_callback <- nn_fit(
  mpg ~ wt + hp,
  data = mtcars,
  hidden = 4,
  optimizer = "adam",
  epochs = 20,
  batch_size = 8,
  learning_rate = 0.01,
  l2 = 1e-4,
  dropout = 0.05,
  gradient_clip = 5,
  validation_split = 0.2,
  callbacks = function(state) {
    epochs_seen <<- state$epoch
    if (state$epoch >= 2) {
      return(list(stop = TRUE))
    }
    NULL
  },
  seed = 5,
  verbose = FALSE
)

fit_callback
#> neuralnetwork model
#>   Task:       regression
#>   Layers:     2 -> 4 -> 1
#>   Optimizer:  adam | activation: sigmoid | backend: rcpp
#>   Loss:       squared_error
#>   Trained:    2 epochs | best epoch: 2
#>   Final:      train loss 0.52135 | rmse 6.4176
#>               validation loss 0.13129 | validation rmse 3.2201
#>   Stopped:    callback

Training choices:

Tuning and cross-validation

Use nn_tune() for a grid search. Classification metrics include accuracy, balanced_accuracy, f1, and log_loss. Regression metrics include rmse, mae, and rsq.

tuned <- nn_tune(
  Species ~ .,
  data = iris,
  grid = list(
    hidden = list(4, c(6, 3)),
    learning_rate = c(0.01)
  ),
  metric = "balanced_accuracy",
  epochs = 4,
  validation_split = 0.2,
  seed = 6,
  verbose = FALSE
)

tuned
#> neuralnetwork tuning result
#>   Candidates: 2
#>   Objective:  balanced_accuracy (higher is better)
#>   Best score: 0.91534
#> 
#> Top candidates:
#>  hidden learning_rate success            metric   score error rank
#>       4          0.01    TRUE balanced_accuracy 0.91534  <NA>    1
#>    6, 3          0.01    TRUE balanced_accuracy 0.88889  <NA>    2
tuned$best_params
#>   hidden learning_rate
#> 1      4          0.01

When exploring a wider grid, error_action = "continue" keeps invalid candidate combinations in the result table and ranks the usable fits. The default remains strict, so a bad grid fails before it produces misleading results.

Use nn_cv() for fold-level estimates.

cv <- nn_cv(
  Species ~ .,
  data = iris,
  k = 3,
  metric = "f1",
  hidden = 4,
  epochs = 2,
  seed = 7,
  verbose = FALSE
)

cv
#> neuralnetwork cross-validation
#>   Folds:   3
#>   Repeats: 1
#> 
#>    metric    mean      sd
#>  macro_f1 0.86362 0.10213

Permutation importance

Permutation importance measures how much a metric changes when one feature is shuffled.

imp <- nn_permutation_importance(
  fit_reg,
  mtcars,
  metric = "mae",
  n_repeats = 2,
  seed = 8
)

imp
#> neuralnetwork permutation importance
#>   Metric:  mae
#>   Repeats: 2
#> 
#>  feature importance baseline permuted metric n_repeats
#>       wt    0.98792    2.281   3.2689    mae         2
#>     disp    0.57524    2.281   2.8562    mae         2
#>       hp    0.54879    2.281   2.8298    mae         2

Save, load, and inspect

Models are regular R objects. nn_save() and nn_load() add package-level checks around saveRDS() and readRDS().

model_path <- tempfile(fileext = ".rds")
nn_save(fit_reg, model_path)
fit_loaded <- nn_load(model_path)

all.equal(
  predict(fit_reg, mtcars[1:3, ]),
  predict(fit_loaded, mtcars[1:3, ])
)
#> [1] TRUE

The package includes compatibility helpers for common nnet and neuralnet tasks.

nn_class_ind(iris$Species[1:4])
#>      setosa versicolor virginica
#> [1,]      1          0         0
#> [2,]      1          0         0
#> [3,]      1          0         0
#> [4,]      1          0         0

computed <- nn_compute(fit_class, iris[1:2, ])
names(computed$neurons)
#> [1] "input"   "hidden1" "output"
round(computed$net.result, 3)
#>      setosa versicolor virginica
#> [1,]      1          0         0
#> [2,]      1          0         0

Function map

Function names:

Need Use
Fit a regression or classification network nn_fit()
Fit a no-hidden-layer multinomial model nn_multinom()
Get class probabilities or numeric predictions predict()
Score a fitted model nn_evaluate()
Tune a small grid nn_tune()
Run repeated k-fold validation nn_cv()
Estimate feature importance nn_permutation_importance()
Get compute-style hidden activations nn_compute()
Get generalized weights nn_generalized_weights()
Save and reload a model nn_save() and nn_load()

Start with nn_fit(), inspect nn_evaluate(), and add nn_tune() or nn_cv() when the first model is worth more computation.

Reference help: ?neuralnetwork, ?neuralnetwork-metrics, ?neuralnetwork-callbacks, and ?neuralnetwork-objects.

These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.