From 910d660d42a745ebe5b8ce5f0b3e1b9918358706 Mon Sep 17 00:00:00 2001 From: dwjak123lkdmaKOP Date: Sun, 17 Mar 2024 10:50:51 +0100 Subject: [PATCH] finalize CRAN update --- DESCRIPTION | 2 +- R/cito.R | 2 +- R/cnn.R | 119 +++++++++++++--------- cran-comments.md | 3 + man/cito.Rd | 2 +- man/print.avgPool.Rd | 18 ++++ man/print.conv.Rd | 18 ++++ man/print.linear.Rd | 18 ++++ man/print.maxPool.Rd | 18 ++++ man/print.transfer.Rd | 20 ++++ vignettes/A-Introduction_to_cito.Rmd.orig | 6 +- 11 files changed, 174 insertions(+), 52 deletions(-) create mode 100644 man/print.avgPool.Rd create mode 100644 man/print.conv.Rd create mode 100644 man/print.linear.Rd create mode 100644 man/print.maxPool.Rd create mode 100644 man/print.transfer.Rd diff --git a/DESCRIPTION b/DESCRIPTION index 963c387..499fd63 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -22,7 +22,7 @@ Authors@R: role = "ctb", email = "armin.schenk99@gmail.com") ) -Description: The 'cito' package provides a user-friendly interface for training and interpreting deep neural networks (DNN). 'cito' simplifies the fitting of DNNs by supporting the familiar formula syntax, hyper-parameter tuning under cross-validation, and helps to detect and handle convergence problems. DNNs can be trained on CPU, GPU and MacOS GPUs. In addition, 'cito' has many downstream functionalities such as various explainable AI metrics (e.g. variable importance, partial dependence plots, accumulated local effect plots, and effect estimates) to interpret trained DNNs. Finally, 'cito' optionally provides confidence intervals (and p-values) for all xAI metrics and predictions. +Description: The 'cito' package provides a user-friendly interface for training and interpreting deep neural networks (DNN). 'cito' simplifies the fitting of DNNs by supporting the familiar formula syntax, hyperparameter tuning under cross-validation, and helps to detect and handle convergence problems. DNNs can be trained on CPU, GPU and MacOS GPUs. In addition, 'cito' has many downstream functionalities such as various explainable AI (xAI) metrics (e.g. variable importance, partial dependence plots, accumulated local effect plots, and effect estimates) to interpret trained DNNs. 'cito' optionally provides confidence intervals (and p-values) for all xAI metrics and predictions. At the same time, 'cito' is computationally efficient because it is based on the deep learning framework 'torch'. The 'torch' package is native to R, so no Python installation or other API is required for this package. Encoding: UTF-8 LazyData: true Roxygen: list(markdown = TRUE) diff --git a/R/cito.R b/R/cito.R index 24ded69..4d606ab 100644 --- a/R/cito.R +++ b/R/cito.R @@ -1,6 +1,6 @@ #' 'cito': Building and training neural networks #' -#' 'cito' simplifies the building and training of (deep) neural networks by relying on standard R syntax and familiar methods from statistical packages. Model creation and training can be done with a single line of code. Furthermore, all generic R methods such as print or plot can be used on the fitted model. At the same time, 'cito' is computationally efficient because it is based on the deep learning framework 'torch' (with optional GPU support). The 'torch' package is native to R, so no Python installation or other API is required for this package. +#' The 'cito' package provides a user-friendly interface for training and interpreting deep neural networks (DNN). 'cito' simplifies the fitting of DNNs by supporting the familiar formula syntax, hyperparameter tuning under cross-validation, and helps to detect and handle convergence problems. DNNs can be trained on CPU, GPU and MacOS GPUs. In addition, 'cito' has many downstream functionalities such as various explainable AI (xAI) metrics (e.g. variable importance, partial dependence plots, accumulated local effect plots, and effect estimates) to interpret trained DNNs. 'cito' optionally provides confidence intervals (and p-values) for all xAI metrics and predictions. At the same time, 'cito' is computationally efficient because it is based on the deep learning framework 'torch'. The 'torch' package is native to R, so no Python installation or other API is required for this package. #' #' Cito is built around its main function \code{\link{dnn}}, which creates and trains a deep neural network. Various tools for analyzing the trained neural network are available. #' diff --git a/R/cnn.R b/R/cnn.R index 58bb5a8..25554b5 100644 --- a/R/cnn.R +++ b/R/cnn.R @@ -716,65 +716,81 @@ print.citoarchitecture <- function(x, input_shape, output_shape, ...) { cat("-------------------------------------------------------------------------------\n") } -print.linear <- function(layer, input_shape, ...) { +#' Print linear layer +#' +#' @param x an object of class linear +#' @param input_shape input shape +#' @param ... further arguments, not supported yet +print.linear <- function(x, input_shape, ...) { cat("-------------------------------------------------------------------------------\n") cat(paste0("Linear |Input: ", prod(input_shape), "\n")) - cat(paste0(" |Output: ", layer[["n_neurons"]], "\n")) - cat(paste0(" |Bias: ", layer[["bias"]], "\n")) - if(layer[["normalization"]]) { + cat(paste0(" |Output: ", x[["n_neurons"]], "\n")) + cat(paste0(" |Bias: ", x[["bias"]], "\n")) + if(x[["normalization"]]) { cat(paste0(" |Batch normalization\n")) } - cat(paste0(" |Activation: ", layer[["activation"]], "\n")) - if(layer[["dropout"]]>0) { - cat(paste0(" |Dropout: rate=", layer[["dropout"]], "\n")) + cat(paste0(" |Activation: ", x[["activation"]], "\n")) + if(x[["dropout"]]>0) { + cat(paste0(" |Dropout: rate=", x[["dropout"]], "\n")) } - return(invisible(layer[["n_neurons"]])) + return(invisible(x[["n_neurons"]])) } -print.conv <- function(layer, input_shape, ...) { +#' Print conv layer +#' +#' @param x an object of class conv +#' @param input_shape input shape +#' @param ... further arguments, not supported yet +print.conv <- function(x, input_shape, ...) { output_shape <- get_output_shape(input_shape = input_shape, - n_kernels = layer[["n_kernels"]], - kernel_size = layer[["kernel_size"]], - stride = layer[["stride"]], - padding = layer[["padding"]], - dilation = layer[["dilation"]]) + n_kernels = x[["n_kernels"]], + kernel_size = x[["kernel_size"]], + stride = x[["stride"]], + padding = x[["padding"]], + dilation = x[["dilation"]]) - kernel_size <- paste(layer[["kernel_size"]], collapse = "x") - stride <- paste(layer[["stride"]], collapse = "x") - padding <- paste(layer[["padding"]], collapse = "x") - dilation <- paste(layer[["dilation"]], collapse = "x") + kernel_size <- paste(x[["kernel_size"]], collapse = "x") + stride <- paste(x[["stride"]], collapse = "x") + padding <- paste(x[["padding"]], collapse = "x") + dilation <- paste(x[["dilation"]], collapse = "x") cat("-------------------------------------------------------------------------------\n") cat(paste0("Convolution|Input: ", paste(input_shape, collapse = "x"), "\n")) cat(paste0(" |Output: ", paste(output_shape, collapse = "x"), "\n")) cat(paste0(" |Kernel: ", kernel_size, " (stride=", stride, ", padding=", padding, ", dilation=", dilation, ")\n")) - cat(paste0(" |Bias: ", layer[["bias"]], "\n")) - if(layer[["normalization"]]) { + cat(paste0(" |Bias: ", x[["bias"]], "\n")) + if(x[["normalization"]]) { cat(paste0(" |Batch normalization\n")) } - cat(paste0(" |Activation: ", layer[["activation"]], "\n")) - if(layer[["dropout"]]>0) { - cat(paste0(" |Dropout: rate=", layer[["dropout"]], "\n")) + cat(paste0(" |Activation: ", x[["activation"]], "\n")) + if(x[["dropout"]]>0) { + cat(paste0(" |Dropout: rate=", x[["dropout"]], "\n")) } return(invisible(output_shape)) } -print.avgPool <- function(layer, input_shape, ...) { + +#' Print pooling layer +#' +#' @param x an object of class avgPool +#' @param input_shape input shape +#' @param ... further arguments, not supported yet +print.avgPool <- function(x, input_shape, ...) { output_shape <- get_output_shape(input_shape = input_shape, n_kernels = input_shape[1], - kernel_size = layer[["kernel_size"]], - stride = layer[["stride"]], - padding = layer[["padding"]], + kernel_size = x[["kernel_size"]], + stride = x[["stride"]], + padding = x[["padding"]], dilation = rep(1,length(input_shape)-1)) - kernel_size <- paste(layer[["kernel_size"]], collapse = "x") - stride <- paste(layer[["stride"]], collapse = "x") - padding <- paste(layer[["padding"]], collapse = "x") + kernel_size <- paste(x[["kernel_size"]], collapse = "x") + stride <- paste(x[["stride"]], collapse = "x") + padding <- paste(x[["padding"]], collapse = "x") cat("-------------------------------------------------------------------------------\n") cat(paste0("AvgPool |Input: ", paste(input_shape, collapse = "x"), "\n")) @@ -784,19 +800,24 @@ print.avgPool <- function(layer, input_shape, ...) { return(invisible(output_shape)) } -print.maxPool <- function(layer, input_shape, ...) { +#' Print pooling layer +#' +#' @param x an object of class maxPool +#' @param input_shape input shape +#' @param ... further arguments, not supported yet +print.maxPool <- function(x, input_shape, ...) { output_shape <- get_output_shape(input_shape = input_shape, n_kernels = input_shape[1], - kernel_size = layer[["kernel_size"]], - stride = layer[["stride"]], - padding = layer[["padding"]], - dilation = layer[["dilation"]]) + kernel_size = x[["kernel_size"]], + stride = x[["stride"]], + padding = x[["padding"]], + dilation = x[["dilation"]]) - kernel_size <- paste(layer[["kernel_size"]], collapse = "x") - stride <- paste(layer[["stride"]], collapse = "x") - padding <- paste(layer[["padding"]], collapse = "x") - dilation <- paste(layer[["dilation"]], collapse = "x") + kernel_size <- paste(x[["kernel_size"]], collapse = "x") + stride <- paste(x[["stride"]], collapse = "x") + padding <- paste(x[["padding"]], collapse = "x") + dilation <- paste(x[["dilation"]], collapse = "x") cat("-------------------------------------------------------------------------------\n") cat(paste0("MaxPool |Input: ", paste(input_shape, collapse = "x"), "\n")) @@ -806,18 +827,25 @@ print.maxPool <- function(layer, input_shape, ...) { return(invisible(output_shape)) } -print.transfer <- function(layer, input_shape, output_shape, ...) { - if(layer$replace_classifier) { - output_shape <- get_transfer_output_shape(layer$name) +#' Print transfer model +#' +#' @param x an object of class transfer +#' @param input_shape input shape +#' @param output_shape output shape +#' @param ... further arguments, not supported yet +print.transfer <- function(x, input_shape, output_shape, ...) { + + if(x$replace_classifier) { + output_shape <- get_transfer_output_shape(x$name) } cat("-------------------------------------------------------------------------------\n") cat(paste0("Transfer |Input: ", paste(input_shape, collapse = "x"), "\n")) cat(paste0(" |Output: ", paste(output_shape, collapse = "x"), "\n")) - cat(paste0(" |Network: ", layer[["name"]] , "\n")) - cat(paste0(" |Pretrained: ", layer[["pretrained"]] , "\n")) - if(layer[["pretrained"]]) cat(paste0(" |Weights frozen: ", layer[["freeze"]] , "\n")) + cat(paste0(" |Network: ", x[["name"]] , "\n")) + cat(paste0(" |Pretrained: ", x[["pretrained"]] , "\n")) + if(x[["pretrained"]]) cat(paste0(" |Weights frozen: ", x[["freeze"]] , "\n")) return(invisible(output_shape)) } @@ -830,7 +858,6 @@ print.transfer <- function(layer, input_shape, output_shape, ...) { #' @param output_shape the number of nodes in the output layer #' @param ... additional arguments #' @return nothing -#' plot.citoarchitecture <- function(x, input_shape, output_shape, ...) { x <- adjust_architecture(x, length(input_shape)-1) diff --git a/cran-comments.md b/cran-comments.md index b08f40d..a01d70b 100644 --- a/cran-comments.md +++ b/cran-comments.md @@ -1,4 +1,5 @@ # Version 1.1 +## cito submission 1 2024/03/17 This is a major update. The update includes new loss/likelihood functions, hyperparameter tuning, bug fixes, and improved documentation. @@ -19,6 +20,8 @@ Github actions: Win-builder * R-release, R-development, and R-oldrelease +Spelling has been checked (potential errors are intended). + # Version 1.0.2 diff --git a/man/cito.Rd b/man/cito.Rd index e8e9511..59ba380 100644 --- a/man/cito.Rd +++ b/man/cito.Rd @@ -6,7 +6,7 @@ \alias{cito-package} \title{'cito': Building and training neural networks} \description{ -'cito' simplifies the building and training of (deep) neural networks by relying on standard R syntax and familiar methods from statistical packages. Model creation and training can be done with a single line of code. Furthermore, all generic R methods such as print or plot can be used on the fitted model. At the same time, 'cito' is computationally efficient because it is based on the deep learning framework 'torch' (with optional GPU support). The 'torch' package is native to R, so no Python installation or other API is required for this package. +The 'cito' package provides a user-friendly interface for training and interpreting deep neural networks (DNN). 'cito' simplifies the fitting of DNNs by supporting the familiar formula syntax, hyperparameter tuning under cross-validation, and helps to detect and handle convergence problems. DNNs can be trained on CPU, GPU and MacOS GPUs. In addition, 'cito' has many downstream functionalities such as various explainable AI (xAI) metrics (e.g. variable importance, partial dependence plots, accumulated local effect plots, and effect estimates) to interpret trained DNNs. 'cito' optionally provides confidence intervals (and p-values) for all xAI metrics and predictions. At the same time, 'cito' is computationally efficient because it is based on the deep learning framework 'torch'. The 'torch' package is native to R, so no Python installation or other API is required for this package. } \details{ Cito is built around its main function \code{\link{dnn}}, which creates and trains a deep neural network. Various tools for analyzing the trained neural network are available. diff --git a/man/print.avgPool.Rd b/man/print.avgPool.Rd new file mode 100644 index 0000000..86b6e7b --- /dev/null +++ b/man/print.avgPool.Rd @@ -0,0 +1,18 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cnn.R +\name{print.avgPool} +\alias{print.avgPool} +\title{Print pooling layer} +\usage{ +\method{print}{avgPool}(x, input_shape, ...) +} +\arguments{ +\item{x}{an object of class avgPool} + +\item{input_shape}{input shape} + +\item{...}{further arguments, not supported yet} +} +\description{ +Print pooling layer +} diff --git a/man/print.conv.Rd b/man/print.conv.Rd new file mode 100644 index 0000000..619555f --- /dev/null +++ b/man/print.conv.Rd @@ -0,0 +1,18 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cnn.R +\name{print.conv} +\alias{print.conv} +\title{Print conv layer} +\usage{ +\method{print}{conv}(x, input_shape, ...) +} +\arguments{ +\item{x}{an object of class conv} + +\item{input_shape}{input shape} + +\item{...}{further arguments, not supported yet} +} +\description{ +Print conv layer +} diff --git a/man/print.linear.Rd b/man/print.linear.Rd new file mode 100644 index 0000000..5c87f5a --- /dev/null +++ b/man/print.linear.Rd @@ -0,0 +1,18 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cnn.R +\name{print.linear} +\alias{print.linear} +\title{Print linear layer} +\usage{ +\method{print}{linear}(x, input_shape, ...) +} +\arguments{ +\item{x}{an object of class linear} + +\item{input_shape}{input shape} + +\item{...}{further arguments, not supported yet} +} +\description{ +Print linear layer +} diff --git a/man/print.maxPool.Rd b/man/print.maxPool.Rd new file mode 100644 index 0000000..38a4df9 --- /dev/null +++ b/man/print.maxPool.Rd @@ -0,0 +1,18 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cnn.R +\name{print.maxPool} +\alias{print.maxPool} +\title{Print pooling layer} +\usage{ +\method{print}{maxPool}(x, input_shape, ...) +} +\arguments{ +\item{x}{an object of class maxPool} + +\item{input_shape}{input shape} + +\item{...}{further arguments, not supported yet} +} +\description{ +Print pooling layer +} diff --git a/man/print.transfer.Rd b/man/print.transfer.Rd new file mode 100644 index 0000000..96539c7 --- /dev/null +++ b/man/print.transfer.Rd @@ -0,0 +1,20 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/cnn.R +\name{print.transfer} +\alias{print.transfer} +\title{Print transfer model} +\usage{ +\method{print}{transfer}(x, input_shape, output_shape, ...) +} +\arguments{ +\item{x}{an object of class transfer} + +\item{input_shape}{input shape} + +\item{output_shape}{output shape} + +\item{...}{further arguments, not supported yet} +} +\description{ +Print transfer model +} diff --git a/vignettes/A-Introduction_to_cito.Rmd.orig b/vignettes/A-Introduction_to_cito.Rmd.orig index 682be37..4d5a965 100644 --- a/vignettes/A-Introduction_to_cito.Rmd.orig +++ b/vignettes/A-Introduction_to_cito.Rmd.orig @@ -77,7 +77,7 @@ To make the model portable (e.g. save and reload the model), the weights are sto Cito can handle many different response types. Common loss functions from ML but also likelihoods for statistical models are supported: | | | | | -|:-------------|:-------------|:------------------------|--------------------| +|:----------------|:-----------------------------|:-------------------------------------------------------------------------|-------------------------------------------------------------| | Name | Explanation | Example / Task | Meta-Code | | `mse` | mean squared error | Regression, predicting continuous values | `dnn(Sepal.Length~., ..., loss = "mse")` | | `mae` | mean absolute error | Regression, predicting continuous values | `dnn(Sepal.Length~., ..., loss = "msa")` | @@ -183,7 +183,7 @@ print(nn.fit) xAI can produce outputs that are similar to known outputs from statistical models: | xAI Method | Explanation | Statistical equivalent | -|----------------|-----------------------------------------|---------------| +|----------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|---------------------------| | Feature importance (returned by `summary(nn.fit)`) | Feature importance based on permutations. See [Fisher, Rudin, and Dominici (2018)](#0) Similar to how much variance in the data is explained by the features. | `anova(model)` | | Average conditional effects (ACE) (returned by `summary(nn.fit)`) | Average of local derivatives, approximation of linear effects. See [Scholbeck et al. (2022)](https://arxiv.org/abs/2201.08837) and [Pichler and Hartig (2023)](https://arxiv.org/abs/2306.10551) | `lm(Y~X)` | | Standard Deviation of Conditional Effects (SDCE) (returned by `summary(nn.fit)`) | Standard deviation of the average conditional effects. Correlates with the non-linearity of the effects. | | @@ -356,7 +356,7 @@ We started to support automatic hyperparameter tuning under Cross Validation. Th We can mark hyperparameters that should be tuned by cito by setting their values to `tune()`, for example `dnn (..., lr = tune()`. `tune()` is a function that creates a range of random values for the given hyperparameter. You can also change the maximum and minimum range of these values. The following table lists the hyperparameters that can currently be tuned: | Hyperparameter | Example | Details | -|:------------|:------------|:---------------------------------------------| +|:---------------|:--------------------------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| | hidden | `dnn(…,hidden=tune(10, 20, fixed=’depth’))` | Depth and width can be both tuned or only one of them, if both of them should be tuned, vectors for lower and upper \#' boundaries must be provided (first = number of nodes) | | bias | `dnn(…, bias=tune())` | Should the bias be turned on or off for all hidden layers | | lambda | `dnn(…, lambda = tune(0.0001, 0.1))` | lambda will be tuned within the range (0.0001, 0.1) |