├── .Rbuildignore ├── .Rhistory ├── .github ├── .gitignore └── workflows │ └── R-CMD-check.yaml ├── .gitignore ├── DESCRIPTION ├── LICENSE.txt ├── NAMESPACE ├── R ├── controls.R ├── cross-validation.R ├── data_handler.R ├── data_handler_torch.R ├── deep-ensembles.R ├── deepregression.R ├── deepregression_torch.R ├── dro.R ├── families.R ├── families_torch.R ├── formula_helpers.R ├── generator.R ├── helperfuns.R ├── layers.R ├── layers_torch.R ├── methods.R ├── models.R ├── nodelayer.R ├── orthogonalization.R ├── psplinelayer.R ├── psplinelayer_torch.R ├── special_processing.R ├── subnetwork_init.R ├── subnetwork_init_torch.R ├── tf_helpers.R ├── torch_helpers.R ├── utils-pipe.R └── zzz.R ├── README.md ├── codecov.yml ├── inst ├── CITATION └── python │ ├── activations │ ├── __init__.py │ └── sparsemax.py │ ├── common │ └── list_handling.py │ ├── distributions │ ├── __init__.py │ ├── __pycache__ │ │ ├── __init__.cpython-310.pyc │ │ └── mvr.cpython-310.pyc │ ├── mvr.py │ └── tweedie.py │ ├── generators │ ├── __init__.py │ ├── __pycache__ │ │ ├── __init__.cpython-310.pyc │ │ └── keras_generators.cpython-310.pyc │ ├── keras_generators.py │ └── rlayer.py │ ├── layers │ ├── __init__.py │ ├── __pycache__ │ │ ├── __init__.cpython-310.pyc │ │ ├── convlasso.cpython-310.pyc │ │ ├── lasso.cpython-310.pyc │ │ └── orthogonalization.cpython-310.pyc │ ├── bnlasso.py │ ├── convlasso.py │ ├── lasso.py │ ├── orthogonalization.py │ └── randomeffects.py │ ├── models │ ├── __init__.py │ ├── __pycache__ │ │ ├── __init__.cpython-310.pyc │ │ ├── custom_train_step.cpython-310.pyc │ │ └── model_trainable_para.cpython-310.pyc │ ├── custom_train_step.py │ ├── helpers.py │ └── model_trainable_para.py │ ├── node │ ├── __init__.py │ └── node.py │ ├── optimizers │ ├── __init__.py │ ├── __pycache__ │ │ ├── __init__.cpython-310.pyc │ │ └── discriminative_layer_training.cpython-310.pyc │ └── discriminative_layer_training.py │ ├── psplines │ ├── __init__.py │ ├── __pycache__ │ │ ├── __init__.cpython-310.pyc │ │ └── psplines.cpython-310.pyc │ └── psplines.py │ ├── tffuns │ ├── __init__.py │ ├── __pycache__ │ │ ├── __init__.cpython-310.pyc │ │ └── tffuns.cpython-310.pyc │ └── tffuns.py │ └── utils │ ├── __init__.py │ └── types.py ├── man ├── check_and_install.Rd ├── check_input_args_fit.Rd ├── choose_kernel_initializer_torch.Rd ├── coef.drEnsemble.Rd ├── collect_distribution_parameters.Rd ├── combine_penalties.Rd ├── convenience_layers.Rd ├── create_family.Rd ├── create_family_torch.Rd ├── create_penalty.Rd ├── cv.Rd ├── deepregression.Rd ├── distfun_to_dist.Rd ├── dr_families.Rd ├── ensemble.Rd ├── ensemble.deepregression.Rd ├── extract_S.Rd ├── extract_pure_gam_part.Rd ├── extractvar.Rd ├── family_to_tfd.Rd ├── family_to_trafo.Rd ├── family_to_trafo_torch.Rd ├── family_to_trochd.Rd ├── fitted.drEnsemble.Rd ├── form_control.Rd ├── formulaHelpers.Rd ├── from_dist_to_loss.Rd ├── from_dist_to_loss_torch.Rd ├── from_distfun_to_dist_torch.Rd ├── from_preds_to_dist.Rd ├── from_preds_to_dist_torch.Rd ├── gam_plot_data.Rd ├── get_distribution.Rd ├── get_ensemble_distribution.Rd ├── get_gam_part.Rd ├── get_gamdata.Rd ├── get_gamdata_reduced_nr.Rd ├── get_help_forward_torch.Rd ├── get_layer_by_opname.Rd ├── get_layernr_by_opname.Rd ├── get_layernr_trainable.Rd ├── get_luz_dataset.Rd ├── get_names_pfc.Rd ├── get_node_term.Rd ├── get_nodedata.Rd ├── get_partial_effect.Rd ├── get_processor_name.Rd ├── get_special.Rd ├── get_type_pfc.Rd ├── get_weight_by_name.Rd ├── get_weight_by_opname.Rd ├── hadamard_layers.Rd ├── hadamard_layers_torch.Rd ├── handle_gam_term.Rd ├── import_packages.Rd ├── import_tf_dependings.Rd ├── import_torch_dependings.Rd ├── keras_dr.Rd ├── layer_dense_module.Rd ├── layer_dense_torch.Rd ├── layer_node.Rd ├── layer_sparse_batch_normalization.Rd ├── layer_sparse_conv_2d.Rd ├── layer_spline.Rd ├── layer_spline_torch.Rd ├── log_score.Rd ├── loop_through_pfc_and_call_trafo.Rd ├── makeInputs.Rd ├── make_folds.Rd ├── make_generator.Rd ├── make_generator_from_matrix.Rd ├── makelayername.Rd ├── methodDR.Rd ├── model_torch.Rd ├── multioptimizer.Rd ├── na_omit_list.Rd ├── names_families.Rd ├── nn_init_no_grad_constant_deepreg.Rd ├── orthog_P.Rd ├── orthog_control.Rd ├── orthog_post_fitting.Rd ├── orthog_structured_smooths_Z.Rd ├── penalty_control.Rd ├── pipe.Rd ├── plot_cv.Rd ├── precalc_gam.Rd ├── predict_gam_handler.Rd ├── predict_gen.Rd ├── prepare_data.Rd ├── prepare_data_torch.Rd ├── prepare_input_list_model.Rd ├── prepare_newdata.Rd ├── prepare_torch_distr_mixdistr.Rd ├── process_terms.Rd ├── processors.Rd ├── quant.Rd ├── re_layers.Rd ├── reinit_weights.Rd ├── reinit_weights.deepregression.Rd ├── separate_define_relation.Rd ├── stddev.Rd ├── stop_iter_cv_result.Rd ├── subnetwork_init.Rd ├── subnetwork_init_torch.Rd ├── tf_repeat.Rd ├── tf_row_tensor.Rd ├── tf_split_multiple.Rd ├── tf_stride_cols.Rd ├── tf_stride_last_dim_tensor.Rd ├── tfd_mse.Rd ├── tfd_zinb.Rd ├── tfd_zip.Rd ├── torch_dr.Rd ├── update_miniconda_deepregression.Rd └── weight_control.Rd └── tests ├── testthat.R └── testthat ├── test_controls.R ├── test_customtraining.R ├── test_customtraining_torch.R ├── test_data_handler.R ├── test_data_handler_torch.R ├── test_deepregression.R ├── test_deepregression_torch.R ├── test_ensemble.R ├── test_ensemble_torch.R ├── test_families.R ├── test_families_torch.R ├── test_helperfuns.R ├── test_layers.R ├── test_layers_torch.R ├── test_methods.R ├── test_methods_torch.R ├── test_models.R ├── test_node.R ├── test_orthogonalization.R ├── test_orthogonalization_torch.R ├── test_reproducibility.R ├── test_reproducibility_torch.R ├── test_special_processing.R ├── test_special_processing_torch.R ├── test_subnetwork_init.R ├── test_subnetwork_init_torch.R ├── test_unstructured.R └── test_unstructured_torch.R /.Rbuildignore: -------------------------------------------------------------------------------- 1 | ^\.github$ 2 | ^codecov\.yml$ 3 | ^.*\.Rproj$ 4 | ^\.Rproj\.user$ 5 | .travis.yml 6 | cran-comments.md 7 | README.md 8 | ^doc$ 9 | ^Meta$ 10 | ^figure$ 11 | LICENSE.txt 12 | -------------------------------------------------------------------------------- /.github/.gitignore: -------------------------------------------------------------------------------- 1 | *.html 2 | -------------------------------------------------------------------------------- /.github/workflows/R-CMD-check.yaml: -------------------------------------------------------------------------------- 1 | # For help debugging build failures open an issue on the RStudio community with the 'github-actions' tag. 2 | # https://community.rstudio.com/new-topic?category=Package%20development&tags=github-actions 3 | on: 4 | push: 5 | branches: 6 | - main 7 | pull_request: 8 | branches: 9 | - main 10 | 11 | name: R-CMD-check 12 | 13 | jobs: 14 | R-CMD-check: 15 | runs-on: ubuntu-latest 16 | steps: 17 | - uses: actions/checkout@v2 18 | - uses: r-lib/actions/setup-r@v2-branch 19 | with: 20 | Ncpus: 4 21 | - uses: r-lib/actions/setup-tinytex@v2-branch 22 | - uses: r-lib/actions/setup-pandoc@v2-branch 23 | 24 | - name: "[Custom block] [Cache] Prepare weekly timestamp for cache" 25 | id: date 26 | run: echo "::set-output name=datem::$(date '+%Y-%m')" 27 | 28 | - name: Cache R packages 29 | uses: pat-s/always-upload-cache@v2 30 | with: 31 | path: ${{ env.R_LIBS_USER }} 32 | key: rcache-${{steps.date.outputs.datem}} 33 | restore-keys: ${{steps.date.outputs.datem}} 34 | 35 | - name: Cache python 36 | uses: pat-s/always-upload-cache@v2 37 | with: 38 | path: ~/.cache/pip 39 | key: pycache-${{steps.date.outputs.datem}} 40 | restore-keys: pycache-${{steps.date.outputs.datem}} 41 | 42 | - name: Install linux prerequesites 43 | run: | 44 | sudo apt-get install libxml2-dev libcurl4-openssl-dev 45 | - name: Install dependencies - Keras & TF 46 | run: | 47 | install.packages(c("remotes", "rcmdcheck")) 48 | remotes::install_deps(dependencies = TRUE) 49 | reticulate::install_miniconda(update = TRUE) 50 | reticulate::conda_create('r-reticulate', packages = c('python==3.8')) 51 | keras::install_keras(version = "2.10.0", tensorflow = "2.10.0", extra_packages = c('IPython', 'requests', 'certifi', 'urllib3', 'six', 'tensorflow_probability==0.16.0')) 52 | torch::install_torch() 53 | shell: Rscript {0} 54 | - name: Install dependencies - Tutorial (Vignette) 55 | run: | 56 | install.packages(c("ggplot2", "reshape2", "MASS", "gamlss.data", "distr")) 57 | shell: Rscript {0} 58 | - name: Check 59 | run: rcmdcheck::rcmdcheck(args=c("--as-cran", "--no-build-vignettes"), build_args=c("--no-build-vignettes"), error_on="error") 60 | shell: Rscript {0} 61 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | doc 2 | Meta 3 | tests/testthat/*.pdf 4 | *.Rproj 5 | *.pyc 6 | */__pycache__ 7 | *.cpython 8 | .Rproj.user 9 | *.DS_Store 10 | -------------------------------------------------------------------------------- /DESCRIPTION: -------------------------------------------------------------------------------- 1 | Package: deepregression 2 | Title: Fitting Deep Distributional Regression 3 | Version: 2.2.0 4 | Authors@R: c( 5 | person("David", "Ruegamer", , "david.ruegamer@gmail.com", role = c("aut", "cre")), 6 | person("Christopher", "Marquardt", , "ch.marquardt@campus.lmu.de", role = c("ctb")), 7 | person("Laetitia", "Frost", , "lae.frost@campus.lmu.de ", role = c("ctb")), 8 | person("Florian", "Pfisterer", , "florian.pfisterer@stat.uni-muenchen.de", role = c("ctb")), 9 | person("Philipp", "Baumann", , "baumann@kof.ethz.ch", role = c("ctb")), 10 | person("Chris", "Kolb", , "chris.kolb@stat.uni-muenchen.de", role = c("ctb")), 11 | person("Lucas", "Kook", , "lucasheinrich.kook@uzh.ch", role = c("ctb"))) 12 | Description: 13 | Allows for the specification of semi-structured deep distributional regression models which are fitted in a neural network as 14 | proposed by Ruegamer et al. (2023) . 15 | Predictors can be modeled using structured (penalized) linear effects, structured non-linear effects or using an unstructured deep network model. 16 | Config/reticulate: 17 | list( 18 | packages = list( 19 | list(package = "six", pip = TRUE), 20 | list(package = "tensorflow", version = "2.15", pip = TRUE), 21 | list(package = "tensorflow_probability", version = "0.23", pip = TRUE), 22 | list(package = "keras", version = "2.15", pip = TRUE)) 23 | ) 24 | Depends: 25 | R (>= 4.0.0), 26 | tensorflow (>= 2.2.0), 27 | tfprobability, 28 | keras (>= 2.2.0) 29 | Suggests: 30 | testthat, 31 | knitr, 32 | covr 33 | Imports: 34 | mgcv, 35 | dplyr, 36 | R6, 37 | reticulate (>= 1.14), 38 | Matrix, 39 | magrittr, 40 | tfruns, 41 | methods, 42 | coro (>= 1.0.3), 43 | torchvision (>= 0.5.1), 44 | luz (>= 0.4.0), 45 | torch 46 | License: GPL-3 47 | Encoding: UTF-8 48 | LazyData: true 49 | RoxygenNote: 7.3.2 50 | -------------------------------------------------------------------------------- /R/cross-validation.R: -------------------------------------------------------------------------------- 1 | make_cv_list_simple <- function(data_size, folds, seed = 42, shuffle = TRUE) 2 | { 3 | 4 | set.seed(seed) 5 | suppressWarnings( 6 | mysplit <- split(sample(1:data_size), 7 | f = rep(1:folds, each = data_size/folds)) 8 | ) 9 | lapply(mysplit, function(test_ind) 10 | list(train_ind = setdiff(1:data_size, test_ind), 11 | test_ind = test_ind)) 12 | 13 | } 14 | 15 | extract_cv_result <- function(res, engine, 16 | name_loss = "loss", name_val_loss = "val_loss"){ 17 | 18 | if(engine == "torch") { 19 | name_loss = "train" 20 | name_val_loss = "valid" 21 | } 22 | 23 | if (engine == "tf"){ 24 | losses <- sapply(res, "[[", "metrics") 25 | } else { 26 | losses <- sapply(res, function(x) lapply( 27 | x$records$metrics, function(y) unlist(y))) 28 | } 29 | 30 | trainloss <- data.frame(losses[name_loss,]) 31 | validloss <- data.frame(losses[name_val_loss,]) 32 | weightshist <- lapply(res, "[[", "weighthistory") 33 | # weight history not yet implemented for torch as plot_cv does'not support 34 | # anything else than losses. Needs to be implemented in cv.deepregression 35 | # Need to save with state_dict and detach from R6 (modify on place). 36 | 37 | return(list(trainloss=trainloss, 38 | validloss=validloss, 39 | weight=weightshist) 40 | ) 41 | } 42 | 43 | #' Plot CV results from deepregression 44 | #' 45 | #' @param x \code{drCV} object returned by \code{cv.deepregression} 46 | #' @param what character indicating what to plot (currently supported 'loss' 47 | #' or 'weights') 48 | #' @param engine character indicating which engine was used to setup the NN 49 | #' @param ... further arguments passed to \code{matplot} 50 | #' 51 | #' @export 52 | #' 53 | plot_cv <- function(x, what=c("loss","weight"), engine = "tf", ...){ 54 | 55 | .pardefault <- par(no.readonly = TRUE) 56 | cres <- extract_cv_result(x, engine = engine) 57 | 58 | what <- match.arg(what) 59 | 60 | if(what=="loss"){ 61 | 62 | loss <- cres$trainloss 63 | mean_loss <- apply(loss, 1, mean) 64 | vloss <- cres$validloss 65 | mean_vloss <- apply(vloss, 1, mean) 66 | 67 | oldpar <- par(no.readonly = TRUE) # code line i 68 | on.exit(par(oldpar)) # code line i + 1 69 | par(mfrow=c(1,2)) 70 | matplot(loss, type="l", col="black", ..., ylab="loss", xlab="epoch") 71 | points(1:(nrow(loss)), mean_loss, type="l", col="red", lwd=2) 72 | abline(v=which.min(mean_loss), lty=2) 73 | matplot(vloss, type="l", col="black", ..., 74 | ylab="validation loss", xlab="epoch") 75 | points(1:(nrow(vloss)), mean_vloss, type="l", col="red", lwd=2) 76 | abline(v=which.min(mean_vloss), lty=2) 77 | suppressWarnings(par(.pardefault)) 78 | 79 | }else{ 80 | 81 | stop("Not implemented yet.") 82 | 83 | } 84 | 85 | invisible(NULL) 86 | 87 | } 88 | 89 | #' Function to get the stoppting iteration from CV 90 | #' @param res result of cv call 91 | #' @param thisFUN aggregating function applied over folds 92 | #' @param loss which loss to use for decision 93 | #' @param whichFUN which function to use for decision 94 | #' 95 | #' @export 96 | stop_iter_cv_result <- function(res, thisFUN = mean, 97 | loss = "validloss", 98 | whichFUN = which.min) 99 | { 100 | 101 | whichFUN(apply(extract_cv_result(res)[[loss]], 1, FUN=thisFUN)) 102 | 103 | } 104 | 105 | #' Generate folds for CV out of one hot encoded matrix 106 | #' 107 | #' @param mat matrix with columns corresponding to folds 108 | #' and entries corresponding to a one hot encoding 109 | #' @param val_train the value corresponding to train, per default 0 110 | #' @param val_test the value corresponding to test, per default 1 111 | #' 112 | #' @details 113 | #' \code{val_train} and \code{val_test} can both be a set of value 114 | #' 115 | #' @export 116 | make_folds <- function(mat, val_train=0, val_test=1) 117 | { 118 | 119 | apply(mat, 2, function(x){ 120 | list(train = which(x %in% val_train), 121 | test = which(x %in% val_test)) 122 | }) 123 | 124 | } 125 | -------------------------------------------------------------------------------- /R/data_handler.R: -------------------------------------------------------------------------------- 1 | #' Function to loop through parsed formulas and apply data trafo 2 | #' 3 | #' @param pfc list of processor transformed formulas 4 | #' @param newdata list in the same format as the original data 5 | #' @param engine character; the engine which is used to setup the NN (tf or torch) 6 | #' @return list of matrices or arrays 7 | #' 8 | loop_through_pfc_and_call_trafo <- function(pfc, newdata = NULL, engine = "tf") 9 | { 10 | 11 | data_list <- list() 12 | k <- 1 13 | for(i in 1:length(pfc)) 14 | { 15 | 16 | for(j in 1:length(pfc[[i]])){ 17 | 18 | # skip those which are already set up by the gamdata 19 | if(!is.null(pfc[[i]][[j]]$gamdata_nr) & engine == 'tf') 20 | if(!pfc[[i]][[j]]$gamdata_combined) next 21 | 22 | if(is.null(newdata)){ 23 | data_list[[k]] <- to_matrix(pfc[[i]][[j]]$data_trafo()) 24 | }else{ 25 | data_list[[k]] <- to_matrix(pfc[[i]][[j]]$predict_trafo(newdata)) 26 | } 27 | k <- k + 1 28 | } 29 | 30 | 31 | } 32 | 33 | return(data_list) 34 | 35 | 36 | } 37 | 38 | #' Function to prepare data based on parsed formulas 39 | #' 40 | #' @param pfc list of processor transformed formulas 41 | #' @param na_handler function to deal with NAs 42 | #' @param gamdata processor for gam part 43 | #' @param engine the engine which is used to setup the NN (tf or torch) 44 | #' @return list of matrices or arrays 45 | #' @export 46 | #' 47 | prepare_data <- function(pfc, na_handler = na_omit_list, gamdata = NULL, 48 | engine = "tf") 49 | { 50 | 51 | ret_list <- loop_through_pfc_and_call_trafo(pfc = pfc, engine = engine) 52 | if(!is.null(gamdata) & engine == "tf") 53 | ret_list <- c(prepare_gamdata(gamdata), ret_list) 54 | 55 | ret_list <- na_handler(ret_list) 56 | 57 | return(ret_list) 58 | 59 | } 60 | 61 | #' Function to prepare new data based on parsed formulas 62 | #' 63 | #' @param pfc list of processor transformed formulas 64 | #' @param na_handler function to deal with NAs 65 | #' @param newdata list in the same format as the original data 66 | #' @param gamdata processor for gam part 67 | #' @param engine character; the engine which is used to setup the NN (tf or torch) 68 | #' @return list of matrices or arrays 69 | #' @export 70 | #' 71 | prepare_newdata <- function(pfc, newdata, na_handler = na_omit_list, gamdata = NULL, 72 | engine = "tf") 73 | { 74 | 75 | ret_list <- loop_through_pfc_and_call_trafo(pfc = pfc, newdata = newdata, 76 | engine = engine) 77 | 78 | if(!is.null(gamdata) & engine == 'tf') 79 | ret_list <- c(prepare_gamdata(gamdata, newdata), ret_list) 80 | ret_list <- na_handler(ret_list) 81 | 82 | return(ret_list) 83 | 84 | } 85 | 86 | 87 | prepare_gamdata <- function(gamdata, newdata = NULL){ 88 | 89 | if(is.null(newdata)) 90 | return( 91 | unname(lapply(gamdata, function(x) 92 | to_matrix(x$data_trafo()))) 93 | ) 94 | 95 | return( 96 | unname(lapply(gamdata, function(x) 97 | to_matrix(x$predict_trafo(newdata)))) 98 | ) 99 | } 100 | 101 | to_matrix <- function(x) 102 | { 103 | 104 | if(is.list(x)){ 105 | if(length(x)==1 & !is.null(dim(x[[1]]))){ # array as input 106 | return(x[[1]]) 107 | }else{ 108 | return(do.call("cbind", x)) 109 | } 110 | } 111 | if(is.data.frame(x)) return(as.matrix(x)) 112 | return(x) 113 | 114 | } 115 | 116 | #' Function to exclude NA values 117 | #' 118 | #' @param datalist list of data as returned by \code{prepare_data} and 119 | #' \code{prepare_newdata} 120 | #' @return list with NA values excluded and locations of original 121 | #' NA positions as attributes 122 | #' @export 123 | #' 124 | na_omit_list <- function(datalist) 125 | { 126 | 127 | na_loc <- unique(unlist(lapply(datalist, function(x) 128 | unique(apply(x, 2, function(y) which(is.na(y))))))) 129 | 130 | if(length(na_loc) > 0) 131 | datalist <- lapply(datalist, function(x) x[-na_loc,,drop=FALSE]) 132 | attr(datalist, "na_loc") <- na_loc 133 | 134 | return(datalist) 135 | 136 | } -------------------------------------------------------------------------------- /R/dro.R: -------------------------------------------------------------------------------- 1 | # from mboost https://github.com/cran/mboost/blob/master/R/helpers.R 2 | make_psd <- function(x, eps = sqrt(.Machine$double.eps)) { 3 | lambda <- min(eigen(x, only.values = TRUE, symmetric = TRUE)$values) 4 | ## use some additional tolerance to ensure semipositive definite matrices 5 | lambda <- lambda - sqrt(.Machine$double.eps) 6 | # smallest eigenvalue negative = not semipositive definite 7 | if (lambda < -1e-10) { 8 | rho <- 1/(1-lambda) 9 | x <- rho * x + (1-rho) * diag(dim(x)[1]) 10 | ## now check if it is really positive definite by recursively calling 11 | x <- make_psd(x) 12 | } 13 | return(x) 14 | } 15 | 16 | # modified version from mboost 17 | DRO <- function(X, df = 4, lambda = NULL, dmat = NULL, # weights, 18 | svdtype = c("default", "custom"), XtX = NULL, 19 | k = 100, q = 3, hat1 = TRUE, custom_svd_fun = NULL, ...) { 20 | 21 | svdtype <- match.arg(svdtype) 22 | if(svdtype=="custom") svd <- custom_svd_fun 23 | 24 | stopifnot(xor(is.null(df), is.null(lambda))) 25 | if (!is.null(df)) { 26 | rank_X <- rankMatrix(X, method = 'qr', warn.t = FALSE) 27 | if (df >= rank_X) { 28 | if (df > rank_X) 29 | warning("'df'", 30 | " too large:\n Degrees of freedom cannot be larger", 31 | " than the rank of the design matrix.\n", 32 | " Unpenalized base-learner with df = ", 33 | rank_X, " used. Re-consider model specification.") 34 | return(c(df = df, lambda = 0)) 35 | } 36 | } 37 | if (!is.null(lambda)) 38 | if (lambda == 0) 39 | return(c(df = rankMatrix(X), lambda = 0)) 40 | 41 | # Demmler-Reinsch Orthogonalization (cf. Ruppert et al., 2003, 42 | # Semiparametric Regression, Appendix B.1.1). 43 | 44 | ### there may be more efficient ways to compute XtX, but we do this 45 | ### elsewhere (e.g. in %O%) 46 | if (is.null(XtX)) 47 | XtX <- crossprod(X) # * sqrt(weights)) 48 | if (is.null(dmat)) { 49 | if(is(XtX, "Matrix")) diag <- Diagonal 50 | dmat <- diag(ncol(XtX)) 51 | } 52 | ## avoid that XtX matrix is not (numerically) singular 53 | A <- XtX + dmat * 1e-09 54 | ## make sure that A is also numerically positiv semi-definite 55 | A <- make_psd(as.matrix(A)) 56 | ## make sure that A is also numerically symmetric 57 | if (is(A, "Matrix")) 58 | A <- forceSymmetric(A) 59 | Rm <- backsolve(chol(A), x = diag(ncol(XtX))) 60 | ## singular value decomposition without singular vectors 61 | d <- try(svd(crossprod(Rm, dmat) %*% Rm, nu=0, nv=0)$d) 62 | ## if unsucessfull try the same computation but compute singular vectors as well 63 | if (inherits(d, "try-error")) 64 | d <- svd(crossprod(Rm, dmat) %*% Rm)$d 65 | if (hat1) { 66 | dfFun <- function(lambda) sum(1/(1 + lambda * d)) 67 | } 68 | else { 69 | dfFun <- function(lambda) 2 * sum(1/(1 + lambda * d)) - 70 | sum(1/(1 + lambda * d)^2) 71 | } 72 | if (!is.null(lambda)) 73 | return(c(df = dfFun(lambda), lambda = lambda)) 74 | if (df >= length(d)) return(c(df = df, lambda = 0)) 75 | 76 | # search for appropriate lambda using uniroot 77 | df2l <- function(lambda) 78 | dfFun(lambda) - df 79 | 80 | lambdaMax <- 1e+16 81 | 82 | if (df2l(lambdaMax) > 0){ 83 | if (df2l(lambdaMax) > sqrt(.Machine$double.eps)) 84 | return(c(df = df, lambda = lambdaMax)) 85 | } 86 | lambda <- uniroot(df2l, c(0, lambdaMax), tol = sqrt(.Machine$double.eps))$root 87 | if (abs(df2l(lambda)) > sqrt(.Machine$double.eps)) 88 | warning("estimated degrees of freedom differ from ", sQuote("df"), 89 | " by ", df2l(lambda)) 90 | return(c(df = df, lambda = lambda)) 91 | } 92 | -------------------------------------------------------------------------------- /R/models.R: -------------------------------------------------------------------------------- 1 | build_customKeras = function(...) { 2 | python_path <- system.file("python", package = "deepregression") 3 | models <- reticulate::import_from_path("models", path = python_path) 4 | 5 | return(models$build_customKeras(...)) 6 | } 7 | 8 | #' Function to define an optimizer combining multiple optimizers 9 | #' @param optimizers_and_layers a list if \code{tuple}s of optimizer 10 | #' and respective layers 11 | #' @return an optimizer 12 | #' @export 13 | multioptimizer = function(optimizers_and_layers) { 14 | python_path <- system.file("python", package = "deepregression") 15 | opt <- reticulate::import_from_path("optimizers", path = python_path) 16 | 17 | return(opt$MultiOptimizer(optimizers_and_layers)) 18 | } 19 | 20 | -------------------------------------------------------------------------------- /R/nodelayer.R: -------------------------------------------------------------------------------- 1 | #' NODE/ODTs Layer 2 | #' 3 | #' @param name name of the layer 4 | #' @param units number of output dimensions, for regression and binary 5 | #' classification: 1, for mc-classification simply the number of classes 6 | #' @param n_layers number of layers consisting of ODTs in NODE 7 | #' @param n_trees number of trees per layer 8 | #' @param tree_depth depth of tree per layer 9 | #' @param threshold_init_beta parameter(s) for Beta-distribution used for initializing feature thresholds 10 | #' @return layer/model object 11 | #' @export 12 | #' @examples 13 | #' n <- 1000 14 | #' data_regr <- data.frame(matrix(rnorm(4 * n), c(n, 4))) 15 | #' colnames(data_regr) <- c("x0", "x1", "x2", "x3") 16 | #' y_regr <- rnorm(n) + data_regr$x0^2 + data_regr$x1 + 17 | #' data_regr$x2*data_regr$x3 + data_regr$x2 + data_regr$x3 18 | #' 19 | #' library(deepregression) 20 | #' 21 | #' formula_node <- ~ node(x1, x2, x3, x0, n_trees = 2, n_layers = 2, tree_depth = 2) 22 | #' 23 | #' mod_node_regr <- deepregression( 24 | #' list_of_formulas = list(loc = formula_node, scale = ~ 1), 25 | #' data = data_regr, 26 | #' y = y_regr 27 | #' ) 28 | #' 29 | #' if(!is.null(mod_node_regr)){ 30 | #' mod_node_regr %>% fit(epochs = 15, batch_size = 64, verbose = TRUE, 31 | #' validation_split = 0.1, early_stopping = TRUE) 32 | #' mod_node_regr %>% predict() 33 | #' } 34 | #' 35 | layer_node <- function(name, 36 | units, 37 | n_layers = 1L, 38 | n_trees = 1L, 39 | tree_depth = 1L, 40 | threshold_init_beta = 1) { 41 | python_path <- system.file("python", package = "deepregression") 42 | node <- reticulate::import_from_path("node", path = python_path) 43 | return( 44 | node$layer_node( 45 | units = units, 46 | n_layers = n_layers, 47 | n_trees = n_trees, 48 | tree_depth = tree_depth, 49 | threshold_init_beta = threshold_init_beta 50 | ) 51 | ) 52 | } 53 | 54 | #' Extract variables from wrapped node term 55 | #' 56 | #' @param term character; node model term 57 | #' @return reduced variable node model term 58 | #' @export 59 | get_node_term <- function(term) 60 | { 61 | reduced_term <- sub("^(.*?),[^,]*=.*", "\\1", term) 62 | if (!grepl(".*\\)$", reduced_term)) { 63 | reduced_term <- paste0(reduced_term, ")") 64 | } 65 | reduced_term 66 | } 67 | 68 | #' Extract attributes/hyper-parameters of the node term 69 | #' @param term term in formula 70 | #' @param what string specifying what to return 71 | #' @return property of the node specification as defined by \code{what} 72 | #' @export 73 | get_nodedata <- function(term, what) { 74 | if (what == "reduced_term") 75 | return(get_node_term(term)) 76 | else if (what == "n_layers") 77 | return(as.integer( 78 | extractval( 79 | term, 80 | "n_layers", 81 | default_for_missing = T, 82 | default = 1 83 | ) 84 | )) 85 | else if (what == "n_trees") 86 | return(as.integer( 87 | extractval( 88 | term, 89 | "n_trees", 90 | default_for_missing = T, 91 | default = 1 92 | ) 93 | )) 94 | else if (what == "tree_depth") 95 | return(as.integer( 96 | extractval( 97 | term, 98 | "tree_depth", 99 | default_for_missing = T, 100 | default = 1 101 | ) 102 | )) 103 | else if (what == "threshold_init_beta") 104 | return(as.integer( 105 | extractval( 106 | term, 107 | "threshold_init_beta", 108 | default_for_missing = T, 109 | default = 1 110 | ) 111 | )) 112 | } -------------------------------------------------------------------------------- /R/psplinelayer_torch.R: -------------------------------------------------------------------------------- 1 | 2 | 3 | #' Function to define spline as Torch layer 4 | #' 5 | #' @param units integer; number of output units 6 | #' @param P matrix; penalty matrix 7 | #' @param name string; string defining the layer's name 8 | #' @param trainable logical; whether layer is trainable 9 | #' @param kernel_initializer initializer; for basis coefficients 10 | #' @param ... value used for constant kernel initializer 11 | #' @return Torch spline layer 12 | #' @export 13 | layer_spline_torch <- function(P, units = 1L, name, trainable = TRUE, 14 | kernel_initializer = "glorot_uniform", ...){ 15 | 16 | P <- torch::torch_tensor(P) 17 | input_shape <- P$size(1) 18 | 19 | dots <- list(...) 20 | kernel_initializer <- do.call( 21 | choose_kernel_initializer_torch, list(kernel_initializer, 22 | dots$kernel_initializer_value)) 23 | 24 | layer_module <- layer_dense_module(kernel_initializer) 25 | spline_layer <- layer_module(in_features = input_shape, 26 | out_features = units, bias = F) 27 | 28 | spline_layer$parameters$weight$register_hook(function(grad){ 29 | grad + torch::torch_matmul((P+P$t()), spline_layer$weight$t())$t() 30 | }) 31 | 32 | if(!trainable) spline_layer$parameters$weight$requires_grad_(F) 33 | 34 | spline_layer 35 | } 36 | -------------------------------------------------------------------------------- /R/subnetwork_init_torch.R: -------------------------------------------------------------------------------- 1 | #' Initializes a Subnetwork based on the Processed Additive Predictor 2 | #' 3 | #' @param pp list of processed predictor lists from \code{processor} 4 | #' @param deep_top In tf approach: keras layer if the top part of the deep network after orthogonalization; Not yet implemented for torch 5 | #' is different to the one extracted from the provided network 6 | #' @param orthog_fun function used for orthogonalization; Not yet implemented for torch 7 | #' @param split_fun function to split the network to extract head 8 | #' @param shared_layers list defining shared weights within one predictor; 9 | #' each list item is a vector of characters of terms as given in the parameter formula 10 | #' @param param_nr integer number for the distribution parameter 11 | #' @param selectfun_in,selectfun_lay functions defining which subset of pp to 12 | #' take as inputs and layers for this subnetwork; per default the \code{param_nr}'s entry 13 | #' @param gaminputs input tensors for gam terms 14 | #' @param summary_layer torch layer that combines inputs (typically adding or concatenating) 15 | #' @return returns a list of input and output for this additive predictor 16 | #' 17 | #' @export 18 | #' 19 | subnetwork_init_torch <- function(pp, deep_top = NULL, 20 | orthog_fun = NULL, 21 | split_fun = split_model, 22 | shared_layers = NULL, 23 | param_nr = 1, 24 | selectfun_in = function(pp) pp[[param_nr]], 25 | selectfun_lay = function(pp) pp[[param_nr]], 26 | gaminputs, 27 | summary_layer = model_torch) 28 | { 29 | 30 | # subnetwork builder for torch is still rudimentary. It only initializes the 31 | # different layers and names them 32 | # Main difference to the tensorflow approach is that the builder don't has a 33 | # input output flow. So the best idea is to maintain different subnetwork 34 | # builder for the approaches. 35 | 36 | pp_in <- selectfun_in(pp) 37 | pp_lay <- selectfun_lay(pp) 38 | 39 | 40 | layer_matching <- 1:length(pp_in) 41 | names(layer_matching) <- layer_matching 42 | 43 | if(!is.null(shared_layers)) 44 | { 45 | 46 | names_terms <- get_names_pfc(pp_in) 47 | 48 | for(group in shared_layers){ 49 | 50 | layer_ref_nr <- which(names_terms==group[1]) 51 | layer_opts <- get("layer_args", environment(pp_lay[[layer_ref_nr]]$layer)) 52 | layer_opts$name <- paste0("shared_",paste(make_valid_layername(group), collapse = "")) 53 | layer_ref <- do.call(get("layer_class", environment(pp_lay[[layer_ref_nr]]$layer)), 54 | layer_opts) 55 | 56 | terms_replace_layer <- which(names_terms%in%group) 57 | layer_matching[terms_replace_layer] <- layer_ref_nr 58 | 59 | for(i in terms_replace_layer) { 60 | pp_lay[[i]]$layer <- function() layer_ref 61 | pp_lay[[i]]$term <- layer_opts$name 62 | } 63 | } 64 | } 65 | 66 | 67 | if(all(sapply(pp_in, function(x) is.null(x$right_from_oz)))){ 68 | # if there is no term to orthogonalize 69 | outputs <- lapply(1:length(pp_in), function(i){ 70 | pp_lay[[i]]$layer()}) 71 | 72 | names(outputs) <- paste(sapply(1:length(pp_in), 73 | function(i) pp_lay[[i]]$term), param_nr, sep = "_") 74 | summary_layer(outputs) 75 | } else{ 76 | 77 | stop("Orthogonalization not implemented for torch") 78 | } 79 | } -------------------------------------------------------------------------------- /R/tf_helpers.R: -------------------------------------------------------------------------------- 1 | #' Function to index tensors columns 2 | #' 3 | #' @param A tensor 4 | #' @param start first index 5 | #' @param end last index (equals start index if NULL) 6 | #' @return sliced tensor 7 | #' @export 8 | #' 9 | tf_stride_cols <- function(A, start, end=NULL) 10 | { 11 | 12 | stopifnot(start <= end) 13 | if(is.null(end)) end <- start 14 | return( 15 | #tf$strided_slice(A, c(0L,as.integer(start-1)), c(tf$shape(A)[1], as.integer(end))) 16 | tf$keras$layers$Lambda(function(x) x[,as.integer(start):as.integer(end)])(A) 17 | ) 18 | 19 | 20 | } 21 | 22 | #' Function to index tensors last dimension 23 | #' 24 | #' @param A tensor 25 | #' @param start first index 26 | #' @param end last index (equals start index if NULL) 27 | #' @return sliced tensor 28 | #' @export 29 | tf_stride_last_dim_tensor <- function(A, start, end=NULL){ 30 | 31 | stopifnot(start <= end) 32 | if(is.null(end)) end <- start 33 | mat <- as.integer(A$shape) 34 | sz <- mat 35 | sz[length(sz)] <- end-start+1L 36 | return( 37 | tf$slice(A, begin = as.integer(c(rep(0, length(mat)-1), start-1L)), 38 | size = as.integer(sz)) 39 | 40 | ) 41 | 42 | } 43 | 44 | #' Split tensor in multiple parts 45 | #' 46 | #' @param A tensor 47 | #' @param len integer; defines the split lengths 48 | #' @return list of tensors 49 | #' 50 | #' @export 51 | tf_split_multiple <- function(A, len){ 52 | 53 | ends <- cumsum(len) 54 | starts <- c(1, ends[-length(ends)]+1) 55 | lapply(1:length(starts), function(i) tf_stride_cols(A, starts[i], ends[i])) 56 | 57 | } 58 | 59 | # function to convert constant to TF float32 tensor 60 | convertfun_tf <- function(x) tf$constant(x, dtype="float32") 61 | 62 | #' TensorFlow repeat function which is not available for TF 2.0 63 | #' 64 | #' @param a tensor 65 | #' @param dim dimension for repeating 66 | #' 67 | #' @export 68 | #' 69 | tf_repeat <- function(a, dim) 70 | tf$reshape(tf$tile(tf$expand_dims(a, axis = -1L), c(1L, 1L, dim)), 71 | shape = list(-1L, a$shape[[2]]*dim)) 72 | 73 | #' Row-wise tensor product using TensorFlow 74 | #' 75 | #' @param a,b tensor 76 | #' @param ... arguments passed to TensorFlow layer 77 | #' @return a TensorFlow layer 78 | #' 79 | #' @export 80 | #' 81 | tf_row_tensor <- function(a, b, ...) 82 | { 83 | # tf$multiply( 84 | # tf_row_tensor_left_part(a,b), 85 | # tf_row_tensor_right_part(a,b) 86 | # ) 87 | python_path <- system.file("python", package = "deepregression") 88 | tffuns <- reticulate::import_from_path("tffuns", path = python_path) 89 | tffuns$RowTensor(...)(list(a, b)) 90 | } 91 | 92 | tf_row_tensor_left_part <- function(a,b) 93 | { 94 | tf_repeat(a, b$shape[[2]]) 95 | } 96 | 97 | tf_row_tensor_right_part <- function(a,b) 98 | { 99 | tf$tile(b, c(1L, a$shape[[2]])) 100 | } 101 | -------------------------------------------------------------------------------- /R/utils-pipe.R: -------------------------------------------------------------------------------- 1 | #' Pipe operator 2 | #' 3 | #' See \code{magrittr::\link[magrittr:pipe]{\%>\%}} for details. 4 | #' 5 | #' @name %>% 6 | #' @rdname pipe 7 | #' @keywords internal 8 | #' @export 9 | #' @importFrom magrittr %>% 10 | #' @usage lhs \%>\% rhs 11 | NULL 12 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | comment: false 2 | 3 | coverage: 4 | status: 5 | project: 6 | default: 7 | target: auto 8 | threshold: 1% 9 | informational: true 10 | patch: 11 | default: 12 | target: auto 13 | threshold: 1% 14 | informational: true 15 | -------------------------------------------------------------------------------- /inst/CITATION: -------------------------------------------------------------------------------- 1 | bibentry(bibtype = "Article", 2 | title = "{deepregression}: A Flexible Neural Network Framework for Semi-Structured Deep Distributional Regression", 3 | author = c(person(given = "David", family = "R{\\\"u}gamer", email = "david.ruegamer@stat.uni-muenchen.de"), 4 | person(given = "Chris", family = "Kolb"), 5 | person(given = "Cornelius", family = "Fritz"), 6 | person(given = "Florian", family = "Pfisterer"), 7 | person(given = "Philipp", family = "Kopper"), 8 | person(given = "Bernd", family = "Bischl"), 9 | person(given = "Ruolin", family = "Shen"), 10 | person(given = "Christina", family = "Bukas"), 11 | person(given = "Lisa", family = "Barros de Andrade e Sousa"), 12 | person(given = "Dominik", family = "Thalmeier"), 13 | person(given = c("Philipp", "F.", "M."), family = "Baumann"), 14 | person(given = "Lucas", family = "Kook"), 15 | person(given = "Nadja", family = "Klein"), 16 | person(given = c("Christian", "L."), family = "M{\\\"u}ller")), 17 | journal = "Journal of Statistical Software", 18 | year = "2023", 19 | volume = "105", 20 | number = "2", 21 | pages = "1--31", 22 | doi = "10.18637/jss.v105.i02", 23 | header = "To cite deepregression in publications use:" 24 | ) 25 | 26 | -------------------------------------------------------------------------------- /inst/python/activations/__init__.py: -------------------------------------------------------------------------------- 1 | from .sparsemax import * 2 | -------------------------------------------------------------------------------- /inst/python/common/list_handling.py: -------------------------------------------------------------------------------- 1 | def lapply(seq, fun): 2 | 3 | return([fun(x) for x in seq]) 4 | 5 | def remove_nones(x): 6 | 7 | return([x for x in test if x is not None]) 8 | -------------------------------------------------------------------------------- /inst/python/distributions/__init__.py: -------------------------------------------------------------------------------- 1 | from .mvr import * 2 | from .tweedie import * 3 | -------------------------------------------------------------------------------- /inst/python/distributions/__pycache__/__init__.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neural-structured-additive-learning/deepregression/c8ab20de60af4ed81b70d0dc633b8c39e56dd3e2/inst/python/distributions/__pycache__/__init__.cpython-310.pyc -------------------------------------------------------------------------------- /inst/python/distributions/__pycache__/mvr.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neural-structured-additive-learning/deepregression/c8ab20de60af4ed81b70d0dc633b8c39e56dd3e2/inst/python/distributions/__pycache__/mvr.cpython-310.pyc -------------------------------------------------------------------------------- /inst/python/generators/__init__.py: -------------------------------------------------------------------------------- 1 | from .keras_generators import * -------------------------------------------------------------------------------- /inst/python/generators/__pycache__/__init__.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neural-structured-additive-learning/deepregression/c8ab20de60af4ed81b70d0dc633b8c39e56dd3e2/inst/python/generators/__pycache__/__init__.cpython-310.pyc -------------------------------------------------------------------------------- /inst/python/generators/__pycache__/keras_generators.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neural-structured-additive-learning/deepregression/c8ab20de60af4ed81b70d0dc633b8c39e56dd3e2/inst/python/generators/__pycache__/keras_generators.cpython-310.pyc -------------------------------------------------------------------------------- /inst/python/generators/rlayer.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | if (os.getenv('KERAS_IMPLEMENTATION', 'tensorflow') == 'keras'): 4 | from keras.layers import Layer 5 | def shape_filter(shape): 6 | return shape 7 | else: 8 | from tensorflow.keras.layers import Layer 9 | def shape_filter(shape): 10 | if not isinstance(shape, list): 11 | return shape.as_list() 12 | else: 13 | return shape 14 | 15 | 16 | class RLayer(Layer): 17 | 18 | def __init__(self, r_build, r_call, r_compute_output_shape, **kwargs): 19 | super(RLayer, self).__init__(**kwargs) 20 | self.r_build = r_build 21 | self.r_call = r_call 22 | self.r_compute_output_shape = r_compute_output_shape 23 | 24 | def build(self, input_shape): 25 | self.r_build(shape_filter(input_shape)) 26 | super(RLayer, self).build(input_shape) 27 | 28 | def call(self, inputs, mask = None): 29 | return self.r_call(inputs, mask) 30 | 31 | def compute_output_shape(self, input_shape): 32 | 33 | # call R to compute the output shape 34 | output_shape = self.r_compute_output_shape(shape_filter(input_shape)) 35 | 36 | # if it was a list of lists then leave it alone, otherwise force to tuple 37 | # so that R users don't need to explicitly return a tuple 38 | if all(isinstance(x, (tuple,list)) for x in output_shape): 39 | return output_shape 40 | else: 41 | return tuple(output_shape) 42 | -------------------------------------------------------------------------------- /inst/python/layers/__init__.py: -------------------------------------------------------------------------------- 1 | from .lasso import * 2 | from .convlasso import * 3 | # from .bnlasso import * 4 | from .orthogonalization import * 5 | from .randomeffects import * 6 | -------------------------------------------------------------------------------- /inst/python/layers/__pycache__/__init__.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neural-structured-additive-learning/deepregression/c8ab20de60af4ed81b70d0dc633b8c39e56dd3e2/inst/python/layers/__pycache__/__init__.cpython-310.pyc -------------------------------------------------------------------------------- /inst/python/layers/__pycache__/convlasso.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neural-structured-additive-learning/deepregression/c8ab20de60af4ed81b70d0dc633b8c39e56dd3e2/inst/python/layers/__pycache__/convlasso.cpython-310.pyc -------------------------------------------------------------------------------- /inst/python/layers/__pycache__/lasso.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neural-structured-additive-learning/deepregression/c8ab20de60af4ed81b70d0dc633b8c39e56dd3e2/inst/python/layers/__pycache__/lasso.cpython-310.pyc -------------------------------------------------------------------------------- /inst/python/layers/__pycache__/orthogonalization.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neural-structured-additive-learning/deepregression/c8ab20de60af4ed81b70d0dc633b8c39e56dd3e2/inst/python/layers/__pycache__/orthogonalization.cpython-310.pyc -------------------------------------------------------------------------------- /inst/python/layers/orthogonalization.py: -------------------------------------------------------------------------------- 1 | import tensorflow as tf 2 | 3 | def orthog_tf(Y, X): 4 | Q = tf.linalg.qr(X, full_matrices=False, name="QR").q 5 | X_XtXinv_Xt = tf.linalg.matmul(Q, tf.linalg.matrix_transpose(Q)) 6 | return(tf.subtract(Y, tf.linalg.matmul(X_XtXinv_Xt, Y))) 7 | 8 | class Orthogonalization(tf.keras.layers.Layer): 9 | def __init__(self, deactivate_at_test = True, **kwargs): 10 | self.deactivate_at_test = deactivate_at_test 11 | super(Orthogonalization, self).__init__(**kwargs) 12 | 13 | def call(self, Y, X, training=None): 14 | if not self.deactivate_at_test: 15 | return orthog_tf(Y, X) 16 | if training: 17 | return orthog_tf(Y, X) 18 | else: 19 | return Y 20 | 21 | def get_config(self): 22 | 23 | config = super().get_config().copy() 24 | config.update({ 25 | 'deactivate_at_test': self.deactivate_at_test 26 | }) 27 | return config 28 | -------------------------------------------------------------------------------- /inst/python/layers/randomeffects.py: -------------------------------------------------------------------------------- 1 | import tensorflow as tf 2 | import numpy as np 3 | 4 | class RELayer(tf.keras.layers.Layer): 5 | def __init__(self, units, **kwargs): 6 | super(RELayer, self).__init__(**kwargs) 7 | self.units = units 8 | self.b = self.add_weight(name='random_intercept', 9 | shape=(units,), 10 | initializer=tf.keras.initializers.RandomNormal, 11 | trainable=True) 12 | self.logtau = self.add_weight(name='ri_variance', 13 | shape=(), 14 | initializer='zeros', 15 | trainable=True) 16 | 17 | def call(self, inputs, training=False): 18 | # Compute Zb 19 | output = tf.matmul(inputs, tf.reshape(self.b, (-1, 1))) 20 | 21 | if True: 22 | # Compute the log-density 23 | tau_squared = tf.square(tf.math.exp(self.logtau)) 24 | log_density = 0.5 * tf.reduce_sum(tf.square(self.b) / tau_squared) \ 25 | + 0.5 * self.units * tf.math.log(2 * np.pi * tau_squared) 26 | 27 | # Add the log-density to the loss 28 | self.add_loss(log_density) 29 | 30 | return output 31 | -------------------------------------------------------------------------------- /inst/python/models/__init__.py: -------------------------------------------------------------------------------- 1 | from .custom_train_step import * 2 | from .model_trainable_para import * 3 | -------------------------------------------------------------------------------- /inst/python/models/__pycache__/__init__.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neural-structured-additive-learning/deepregression/c8ab20de60af4ed81b70d0dc633b8c39e56dd3e2/inst/python/models/__pycache__/__init__.cpython-310.pyc -------------------------------------------------------------------------------- /inst/python/models/__pycache__/custom_train_step.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neural-structured-additive-learning/deepregression/c8ab20de60af4ed81b70d0dc633b8c39e56dd3e2/inst/python/models/__pycache__/custom_train_step.cpython-310.pyc -------------------------------------------------------------------------------- /inst/python/models/__pycache__/model_trainable_para.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neural-structured-additive-learning/deepregression/c8ab20de60af4ed81b70d0dc633b8c39e56dd3e2/inst/python/models/__pycache__/model_trainable_para.cpython-310.pyc -------------------------------------------------------------------------------- /inst/python/models/custom_train_step.py: -------------------------------------------------------------------------------- 1 | import tensorflow as tf 2 | import numpy as np 3 | import math 4 | from tensorflow import keras 5 | from tensorflow.python.keras.engine import data_adapter 6 | from tensorflow.python.eager import backprop 7 | 8 | def build_customKeras(custom_update = None): 9 | 10 | if(custom_update is None): 11 | # this is just for comparison reasons with default keras routine 12 | 13 | class customKeras(keras.models.Model): 14 | 15 | def train_step(self, data): 16 | data = data_adapter.expand_1d(data) 17 | x, y, sample_weight = data_adapter.unpack_x_y_sample_weight(data) 18 | # Run forward pass. 19 | with backprop.GradientTape() as tape: 20 | y_pred = self(x, training=True) 21 | loss = self.compiled_loss( 22 | y, y_pred, sample_weight, regularization_losses=self.losses) 23 | 24 | # Compute gradients 25 | trainable_vars = self.trainable_variables 26 | gradients = tape.gradient(loss, trainable_vars) 27 | # Update weights 28 | self.optimizer.apply_gradients(zip(gradients, trainable_vars)) 29 | self.compiled_metrics.update_state(y, y_pred, sample_weight) 30 | # Collect metrics to return 31 | return_metrics = {} 32 | for metric in self.metrics: 33 | result = metric.result() 34 | if isinstance(result, dict): 35 | return_metrics.update(result) 36 | else: 37 | return_metrics[metric.name] = result 38 | return return_metrics 39 | 40 | else: 41 | 42 | raise RuntimeError("Not implemented yet.") 43 | 44 | 45 | return(customKeras) 46 | -------------------------------------------------------------------------------- /inst/python/models/helpers.py: -------------------------------------------------------------------------------- 1 | import tensorflow as tf 2 | import tf.keras.layers.InputLayer as layer_input 3 | import tf.keras.layers.Dense as layer_dense 4 | import tf.keras.layers.Add as layer_add 5 | import tf.keras.layers.Concatenate as layer_concatenate 6 | 7 | def create_inputs(list_shapes): 8 | 9 | inputs = [] 10 | for i in range(len(list_shapes)): 11 | nc = list_shapes[i] 12 | if nc==0 or nc is None: 13 | inputs += [None] 14 | else: 15 | inputs += [layer_input(shape = (int(nc))] 16 | 17 | return(inputs) 18 | 19 | def create_offset(offset_inputs): 20 | 21 | ones_initializer = tf.keras.initializers.Ones() 22 | 23 | offset_layers = [] 24 | for i in range(len(offset_inputs)): 25 | 26 | x = offset_inputs[i] 27 | if x is None: 28 | offset_layers += [None] 29 | else: 30 | offset_layers += [layer_dense(units = 1, activation = "linear", use_bias = False, trainable = False, kernel_initializer = ones_initializer)(x)] 31 | 32 | return(offset_layers) 33 | 34 | def create_structured_linear(inp, outdim, name): 35 | 36 | return(layer_dense(units = int(outdim), activation = "linear", use_bias = False, name = name)(inp)) 37 | 38 | def create_mixture_preds(preds, dim): 39 | 40 | mix_prob = preds[:,0] 41 | rest = preds[:,1:] 42 | return(layer_concatenate([layer_dense(units = int(dim), activation = "softmax", use_bias = False)(mix_prob), rest])) 43 | 44 | def 45 | -------------------------------------------------------------------------------- /inst/python/models/model_trainable_para.py: -------------------------------------------------------------------------------- 1 | import tensorflow as tf 2 | from tensorflow.keras import Model 3 | 4 | def create_model_with_param(init_val = [1.0]): 5 | 6 | class ModelwP(Model): 7 | def __init__(self, **kwargs): 8 | super(ModelwP, self).__init__(**kwargs) 9 | self.a = tf.Variable(init_val, name="extra_param") 10 | 11 | def call(self, inputs, training=True, mask=None): 12 | return inputs 13 | 14 | return ModelwP 15 | -------------------------------------------------------------------------------- /inst/python/node/__init__.py: -------------------------------------------------------------------------------- 1 | from .node import * 2 | -------------------------------------------------------------------------------- /inst/python/optimizers/__init__.py: -------------------------------------------------------------------------------- 1 | from .discriminative_layer_training import * 2 | -------------------------------------------------------------------------------- /inst/python/optimizers/__pycache__/__init__.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neural-structured-additive-learning/deepregression/c8ab20de60af4ed81b70d0dc633b8c39e56dd3e2/inst/python/optimizers/__pycache__/__init__.cpython-310.pyc -------------------------------------------------------------------------------- /inst/python/optimizers/__pycache__/discriminative_layer_training.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neural-structured-additive-learning/deepregression/c8ab20de60af4ed81b70d0dc633b8c39e56dd3e2/inst/python/optimizers/__pycache__/discriminative_layer_training.cpython-310.pyc -------------------------------------------------------------------------------- /inst/python/psplines/__init__.py: -------------------------------------------------------------------------------- 1 | from .psplines import * 2 | -------------------------------------------------------------------------------- /inst/python/psplines/__pycache__/__init__.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neural-structured-additive-learning/deepregression/c8ab20de60af4ed81b70d0dc633b8c39e56dd3e2/inst/python/psplines/__pycache__/__init__.cpython-310.pyc -------------------------------------------------------------------------------- /inst/python/psplines/__pycache__/psplines.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neural-structured-additive-learning/deepregression/c8ab20de60af4ed81b70d0dc633b8c39e56dd3e2/inst/python/psplines/__pycache__/psplines.cpython-310.pyc -------------------------------------------------------------------------------- /inst/python/tffuns/__init__.py: -------------------------------------------------------------------------------- 1 | from .tffuns import * 2 | -------------------------------------------------------------------------------- /inst/python/tffuns/__pycache__/__init__.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neural-structured-additive-learning/deepregression/c8ab20de60af4ed81b70d0dc633b8c39e56dd3e2/inst/python/tffuns/__pycache__/__init__.cpython-310.pyc -------------------------------------------------------------------------------- /inst/python/tffuns/__pycache__/tffuns.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/neural-structured-additive-learning/deepregression/c8ab20de60af4ed81b70d0dc633b8c39e56dd3e2/inst/python/tffuns/__pycache__/tffuns.cpython-310.pyc -------------------------------------------------------------------------------- /inst/python/tffuns/tffuns.py: -------------------------------------------------------------------------------- 1 | import tensorflow as tf 2 | import numpy as np 3 | import math 4 | from tensorflow import keras 5 | import tensorflow.keras.regularizers as regularizers 6 | 7 | def tf_repeat(a, dim): 8 | return tf.reshape(tf.tile(tf.expand_dims(a, axis = -1), (1, 1, dim)), 9 | shape = (-1, a.shape[1]*dim)) 10 | 11 | 12 | def tf_row_tensor_left_part(a,b): 13 | return tf_repeat(a, b.shape[1]) 14 | 15 | def tf_row_tensor_right_part(a,b): 16 | return tf.tile(b, (1, a.shape[1])) 17 | 18 | def tf_row_tensor_fun(a,b): 19 | return tf.multiply(tf_row_tensor_left_part(a,b), tf_row_tensor_right_part(a,b)) 20 | 21 | class RowTensor(keras.layers.Layer): 22 | def __init__(self, **kwargs): 23 | super(RowTensor, self).__init__(**kwargs) 24 | 25 | def call(self, inputs): 26 | return tf_row_tensor_fun(inputs[0],inputs[1]) 27 | 28 | -------------------------------------------------------------------------------- /inst/python/utils/__init__.py: -------------------------------------------------------------------------------- 1 | from .types import * 2 | -------------------------------------------------------------------------------- /inst/python/utils/types.py: -------------------------------------------------------------------------------- 1 | # Copyright 2019 The TensorFlow Authors. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | # ============================================================================== 15 | """Types for typing functions signatures.""" 16 | 17 | from typing import Union, Callable, List 18 | 19 | import importlib 20 | import numpy as np 21 | import tensorflow as tf 22 | 23 | from packaging.version import Version 24 | 25 | # TODO: Remove once https://github.com/tensorflow/tensorflow/issues/44613 is resolved 26 | if Version(tf.__version__).release >= Version("2.13").release: 27 | # New versions of Keras require importing from `keras.src` when 28 | # importing internal symbols. 29 | from keras.src.engine import keras_tensor 30 | elif Version(tf.__version__).release >= Version("2.5").release: 31 | from keras.engine import keras_tensor 32 | else: 33 | from tensorflow.python.keras.engine import keras_tensor 34 | 35 | 36 | Number = Union[ 37 | float, 38 | int, 39 | np.float16, 40 | np.float32, 41 | np.float64, 42 | np.int8, 43 | np.int16, 44 | np.int32, 45 | np.int64, 46 | np.uint8, 47 | np.uint16, 48 | np.uint32, 49 | np.uint64, 50 | ] 51 | 52 | Initializer = Union[None, dict, str, Callable, tf.keras.initializers.Initializer] 53 | Regularizer = Union[None, dict, str, Callable, tf.keras.regularizers.Regularizer] 54 | Constraint = Union[None, dict, str, Callable, tf.keras.constraints.Constraint] 55 | Activation = Union[None, str, Callable] 56 | if importlib.util.find_spec("tensorflow.keras.optimizers.legacy") is not None: 57 | Optimizer = Union[ 58 | tf.keras.optimizers.Optimizer, tf.keras.optimizers.legacy.Optimizer, str 59 | ] 60 | else: 61 | Optimizer = Union[tf.keras.optimizers.Optimizer, str] 62 | 63 | TensorLike = Union[ 64 | List[Union[Number, list]], 65 | tuple, 66 | Number, 67 | np.ndarray, 68 | tf.Tensor, 69 | tf.SparseTensor, 70 | tf.Variable, 71 | keras_tensor.KerasTensor, 72 | ] 73 | FloatTensorLike = Union[tf.Tensor, float, np.float16, np.float32, np.float64] 74 | AcceptableDTypes = Union[tf.DType, np.dtype, type, int, str, None] -------------------------------------------------------------------------------- /man/check_and_install.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/zzz.R 3 | \name{check_and_install} 4 | \alias{check_and_install} 5 | \title{Function to check python environment and install necessary packages} 6 | \usage{ 7 | check_and_install(force = FALSE, engine) 8 | } 9 | \arguments{ 10 | \item{force}{if TRUE, forces the installations} 11 | 12 | \item{engine}{character; check if tf(= tensorflow) or torch is available} 13 | } 14 | \value{ 15 | Function that checks if a Python environment is available 16 | and contains TensorFlow. If not the recommended version is installed. 17 | } 18 | \description{ 19 | If you encounter problems with installing the required python modules 20 | please make sure, that a correct python version is configured using 21 | \code{py_discover_config} and change the python version if required. 22 | Internally uses \code{keras::install_keras}. 23 | } 24 | -------------------------------------------------------------------------------- /man/check_input_args_fit.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/torch_helpers.R 3 | \name{check_input_args_fit} 4 | \alias{check_input_args_fit} 5 | \title{Function to check if inputs are supported by corresponding fit function} 6 | \usage{ 7 | check_input_args_fit(args, fit_fun) 8 | } 9 | \arguments{ 10 | \item{args}{list; list of arguments used in fit process} 11 | 12 | \item{fit_fun}{used fit function (e.g. fit.keras.engine.training.Model)} 13 | } 14 | \value{ 15 | stop message if inputs are not supported 16 | } 17 | \description{ 18 | Function to check if inputs are supported by corresponding fit function 19 | } 20 | -------------------------------------------------------------------------------- /man/choose_kernel_initializer_torch.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/layers_torch.R 3 | \name{choose_kernel_initializer_torch} 4 | \alias{choose_kernel_initializer_torch} 5 | \title{Function to choose a kernel initializer for a torch layer} 6 | \usage{ 7 | choose_kernel_initializer_torch(kernel_initializer, value = NULL) 8 | } 9 | \arguments{ 10 | \item{kernel_initializer}{string; initializer} 11 | 12 | \item{value}{numeric; value used for a constant initializer} 13 | } 14 | \value{ 15 | kernel initializer 16 | } 17 | \description{ 18 | Function to choose a kernel initializer for a torch layer 19 | } 20 | -------------------------------------------------------------------------------- /man/coef.drEnsemble.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/deep-ensembles.R 3 | \name{coef.drEnsemble} 4 | \alias{coef.drEnsemble} 5 | \title{Method for extracting ensemble coefficient estimates} 6 | \usage{ 7 | \method{coef}{drEnsemble}(object, which_param = 1, type = NULL, ...) 8 | } 9 | \arguments{ 10 | \item{object}{object of class \code{"drEnsemble"}} 11 | 12 | \item{which_param}{integer, indicating for which distribution parameter 13 | coefficients should be returned (default is first parameter)} 14 | 15 | \item{type}{either NULL (all types of coefficients are returned), 16 | "linear" for linear coefficients or "smooth" for coefficients of 17 | smooth terms} 18 | 19 | \item{...}{further arguments supplied to \code{coef.deepregression}} 20 | } 21 | \value{ 22 | list of coefficient estimates of all ensemble members 23 | } 24 | \description{ 25 | Method for extracting ensemble coefficient estimates 26 | } 27 | -------------------------------------------------------------------------------- /man/collect_distribution_parameters.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/families_torch.R 3 | \name{collect_distribution_parameters} 4 | \alias{collect_distribution_parameters} 5 | \title{Character-to-parameter collection function needed for mixture of same distribution (torch)} 6 | \usage{ 7 | collect_distribution_parameters(family) 8 | } 9 | \arguments{ 10 | \item{family}{character defining the distribution} 11 | } 12 | \value{ 13 | a list of extractions for each supported distribution 14 | } 15 | \description{ 16 | Character-to-parameter collection function needed for mixture of same distribution (torch) 17 | } 18 | -------------------------------------------------------------------------------- /man/combine_penalties.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/helperfuns.R 3 | \name{combine_penalties} 4 | \alias{combine_penalties} 5 | \title{Function to combine two penalties} 6 | \usage{ 7 | combine_penalties(penalties, dims) 8 | } 9 | \arguments{ 10 | \item{penalties}{a list of penalties} 11 | 12 | \item{dims}{dimensions of the parameters to penalize} 13 | } 14 | \value{ 15 | a TensorFlow penalty combining the two penalties 16 | } 17 | \description{ 18 | Function to combine two penalties 19 | } 20 | -------------------------------------------------------------------------------- /man/convenience_layers.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/subnetwork_init.R 3 | \name{layer_add_identity} 4 | \alias{layer_add_identity} 5 | \alias{layer_concatenate_identity} 6 | \title{Convenience layer function} 7 | \usage{ 8 | layer_add_identity(inputs) 9 | 10 | layer_concatenate_identity(inputs) 11 | } 12 | \arguments{ 13 | \item{inputs}{list of tensors} 14 | } 15 | \value{ 16 | tensor 17 | } 18 | \description{ 19 | Convenience layer function 20 | } 21 | \details{ 22 | convenience layers to work with list of inputs where \code{inputs} 23 | can also have length one 24 | } 25 | -------------------------------------------------------------------------------- /man/create_family.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/families.R 3 | \name{create_family} 4 | \alias{create_family} 5 | \title{Function to create (custom) family} 6 | \usage{ 7 | create_family(tfd_dist, trafo_list, output_dim = 1L) 8 | } 9 | \arguments{ 10 | \item{tfd_dist}{a tensorflow probability distribution} 11 | 12 | \item{trafo_list}{list of transformations h for each parameter 13 | (e.g, \code{exp} for a variance parameter)} 14 | 15 | \item{output_dim}{integer defining the size of the response} 16 | } 17 | \value{ 18 | a function that can be used by 19 | \code{tfp$layers$DistributionLambda} to create a new 20 | distribuional layer 21 | } 22 | \description{ 23 | Function to create (custom) family 24 | } 25 | -------------------------------------------------------------------------------- /man/create_family_torch.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/families_torch.R 3 | \name{create_family_torch} 4 | \alias{create_family_torch} 5 | \title{Function to create (custom) family} 6 | \usage{ 7 | create_family_torch(torch_dist, trafo_list, output_dim = 1L) 8 | } 9 | \arguments{ 10 | \item{torch_dist}{a torch probability distribution} 11 | 12 | \item{trafo_list}{list of transformations h for each parameter 13 | (e.g, \code{exp} for a variance parameter)} 14 | 15 | \item{output_dim}{integer defining the size of the response} 16 | } 17 | \value{ 18 | a function that can be used to train a 19 | distribution learning model in torch 20 | } 21 | \description{ 22 | Function to create (custom) family 23 | } 24 | -------------------------------------------------------------------------------- /man/create_penalty.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/psplinelayer.R 3 | \name{create_penalty} 4 | \alias{create_penalty} 5 | \title{Function to create mgcv-type penalty} 6 | \usage{ 7 | create_penalty(evaluated_gam_term, df, controls, Z = NULL) 8 | } 9 | \arguments{ 10 | \item{evaluated_gam_term}{a list resulting from a smoothConstruct call} 11 | 12 | \item{df}{integer; specified degrees-of-freedom for the gam term} 13 | 14 | \item{controls}{list; further arguments defining the smooth} 15 | 16 | \item{Z}{matrix; matrix for constraint(s)} 17 | } 18 | \value{ 19 | a list with penalty parameter and penalty matrix 20 | } 21 | \description{ 22 | Function to create mgcv-type penalty 23 | } 24 | -------------------------------------------------------------------------------- /man/cv.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/methods.R 3 | \name{cv} 4 | \alias{cv} 5 | \title{Generic cv function} 6 | \usage{ 7 | cv(x, ...) 8 | } 9 | \arguments{ 10 | \item{x}{model to do cv on} 11 | 12 | \item{...}{further arguments passed to the class-specific function} 13 | } 14 | \description{ 15 | Generic cv function 16 | } 17 | -------------------------------------------------------------------------------- /man/distfun_to_dist.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/deepregression.R 3 | \name{distfun_to_dist} 4 | \alias{distfun_to_dist} 5 | \title{Function to define output distribution based on dist_fun} 6 | \usage{ 7 | distfun_to_dist(dist_fun, preds) 8 | } 9 | \arguments{ 10 | \item{dist_fun}{a distribution function as defined by \code{make_tfd_dist}} 11 | 12 | \item{preds}{tensors with predictions} 13 | } 14 | \value{ 15 | a symbolic tfp distribution 16 | } 17 | \description{ 18 | Function to define output distribution based on dist_fun 19 | } 20 | -------------------------------------------------------------------------------- /man/dr_families.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/families.R, R/families_torch.R 3 | \name{make_tfd_dist} 4 | \alias{make_tfd_dist} 5 | \alias{make_torch_dist} 6 | \title{Families for deepregression} 7 | \usage{ 8 | make_tfd_dist(family, add_const = 1e-08, output_dim = 1L, trafo_list = NULL) 9 | 10 | make_torch_dist(family, add_const = 1e-08, output_dim = 1L, trafo_list = NULL) 11 | } 12 | \arguments{ 13 | \item{family}{character vector} 14 | 15 | \item{add_const}{small positive constant to stabilize calculations} 16 | 17 | \item{output_dim}{number of output dimensions of the response (larger 1 for 18 | multivariate case) (not implemented yet)} 19 | 20 | \item{trafo_list}{list of transformations for each distribution parameter. 21 | Per default the transformation listed in details is applied.} 22 | } 23 | \description{ 24 | Families for deepregression 25 | 26 | Families for deepregression 27 | } 28 | \details{ 29 | To specify a custom distribution, define the a function as follows 30 | \code{ 31 | function(x) do.call(your_tfd_dist, lapply(1:ncol(x)[[1]], 32 | function(i) 33 | your_trafo_list_on_inputs[[i]]( 34 | x[,i,drop=FALSE]))) 35 | } 36 | and pass it to \code{deepregression} via the \code{dist_fun} argument. 37 | Currently the following distributions are supported 38 | with parameters (and corresponding inverse link function in brackets): 39 | 40 | \itemize{ 41 | \item \code{"normal"} : normal distribution with location (identity), scale (exp) 42 | \item \code{"bernoulli"} : bernoulli distribution with logits (identity) 43 | \item \code{"bernoulli_prob"} : bernoulli distribution with probabilities (sigmoid) 44 | \item \code{"beta"} : beta with concentration 1 = alpha (exp) and concentration 45 | 0 = beta (exp) 46 | \item \code{"betar"} : beta with mean (sigmoid) and scale (sigmoid) 47 | \item \code{"cauchy"} : location (identity), scale (exp) 48 | \item \code{"chi2"} : cauchy with df (exp) 49 | \item \code{"chi"} : cauchy with df (exp) 50 | \item \code{"exponential"} : exponential with lambda (exp) 51 | \item \code{"gamma"} : gamma with concentration (exp) and rate (exp) 52 | \item \code{"gammar"} : gamma with location (exp) and scale (exp), following 53 | \code{gamlss.dist::GA}, which implies that the expectation is the location, 54 | and the variance of the distribution is the \code{location^2 scale^2} 55 | \item \code{"gumbel"} : gumbel with location (identity), scale (exp) 56 | \item \code{"half_cauchy"} : half cauchy with location (identity), scale (exp) 57 | \item \code{"half_normal"} : half normal with scale (exp) 58 | \item \code{"horseshoe"} : horseshoe with scale (exp) 59 | \item \code{"inverse_gamma"} : inverse gamma with concentation (exp) and rate (exp) 60 | \item \code{"inverse_gamma_ls"} : inverse gamma with location (exp) and variance (1/exp) 61 | \item \code{"inverse_gaussian"} : inverse Gaussian with location (exp) and concentation 62 | (exp) 63 | \item \code{"laplace"} : Laplace with location (identity) and scale (exp) 64 | \item \code{"log_normal"} : Log-normal with location (identity) and scale (exp) of 65 | underlying normal distribution 66 | \item \code{"logistic"} : logistic with location (identity) and scale (exp) 67 | \item \code{"negbinom"} : neg. binomial with count (exp) and prob (sigmoid) 68 | \item \code{"negbinom_ls"} : neg. binomail with mean (exp) and clutter factor (exp) 69 | \item \code{"pareto"} : Pareto with concentration (exp) and scale (1/exp) 70 | \item \code{"pareto_ls"} : Pareto location scale version with mean (exp) 71 | and scale (exp), which corresponds to a Pareto distribution with parameters scale = mean 72 | and concentration = 1/sigma, where sigma is the scale in the pareto_ls version 73 | \item \code{"poisson"} : poisson with rate (exp) 74 | \item \code{"poisson_lograte"} : poisson with lograte (identity)) 75 | \item \code{"student_t"} : Student's t with df (exp) 76 | \item \code{"student_t_ls"} : Student's t with df (exp), location (identity) and 77 | scale (exp) 78 | \item \code{"uniform"} : uniform with upper and lower (both identity) 79 | \item \code{"zinb"} : Zero-inflated negative binomial with mean (exp), 80 | variance (exp) and prob (sigmoid) 81 | \item \code{"zip": } Zero-inflated poisson distribution with mean (exp) and prob (sigmoid) 82 | } 83 | 84 | To specify a custom distribution, define the a function as follows 85 | \code{ 86 | function(x) do.call(your_tfd_dist, lapply(1:ncol(x)[[1]], 87 | function(i) 88 | your_trafo_list_on_inputs[[i]]( 89 | x[,i,drop=FALSE]))) 90 | } 91 | and pass it to \code{deepregression} via the \code{dist_fun} argument. 92 | Currently the following distributions are supported 93 | with parameters (and corresponding inverse link function in brackets): 94 | 95 | \itemize{ 96 | \item \code{"normal"} : normal distribution with location (identity), scale (exp) 97 | \item \code{"bernoulli"} : bernoulli distribution with logits (identity) 98 | \item \code{"exponential"} : exponential with lambda (exp) 99 | \item \code{"gamma"} : gamma with concentration (exp) and rate (exp) 100 | \item \code{"poisson"} : poisson with rate (exp) 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /man/ensemble.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/deep-ensembles.R 3 | \name{ensemble} 4 | \alias{ensemble} 5 | \title{Generic deep ensemble function} 6 | \usage{ 7 | ensemble(x, ...) 8 | } 9 | \arguments{ 10 | \item{x}{model to ensemble} 11 | 12 | \item{...}{further arguments passed to the class-specific function} 13 | } 14 | \description{ 15 | Generic deep ensemble function 16 | } 17 | -------------------------------------------------------------------------------- /man/ensemble.deepregression.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/deep-ensembles.R 3 | \name{ensemble.deepregression} 4 | \alias{ensemble.deepregression} 5 | \title{Ensembling deepregression models} 6 | \usage{ 7 | \method{ensemble}{deepregression}( 8 | x, 9 | n_ensemble = 5, 10 | reinitialize = TRUE, 11 | mylapply = lapply, 12 | verbose = FALSE, 13 | patience = 20, 14 | plot = TRUE, 15 | print_members = TRUE, 16 | stop_if_nan = TRUE, 17 | save_weights = TRUE, 18 | callbacks = list(), 19 | save_fun = NULL, 20 | seed = seq_len(n_ensemble), 21 | ... 22 | ) 23 | } 24 | \arguments{ 25 | \item{x}{object of class \code{"deepregression"} to ensemble} 26 | 27 | \item{n_ensemble}{numeric; number of ensemble members to fit} 28 | 29 | \item{reinitialize}{logical; if \code{TRUE} (default), model weights are 30 | initialized randomly prior to fitting each member. Fixed weights are 31 | not affected} 32 | 33 | \item{mylapply}{lapply function to be used; defaults to \code{lapply}} 34 | 35 | \item{verbose}{whether to print training in each fold} 36 | 37 | \item{patience}{number of patience for early stopping} 38 | 39 | \item{plot}{whether to plot the resulting losses in each fold} 40 | 41 | \item{print_members}{logical; print results for each member} 42 | 43 | \item{stop_if_nan}{logical; whether to stop CV if NaN values occur} 44 | 45 | \item{save_weights}{whether to save final weights of each ensemble member; 46 | defaults to \code{TRUE}} 47 | 48 | \item{callbacks}{a list of callbacks used for fitting} 49 | 50 | \item{save_fun}{function applied to the model in each fold to be stored in 51 | the final result} 52 | 53 | \item{seed}{seed for reproducibility} 54 | 55 | \item{...}{further arguments passed to \code{object$fit_fun}} 56 | } 57 | \value{ 58 | object of class \code{"drEnsemble"}, containing the original 59 | \code{"deepregression"} model together with a list of ensembling 60 | results (training history and, if \code{save_weights} is \code{TRUE}, 61 | the trained weights of each ensemble member) 62 | } 63 | \description{ 64 | Ensembling deepregression models 65 | } 66 | -------------------------------------------------------------------------------- /man/extract_S.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/psplinelayer.R 3 | \name{extract_S} 4 | \alias{extract_S} 5 | \title{Convenience function to extract penalty matrix and value} 6 | \usage{ 7 | extract_S(x) 8 | } 9 | \arguments{ 10 | \item{x}{evaluated smooth term object} 11 | } 12 | \description{ 13 | Convenience function to extract penalty matrix and value 14 | } 15 | -------------------------------------------------------------------------------- /man/extract_pure_gam_part.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/psplinelayer.R 3 | \name{extract_pure_gam_part} 4 | \alias{extract_pure_gam_part} 5 | \title{Extract the smooth term from a deepregression term specification} 6 | \usage{ 7 | extract_pure_gam_part(term, remove_other_options = TRUE) 8 | } 9 | \arguments{ 10 | \item{term}{term specified in a formula} 11 | 12 | \item{remove_other_options}{logical; whether to remove other options 13 | withing the smooth term} 14 | } 15 | \value{ 16 | pure gam part of term 17 | } 18 | \description{ 19 | Extract the smooth term from a deepregression term specification 20 | } 21 | -------------------------------------------------------------------------------- /man/extractvar.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/formula_helpers.R 3 | \name{extractvar} 4 | \alias{extractvar} 5 | \title{Extract variable from term} 6 | \usage{ 7 | extractvar(term, allow_ia = FALSE) 8 | } 9 | \arguments{ 10 | \item{term}{term specified in formula} 11 | 12 | \item{allow_ia}{logical; whether to allow interaction of terms 13 | using the \code{:} notation} 14 | } 15 | \value{ 16 | variable as string 17 | } 18 | \description{ 19 | Extract variable from term 20 | } 21 | -------------------------------------------------------------------------------- /man/family_to_tfd.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/families.R 3 | \name{family_to_tfd} 4 | \alias{family_to_tfd} 5 | \title{Character-tfd mapping function} 6 | \usage{ 7 | family_to_tfd(family) 8 | } 9 | \arguments{ 10 | \item{family}{character defining the distribution} 11 | } 12 | \value{ 13 | a tfp distribution 14 | } 15 | \description{ 16 | Character-tfd mapping function 17 | } 18 | -------------------------------------------------------------------------------- /man/family_to_trafo.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/families.R 3 | \name{family_to_trafo} 4 | \alias{family_to_trafo} 5 | \title{Character-to-transformation mapping function} 6 | \usage{ 7 | family_to_trafo(family, add_const = 1e-08) 8 | } 9 | \arguments{ 10 | \item{family}{character defining the distribution} 11 | 12 | \item{add_const}{see \code{\link{make_tfd_dist}}} 13 | } 14 | \value{ 15 | a list of transformation for each distribution parameter 16 | } 17 | \description{ 18 | Character-to-transformation mapping function 19 | } 20 | -------------------------------------------------------------------------------- /man/family_to_trafo_torch.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/families_torch.R 3 | \name{family_to_trafo_torch} 4 | \alias{family_to_trafo_torch} 5 | \title{Character-to-transformation mapping function} 6 | \usage{ 7 | family_to_trafo_torch(family, add_const = 1e-08) 8 | } 9 | \arguments{ 10 | \item{family}{character defining the distribution} 11 | 12 | \item{add_const}{see \code{\link{make_torch_dist}}} 13 | } 14 | \value{ 15 | a list of transformation for each distribution parameter 16 | } 17 | \description{ 18 | Character-to-transformation mapping function 19 | } 20 | -------------------------------------------------------------------------------- /man/family_to_trochd.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/families_torch.R 3 | \name{family_to_trochd} 4 | \alias{family_to_trochd} 5 | \title{Character-torch mapping function} 6 | \usage{ 7 | family_to_trochd(family) 8 | } 9 | \arguments{ 10 | \item{family}{character defining the distribution} 11 | } 12 | \value{ 13 | a torch distribution 14 | } 15 | \description{ 16 | Character-torch mapping function 17 | } 18 | -------------------------------------------------------------------------------- /man/fitted.drEnsemble.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/deep-ensembles.R 3 | \name{fitted.drEnsemble} 4 | \alias{fitted.drEnsemble} 5 | \title{Method for extracting the fitted values of an ensemble} 6 | \usage{ 7 | \method{fitted}{drEnsemble}(object, apply_fun = tfd_mean, ...) 8 | } 9 | \arguments{ 10 | \item{object}{a deepregression model} 11 | 12 | \item{apply_fun}{function applied to fitted distribution, 13 | per default \code{tfd_mean}} 14 | 15 | \item{...}{arguments passed to the \code{predict} function} 16 | } 17 | \value{ 18 | list of fitted values for each ensemble member 19 | } 20 | \description{ 21 | Method for extracting the fitted values of an ensemble 22 | } 23 | -------------------------------------------------------------------------------- /man/form_control.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/controls.R 3 | \name{form_control} 4 | \alias{form_control} 5 | \title{Options for formula parsing} 6 | \usage{ 7 | form_control(precalculate_gamparts = TRUE, check_form = TRUE) 8 | } 9 | \arguments{ 10 | \item{precalculate_gamparts}{logical; if TRUE (default), additive parts are pre-calculated 11 | and can later be used more efficiently. Set to FALSE only if no smooth effects are in the 12 | formula(s) and a formula is very large so that extracting all terms takes long or might fail} 13 | 14 | \item{check_form}{logical; if TRUE (default), the formula is checked in \code{process_terms}} 15 | } 16 | \value{ 17 | Returns a list with options 18 | } 19 | \description{ 20 | Options for formula parsing 21 | } 22 | -------------------------------------------------------------------------------- /man/formulaHelpers.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/formula_helpers.R 3 | \name{extractval} 4 | \alias{extractval} 5 | \alias{extractvals} 6 | \alias{extractlen} 7 | \alias{form2text} 8 | \title{Formula helpers} 9 | \usage{ 10 | extractval(term, name, default_for_missing = FALSE, default = NULL) 11 | 12 | extractvals(term, names) 13 | 14 | extractlen(term, data) 15 | 16 | form2text(form) 17 | } 18 | \arguments{ 19 | \item{term}{formula term} 20 | 21 | \item{name}{character; the value to extract} 22 | 23 | \item{default_for_missing}{logical; if TRUE, returns \code{default} if argument is missing} 24 | 25 | \item{default}{value returned when missing} 26 | 27 | \item{names}{character vector of names} 28 | 29 | \item{data}{a data.frame or list} 30 | 31 | \item{form}{formula that is converted to a character string} 32 | } 33 | \value{ 34 | the value used for \code{name} 35 | } 36 | \description{ 37 | Formula helpers 38 | 39 | Extractval with multiple options 40 | } 41 | \examples{ 42 | extractval("s(a, la = 2)", "la") 43 | 44 | } 45 | -------------------------------------------------------------------------------- /man/from_dist_to_loss.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/deepregression.R 3 | \name{from_dist_to_loss} 4 | \alias{from_dist_to_loss} 5 | \title{Function to transform a distritbution layer output into a loss function} 6 | \usage{ 7 | from_dist_to_loss( 8 | family, 9 | ind_fun = function(x) tfd_independent(x), 10 | weights = NULL 11 | ) 12 | } 13 | \arguments{ 14 | \item{family}{see \code{?deepregression}} 15 | 16 | \item{ind_fun}{function applied to the model output before calculating the 17 | log-likelihood. Per default independence is assumed by applying \code{tfd_independent}.} 18 | 19 | \item{weights}{sample weights} 20 | } 21 | \value{ 22 | loss function 23 | } 24 | \description{ 25 | Function to transform a distritbution layer output into a loss function 26 | } 27 | -------------------------------------------------------------------------------- /man/from_dist_to_loss_torch.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/deepregression_torch.R 3 | \name{from_dist_to_loss_torch} 4 | \alias{from_dist_to_loss_torch} 5 | \title{Function to transform a distribution layer output into a loss function} 6 | \usage{ 7 | from_dist_to_loss_torch(family, weights = NULL) 8 | } 9 | \arguments{ 10 | \item{family}{see \code{?deepregression}} 11 | 12 | \item{weights}{sample weights} 13 | } 14 | \value{ 15 | loss function 16 | } 17 | \description{ 18 | Function to transform a distribution layer output into a loss function 19 | } 20 | -------------------------------------------------------------------------------- /man/from_distfun_to_dist_torch.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/deepregression_torch.R 3 | \name{from_distfun_to_dist_torch} 4 | \alias{from_distfun_to_dist_torch} 5 | \title{Function to define output distribution based on dist_fun} 6 | \usage{ 7 | from_distfun_to_dist_torch(dist_fun, preds) 8 | } 9 | \arguments{ 10 | \item{dist_fun}{a distribution function as defined by \code{make_torch_dist}} 11 | 12 | \item{preds}{tensors with predictions} 13 | } 14 | \value{ 15 | a symbolic torch distribution 16 | } 17 | \description{ 18 | Function to define output distribution based on dist_fun 19 | } 20 | -------------------------------------------------------------------------------- /man/from_preds_to_dist.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/deepregression.R 3 | \name{from_preds_to_dist} 4 | \alias{from_preds_to_dist} 5 | \title{Define Predictor of a Deep Distributional Regression Model} 6 | \usage{ 7 | from_preds_to_dist( 8 | list_pred_param, 9 | family = NULL, 10 | output_dim = 1L, 11 | mapping = NULL, 12 | from_family_to_distfun = make_tfd_dist, 13 | from_distfun_to_dist = distfun_to_dist, 14 | add_layer_shared_pred = function(x, units) layer_dense(x, units = units, use_bias = 15 | FALSE), 16 | trafo_list = NULL 17 | ) 18 | } 19 | \arguments{ 20 | \item{list_pred_param}{list of input-output(-lists) generated from 21 | \code{subnetwork_init}} 22 | 23 | \item{family}{see \code{?deepregression}; if NULL, concatenated 24 | \code{list_pred_param} entries are returned (after applying mapping if provided)} 25 | 26 | \item{output_dim}{dimension of the output} 27 | 28 | \item{mapping}{a list of integers. The i-th list item defines which element 29 | elements of \code{list_pred_param} are used for the i-th parameter. 30 | For example, \code{mapping = list(1,2,1:2)} means that \code{list_pred_param[[1]]} 31 | is used for the first distribution parameter, \code{list_pred_param[[2]]} for 32 | the second distribution parameter and \code{list_pred_param[[3]]} for both 33 | distribution parameters (and then added once to \code{list_pred_param[[1]]} and 34 | once to \code{list_pred_param[[2]]})} 35 | 36 | \item{from_family_to_distfun}{function to create a \code{dist_fun} 37 | (see \code{?distfun_to_dist}) from the given character \code{family}} 38 | 39 | \item{from_distfun_to_dist}{function creating a tfp distribution based on the 40 | prediction tensors and \code{dist_fun}. See \code{?distfun_to_dist}} 41 | 42 | \item{add_layer_shared_pred}{layer to extend shared layers defined in \code{mapping}} 43 | 44 | \item{trafo_list}{a list of transformation function to convert the scale of the 45 | additive predictors to the respective distribution parameter} 46 | } 47 | \value{ 48 | a list with input tensors and output tensors that can be passed 49 | to, e.g., \code{keras_model} 50 | } 51 | \description{ 52 | Define Predictor of a Deep Distributional Regression Model 53 | } 54 | -------------------------------------------------------------------------------- /man/from_preds_to_dist_torch.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/deepregression_torch.R 3 | \name{from_preds_to_dist_torch} 4 | \alias{from_preds_to_dist_torch} 5 | \title{Define Predictor of a Deep Distributional Regression Model} 6 | \usage{ 7 | from_preds_to_dist_torch( 8 | list_pred_param, 9 | family = NULL, 10 | output_dim = 1L, 11 | mapping = NULL, 12 | from_family_to_distfun = make_torch_dist, 13 | from_distfun_to_dist = from_distfun_to_dist_torch, 14 | add_layer_shared_pred = function(input_shape, units) layer_dense_torch(input_shape = 15 | input_shape, units = units, use_bias = FALSE), 16 | trafo_list = NULL 17 | ) 18 | } 19 | \arguments{ 20 | \item{list_pred_param}{list of output(-lists) generated from 21 | \code{subnetwork_init}} 22 | 23 | \item{family}{see \code{?deepregression}; if NULL, concatenated 24 | \code{list_pred_param} entries are returned (after applying mapping if provided)} 25 | 26 | \item{output_dim}{dimension of the output} 27 | 28 | \item{mapping}{a list of integers. The i-th list item defines which element 29 | elements of \code{list_pred_param} are used for the i-th parameter. 30 | For example, \code{mapping = list(1,2,1:2)} means that \code{list_pred_param[[1]]} 31 | is used for the first distribution parameter, \code{list_pred_param[[2]]} for 32 | the second distribution parameter and \code{list_pred_param[[3]]} for both 33 | distribution parameters (and then added once to \code{list_pred_param[[1]]} and 34 | once to \code{list_pred_param[[2]]})} 35 | 36 | \item{from_family_to_distfun}{function to create a \code{dist_fun} 37 | (see \code{?distfun_to_dist}) from the given character \code{family}} 38 | 39 | \item{from_distfun_to_dist}{function creating a torch distribution based on the 40 | prediction tensors and \code{dist_fun}. See \code{?distfun_to_dist}} 41 | 42 | \item{add_layer_shared_pred}{layer to extend shared layers defined in \code{mapping}} 43 | 44 | \item{trafo_list}{a list of transformation function to convert the scale of the 45 | additive predictors to the respective distribution parameter} 46 | } 47 | \value{ 48 | a list with input tensors and output tensors that can be passed 49 | to, e.g., \code{torch_model} 50 | } 51 | \description{ 52 | Define Predictor of a Deep Distributional Regression Model 53 | } 54 | -------------------------------------------------------------------------------- /man/gam_plot_data.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/psplinelayer.R 3 | \name{gam_plot_data} 4 | \alias{gam_plot_data} 5 | \title{used by gam_processor} 6 | \usage{ 7 | gam_plot_data(pp, weights, grid_length = 40, pe_fun = pe_gen) 8 | } 9 | \arguments{ 10 | \item{pp}{processed term} 11 | 12 | \item{weights}{layer weights} 13 | 14 | \item{grid_length}{length for grid for evaluating basis} 15 | 16 | \item{pe_fun}{function used to generate partial effects} 17 | } 18 | \description{ 19 | used by gam_processor 20 | } 21 | -------------------------------------------------------------------------------- /man/get_distribution.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/methods.R 3 | \name{get_distribution} 4 | \alias{get_distribution} 5 | \title{Function to return the fitted distribution} 6 | \usage{ 7 | get_distribution(x, data = NULL, force_float = FALSE) 8 | } 9 | \arguments{ 10 | \item{x}{the fitted deepregression object} 11 | 12 | \item{data}{an optional data set} 13 | 14 | \item{force_float}{forces conversion into float tensors} 15 | } 16 | \description{ 17 | Function to return the fitted distribution 18 | } 19 | -------------------------------------------------------------------------------- /man/get_ensemble_distribution.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/deep-ensembles.R 3 | \name{get_ensemble_distribution} 4 | \alias{get_ensemble_distribution} 5 | \title{Obtain the conditional ensemble distribution} 6 | \usage{ 7 | get_ensemble_distribution(object, data = NULL, topK = NULL, ...) 8 | } 9 | \arguments{ 10 | \item{object}{object of class \code{"drEnsemble"}} 11 | 12 | \item{data}{data for which to return the fitted distribution} 13 | 14 | \item{topK}{not implemented yet} 15 | 16 | \item{...}{further arguments currently ignored} 17 | } 18 | \value{ 19 | \code{tfd_distribution} of the ensemble, i.e., a mixture of the 20 | ensemble member's predicted distributions conditional on \code{data} 21 | } 22 | \description{ 23 | Obtain the conditional ensemble distribution 24 | } 25 | -------------------------------------------------------------------------------- /man/get_gam_part.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/psplinelayer.R 3 | \name{get_gam_part} 4 | \alias{get_gam_part} 5 | \title{Extract gam part from wrapped term} 6 | \usage{ 7 | get_gam_part(term, wrapper = "vc") 8 | } 9 | \arguments{ 10 | \item{term}{character; gam model term} 11 | 12 | \item{wrapper}{character; function name that is wrapped around the gam part} 13 | } 14 | \description{ 15 | Extract gam part from wrapped term 16 | } 17 | -------------------------------------------------------------------------------- /man/get_gamdata.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/psplinelayer.R 3 | \name{get_gamdata} 4 | \alias{get_gamdata} 5 | \title{Extract property of gamdata} 6 | \usage{ 7 | get_gamdata( 8 | term, 9 | param_nr, 10 | gamdata, 11 | what = c("data_trafo", "predict_trafo", "input_dim", "partial_effect", "sp_and_S", 12 | "df") 13 | ) 14 | } 15 | \arguments{ 16 | \item{term}{term in formula} 17 | 18 | \item{param_nr}{integer; number of the distribution parameter} 19 | 20 | \item{gamdata}{list as returned by \code{precalc_gam}} 21 | 22 | \item{what}{string specifying what to return} 23 | } 24 | \value{ 25 | property of the gamdata object as defined by \code{what} 26 | } 27 | \description{ 28 | Extract property of gamdata 29 | } 30 | -------------------------------------------------------------------------------- /man/get_gamdata_reduced_nr.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/psplinelayer.R 3 | \name{get_gamdata_reduced_nr} 4 | \alias{get_gamdata_reduced_nr} 5 | \title{Extract number in matching table of reduced gam term} 6 | \usage{ 7 | get_gamdata_reduced_nr(term, param_nr, gamdata) 8 | } 9 | \arguments{ 10 | \item{term}{term in formula} 11 | 12 | \item{param_nr}{integer; number of the distribution parameter} 13 | 14 | \item{gamdata}{list as returned by \code{precalc_gam}} 15 | } 16 | \value{ 17 | integer with number of gam term in matching table 18 | } 19 | \description{ 20 | Extract number in matching table of reduced gam term 21 | } 22 | -------------------------------------------------------------------------------- /man/get_help_forward_torch.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/torch_helpers.R 3 | \name{get_help_forward_torch} 4 | \alias{get_help_forward_torch} 5 | \title{Helper function to calculate amount of layers 6 | Needed when shared layers are used, because of layers have same names} 7 | \usage{ 8 | get_help_forward_torch(list_pred_param) 9 | } 10 | \arguments{ 11 | \item{list_pred_param}{list; subnetworks} 12 | } 13 | \value{ 14 | layers 15 | } 16 | \description{ 17 | Helper function to calculate amount of layers 18 | Needed when shared layers are used, because of layers have same names 19 | } 20 | -------------------------------------------------------------------------------- /man/get_layer_by_opname.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/helperfuns.R 3 | \name{get_layer_by_opname} 4 | \alias{get_layer_by_opname} 5 | \title{Function to return layer given model and name} 6 | \usage{ 7 | get_layer_by_opname(mod, name, partial_match = FALSE) 8 | } 9 | \arguments{ 10 | \item{mod}{deepregression model} 11 | 12 | \item{name}{character} 13 | 14 | \item{partial_match}{logical; whether to also check for a partial match} 15 | } 16 | \description{ 17 | Function to return layer given model and name 18 | } 19 | -------------------------------------------------------------------------------- /man/get_layernr_by_opname.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/helperfuns.R 3 | \name{get_layernr_by_opname} 4 | \alias{get_layernr_by_opname} 5 | \title{Function to return layer number given model and name} 6 | \usage{ 7 | get_layernr_by_opname(mod, name, partial_match = FALSE) 8 | } 9 | \arguments{ 10 | \item{mod}{deepregression model} 11 | 12 | \item{name}{character} 13 | 14 | \item{partial_match}{logical; whether to also check for a partial match} 15 | } 16 | \description{ 17 | Function to return layer number given model and name 18 | } 19 | -------------------------------------------------------------------------------- /man/get_layernr_trainable.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/helperfuns.R 3 | \name{get_layernr_trainable} 4 | \alias{get_layernr_trainable} 5 | \title{Function to return layer numbers with trainable weights} 6 | \usage{ 7 | get_layernr_trainable(mod, logic = FALSE) 8 | } 9 | \arguments{ 10 | \item{mod}{deepregression model} 11 | 12 | \item{logic}{logical; TRUE: return logical vector; FALSE (default) index} 13 | } 14 | \description{ 15 | Function to return layer numbers with trainable weights 16 | } 17 | -------------------------------------------------------------------------------- /man/get_luz_dataset.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/torch_helpers.R 3 | \name{get_luz_dataset} 4 | \alias{get_luz_dataset} 5 | \title{Helper function to create an function that generates R6 instances of 6 | class dataset} 7 | \usage{ 8 | get_luz_dataset(df_list, target = NULL, length = NULL, object) 9 | } 10 | \arguments{ 11 | \item{df_list}{list; data for the distribution learning model (data for every distributional parameter)} 12 | 13 | \item{target}{vector; target value} 14 | 15 | \item{length}{amount of inputs} 16 | 17 | \item{object}{deepregression object} 18 | } 19 | \value{ 20 | R6 instances of class dataset 21 | } 22 | \description{ 23 | Helper function to create an function that generates R6 instances of 24 | class dataset 25 | } 26 | -------------------------------------------------------------------------------- /man/get_names_pfc.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/helperfuns.R 3 | \name{get_names_pfc} 4 | \alias{get_names_pfc} 5 | \title{Extract term names from the parsed formula content} 6 | \usage{ 7 | get_names_pfc(pfc) 8 | } 9 | \arguments{ 10 | \item{pfc}{parsed formula content} 11 | } 12 | \value{ 13 | vector of term names 14 | } 15 | \description{ 16 | Extract term names from the parsed formula content 17 | } 18 | -------------------------------------------------------------------------------- /man/get_node_term.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/nodelayer.R 3 | \name{get_node_term} 4 | \alias{get_node_term} 5 | \title{Extract variables from wrapped node term} 6 | \usage{ 7 | get_node_term(term) 8 | } 9 | \arguments{ 10 | \item{term}{character; node model term} 11 | } 12 | \value{ 13 | reduced variable node model term 14 | } 15 | \description{ 16 | Extract variables from wrapped node term 17 | } 18 | -------------------------------------------------------------------------------- /man/get_nodedata.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/nodelayer.R 3 | \name{get_nodedata} 4 | \alias{get_nodedata} 5 | \title{Extract attributes/hyper-parameters of the node term} 6 | \usage{ 7 | get_nodedata(term, what) 8 | } 9 | \arguments{ 10 | \item{term}{term in formula} 11 | 12 | \item{what}{string specifying what to return} 13 | } 14 | \value{ 15 | property of the node specification as defined by \code{what} 16 | } 17 | \description{ 18 | Extract attributes/hyper-parameters of the node term 19 | } 20 | -------------------------------------------------------------------------------- /man/get_partial_effect.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/methods.R 3 | \name{get_partial_effect} 4 | \alias{get_partial_effect} 5 | \title{Return partial effect of one smooth term} 6 | \usage{ 7 | get_partial_effect( 8 | object, 9 | names = NULL, 10 | return_matrix = FALSE, 11 | which_param = 1, 12 | newdata = NULL, 13 | ... 14 | ) 15 | } 16 | \arguments{ 17 | \item{object}{deepregression object} 18 | 19 | \item{names}{string; for partial match with smooth term} 20 | 21 | \item{return_matrix}{logical; whether to return the design matrix or} 22 | 23 | \item{which_param}{integer; which distribution parameter 24 | the partial effect (\code{FALSE}, default)} 25 | 26 | \item{newdata}{data.frame; new data (optional)} 27 | 28 | \item{...}{arguments passed to \code{get_weight_by_name}} 29 | } 30 | \description{ 31 | Return partial effect of one smooth term 32 | } 33 | -------------------------------------------------------------------------------- /man/get_processor_name.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/formula_helpers.R 3 | \name{get_processor_name} 4 | \alias{get_processor_name} 5 | \title{Extract processor name from term} 6 | \usage{ 7 | get_processor_name(term) 8 | } 9 | \arguments{ 10 | \item{term}{term in formula} 11 | } 12 | \value{ 13 | processor name as string 14 | } 15 | \description{ 16 | Extract processor name from term 17 | } 18 | -------------------------------------------------------------------------------- /man/get_special.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/formula_helpers.R 3 | \name{get_special} 4 | \alias{get_special} 5 | \title{Extract terms defined by specials in formula} 6 | \usage{ 7 | get_special(term, specials, simplify = FALSE) 8 | } 9 | \arguments{ 10 | \item{term}{term in formula} 11 | 12 | \item{specials}{string(s); special name(s)} 13 | 14 | \item{simplify}{logical; shortcut for returning only 15 | the name of the special in term} 16 | } 17 | \value{ 18 | specials in formula 19 | } 20 | \description{ 21 | Extract terms defined by specials in formula 22 | } 23 | -------------------------------------------------------------------------------- /man/get_type_pfc.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/helperfuns.R 3 | \name{get_type_pfc} 4 | \alias{get_type_pfc} 5 | \title{Function to subset parsed formulas} 6 | \usage{ 7 | get_type_pfc(pfc, type = NULL) 8 | } 9 | \arguments{ 10 | \item{pfc}{list of parsed formulas} 11 | 12 | \item{type}{either NULL (all types of coefficients are returned), 13 | "linear" for linear coefficients or "smooth" for coefficients of} 14 | } 15 | \description{ 16 | Function to subset parsed formulas 17 | } 18 | -------------------------------------------------------------------------------- /man/get_weight_by_name.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/methods.R 3 | \name{get_weight_by_name} 4 | \alias{get_weight_by_name} 5 | \title{Function to retrieve the weights of a structured layer} 6 | \usage{ 7 | get_weight_by_name(mod, name, param_nr = 1, postfixes = "") 8 | } 9 | \arguments{ 10 | \item{mod}{fitted deepregression object} 11 | 12 | \item{name}{name of partial effect} 13 | 14 | \item{param_nr}{distribution parameter number} 15 | 16 | \item{postfixes}{character (vector) appended to layer name} 17 | } 18 | \value{ 19 | weight matrix 20 | } 21 | \description{ 22 | Function to retrieve the weights of a structured layer 23 | } 24 | -------------------------------------------------------------------------------- /man/get_weight_by_opname.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/helperfuns.R 3 | \name{get_weight_by_opname} 4 | \alias{get_weight_by_opname} 5 | \title{Function to return weight given model and name} 6 | \usage{ 7 | get_weight_by_opname(mod, name, partial_match = FALSE) 8 | } 9 | \arguments{ 10 | \item{mod}{deepregression model} 11 | 12 | \item{name}{character} 13 | 14 | \item{partial_match}{logical; whether to also check for a partial match} 15 | } 16 | \description{ 17 | Function to return weight given model and name 18 | } 19 | -------------------------------------------------------------------------------- /man/hadamard_layers.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/layers.R 3 | \name{tib_layer} 4 | \alias{tib_layer} 5 | \alias{simplyconnected_layer} 6 | \alias{inverse_group_lasso_pen} 7 | \alias{regularizer_group_lasso} 8 | \alias{tibgroup_layer} 9 | \alias{layer_hadamard} 10 | \alias{layer_group_hadamard} 11 | \alias{layer_hadamard_diff} 12 | \title{Hadamard-type layers} 13 | \usage{ 14 | tib_layer(units, la, ...) 15 | 16 | simplyconnected_layer(la, ...) 17 | 18 | inverse_group_lasso_pen(la) 19 | 20 | regularizer_group_lasso(la, group_idx) 21 | 22 | tibgroup_layer(units, group_idx, la, ...) 23 | 24 | layer_hadamard(units = 1, la = 0, depth = 3, ...) 25 | 26 | layer_group_hadamard(units, la, group_idx, depth, ...) 27 | 28 | layer_hadamard_diff( 29 | units, 30 | la, 31 | initu = "glorot_uniform", 32 | initv = "glorot_uniform", 33 | ... 34 | ) 35 | 36 | layer_hadamard(units = 1, la = 0, depth = 3, ...) 37 | } 38 | \arguments{ 39 | \item{units}{integer; number of units} 40 | 41 | \item{la}{numeric; regularization value (> 0)} 42 | 43 | \item{...}{arguments passed to TensorFlow layer} 44 | 45 | \item{group_idx}{list of group indices} 46 | 47 | \item{depth}{integer; depth of weight factorization} 48 | 49 | \item{initu, initv}{initializers for parameters} 50 | } 51 | \value{ 52 | layer object 53 | } 54 | \description{ 55 | Hadamard-type layers 56 | } 57 | -------------------------------------------------------------------------------- /man/hadamard_layers_torch.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/layers_torch.R 3 | \name{simplyconnected_layer_torch} 4 | \alias{simplyconnected_layer_torch} 5 | \alias{tiblinlasso_layer_torch} 6 | \alias{tib_layer_torch} 7 | \alias{tibgroup_layer_torch} 8 | \title{Hadamard-type layers torch} 9 | \usage{ 10 | simplyconnected_layer_torch( 11 | la = la, 12 | multfac_initializer = torch_ones, 13 | input_shape 14 | ) 15 | 16 | tiblinlasso_layer_torch( 17 | la, 18 | input_shape = 1, 19 | units = 1, 20 | kernel_initializer = "he_normal" 21 | ) 22 | 23 | tib_layer_torch(units, la, input_shape, multfac_initializer = torch_ones) 24 | 25 | tibgroup_layer_torch( 26 | units, 27 | group_idx = NULL, 28 | la = 0, 29 | input_shape, 30 | kernel_initializer = "torch_ones", 31 | multfac_initializer = "he_normal" 32 | ) 33 | } 34 | \arguments{ 35 | \item{la}{numeric; regularization value (> 0)} 36 | 37 | \item{multfac_initializer}{initializer for parameters} 38 | 39 | \item{input_shape}{integer; number of input dimension} 40 | 41 | \item{units}{integer; number of units} 42 | 43 | \item{kernel_initializer}{initializer} 44 | 45 | \item{group_idx}{list of group indices} 46 | } 47 | \value{ 48 | nn_module 49 | 50 | torch layer object 51 | 52 | nn_module 53 | 54 | nn_module 55 | } 56 | \description{ 57 | Hadamard-type layers torch 58 | } 59 | -------------------------------------------------------------------------------- /man/handle_gam_term.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/psplinelayer.R 3 | \name{handle_gam_term} 4 | \alias{handle_gam_term} 5 | \title{Function to define smoothness and call mgcv's smooth constructor} 6 | \usage{ 7 | handle_gam_term(object, data, controls) 8 | } 9 | \arguments{ 10 | \item{object}{character defining the model term} 11 | 12 | \item{data}{data.frame or list} 13 | 14 | \item{controls}{controls for penalization} 15 | } 16 | \value{ 17 | constructed smooth term 18 | } 19 | \description{ 20 | Function to define smoothness and call mgcv's smooth constructor 21 | } 22 | -------------------------------------------------------------------------------- /man/import_packages.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/helperfuns.R 3 | \name{import_packages} 4 | \alias{import_packages} 5 | \title{Function to import required packages} 6 | \usage{ 7 | import_packages(engine) 8 | } 9 | \arguments{ 10 | \item{engine}{tensorflow or torch} 11 | } 12 | \description{ 13 | Function to import required packages 14 | } 15 | -------------------------------------------------------------------------------- /man/import_tf_dependings.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/helperfuns.R 3 | \name{import_tf_dependings} 4 | \alias{import_tf_dependings} 5 | \title{Function to import required packages for tensorflow 6 | 7 | @import tensorflow tfprobability keras} 8 | \usage{ 9 | import_tf_dependings() 10 | } 11 | \description{ 12 | Function to import required packages for tensorflow 13 | 14 | @import tensorflow tfprobability keras 15 | } 16 | -------------------------------------------------------------------------------- /man/import_torch_dependings.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/helperfuns.R 3 | \name{import_torch_dependings} 4 | \alias{import_torch_dependings} 5 | \title{Function to import required packages for torch 6 | 7 | @import torch torchvision luz} 8 | \usage{ 9 | import_torch_dependings() 10 | } 11 | \description{ 12 | Function to import required packages for torch 13 | 14 | @import torch torchvision luz 15 | } 16 | -------------------------------------------------------------------------------- /man/keras_dr.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/deepregression.R 3 | \name{keras_dr} 4 | \alias{keras_dr} 5 | \title{Compile a Deep Distributional Regression Model} 6 | \usage{ 7 | keras_dr( 8 | list_pred_param, 9 | weights = NULL, 10 | optimizer = tf$keras$optimizers$Adam(), 11 | model_fun = keras_model, 12 | monitor_metrics = list(), 13 | from_preds_to_output = from_preds_to_dist, 14 | loss = from_dist_to_loss(family = list(...)$family, weights = weights), 15 | additional_penalty = NULL, 16 | ... 17 | ) 18 | } 19 | \arguments{ 20 | \item{list_pred_param}{list of input-output(-lists) generated from 21 | \code{subnetwork_init}} 22 | 23 | \item{weights}{vector of positive values; optional (default = 1 for all observations)} 24 | 25 | \item{optimizer}{optimizer used. Per default Adam} 26 | 27 | \item{model_fun}{which function to use for model building (default \code{keras_model})} 28 | 29 | \item{monitor_metrics}{Further metrics to monitor} 30 | 31 | \item{from_preds_to_output}{function taking the list_pred_param outputs 32 | and transforms it into a single network output} 33 | 34 | \item{loss}{the model's loss function; per default evaluated based on 35 | the arguments \code{family} and \code{weights} using \code{from_dist_to_loss}} 36 | 37 | \item{additional_penalty}{a penalty that is added to the negative log-likelihood; 38 | must be a function of model$trainable_weights with suitable subsetting} 39 | 40 | \item{...}{arguments passed to \code{from_preds_to_output}} 41 | } 42 | \value{ 43 | a list with input tensors and output tensors that can be passed 44 | to, e.g., \code{keras_model} 45 | } 46 | \description{ 47 | Compile a Deep Distributional Regression Model 48 | } 49 | \examples{ 50 | set.seed(24) 51 | n <- 500 52 | x <- runif(n) \%>\% as.matrix() 53 | z <- runif(n) \%>\% as.matrix() 54 | 55 | y <- x - z 56 | data <- data.frame(x = x, z = z, y = y) 57 | 58 | # change loss to mse and adapt 59 | # \code{from_preds_to_output} to work 60 | # only on the first output column 61 | mod <- deepregression( 62 | y = y, 63 | data = data, 64 | list_of_formulas = list(loc = ~ 1 + x + z, scale = ~ 1), 65 | list_of_deep_models = NULL, 66 | family = "normal", 67 | from_preds_to_output = function(x, ...) x[[1]], 68 | loss = "mse" 69 | ) 70 | 71 | 72 | } 73 | -------------------------------------------------------------------------------- /man/layer_dense_module.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/layers_torch.R 3 | \name{layer_dense_module} 4 | \alias{layer_dense_module} 5 | \title{Function to create custom nn_linear module to overwrite reset_parameters} 6 | \usage{ 7 | layer_dense_module(kernel_initializer) 8 | } 9 | \arguments{ 10 | \item{kernel_initializer}{string; initializer used to reset_parameters} 11 | } 12 | \value{ 13 | nn module 14 | } 15 | \description{ 16 | Function to create custom nn_linear module to overwrite reset_parameters 17 | } 18 | -------------------------------------------------------------------------------- /man/layer_dense_torch.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/layers_torch.R 3 | \name{layer_dense_torch} 4 | \alias{layer_dense_torch} 5 | \title{Function to define a torch layer similar to a tf dense layer} 6 | \usage{ 7 | layer_dense_torch( 8 | input_shape, 9 | units = 1L, 10 | name, 11 | trainable = TRUE, 12 | kernel_initializer = "glorot_uniform", 13 | use_bias = FALSE, 14 | kernel_regularizer = NULL, 15 | ... 16 | ) 17 | } 18 | \arguments{ 19 | \item{input_shape}{integer; number of input units} 20 | 21 | \item{units}{integer; number of output units} 22 | 23 | \item{name}{string; string defining the layer's name} 24 | 25 | \item{trainable}{logical; whether layer is trainable} 26 | 27 | \item{kernel_initializer}{initializer; for coefficients} 28 | 29 | \item{use_bias}{logical; wether bias is used (default no)} 30 | 31 | \item{kernel_regularizer}{regularizer; for coefficients} 32 | 33 | \item{...}{arguments used in choose_kernel_initializer_torch} 34 | } 35 | \value{ 36 | torch layer 37 | } 38 | \description{ 39 | Function to define a torch layer similar to a tf dense layer 40 | } 41 | -------------------------------------------------------------------------------- /man/layer_node.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/nodelayer.R 3 | \name{layer_node} 4 | \alias{layer_node} 5 | \title{NODE/ODTs Layer} 6 | \usage{ 7 | layer_node( 8 | name, 9 | units, 10 | n_layers = 1L, 11 | n_trees = 1L, 12 | tree_depth = 1L, 13 | threshold_init_beta = 1 14 | ) 15 | } 16 | \arguments{ 17 | \item{name}{name of the layer} 18 | 19 | \item{units}{number of output dimensions, for regression and binary 20 | classification: 1, for mc-classification simply the number of classes} 21 | 22 | \item{n_layers}{number of layers consisting of ODTs in NODE} 23 | 24 | \item{n_trees}{number of trees per layer} 25 | 26 | \item{tree_depth}{depth of tree per layer} 27 | 28 | \item{threshold_init_beta}{parameter(s) for Beta-distribution used for initializing feature thresholds} 29 | } 30 | \value{ 31 | layer/model object 32 | } 33 | \description{ 34 | NODE/ODTs Layer 35 | } 36 | \examples{ 37 | n <- 1000 38 | data_regr <- data.frame(matrix(rnorm(4 * n), c(n, 4))) 39 | colnames(data_regr) <- c("x0", "x1", "x2", "x3") 40 | y_regr <- rnorm(n) + data_regr$x0^2 + data_regr$x1 + 41 | data_regr$x2*data_regr$x3 + data_regr$x2 + data_regr$x3 42 | 43 | library(deepregression) 44 | 45 | formula_node <- ~ node(x1, x2, x3, x0, n_trees = 2, n_layers = 2, tree_depth = 2) 46 | 47 | mod_node_regr <- deepregression( 48 | list_of_formulas = list(loc = formula_node, scale = ~ 1), 49 | data = data_regr, 50 | y = y_regr 51 | ) 52 | 53 | if(!is.null(mod_node_regr)){ 54 | mod_node_regr \%>\% fit(epochs = 15, batch_size = 64, verbose = TRUE, 55 | validation_split = 0.1, early_stopping = TRUE) 56 | mod_node_regr \%>\% predict() 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /man/layer_sparse_batch_normalization.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/layers.R 3 | \name{layer_sparse_batch_normalization} 4 | \alias{layer_sparse_batch_normalization} 5 | \title{Sparse Batch Normalization layer} 6 | \usage{ 7 | layer_sparse_batch_normalization(lam = NULL, ...) 8 | } 9 | \arguments{ 10 | \item{lam}{regularization strength} 11 | 12 | \item{...}{arguments passed to TensorFlow layer} 13 | } 14 | \value{ 15 | layer object 16 | } 17 | \description{ 18 | Sparse Batch Normalization layer 19 | } 20 | -------------------------------------------------------------------------------- /man/layer_sparse_conv_2d.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/layers.R 3 | \name{layer_sparse_conv_2d} 4 | \alias{layer_sparse_conv_2d} 5 | \title{Sparse 2D Convolutional layer} 6 | \usage{ 7 | layer_sparse_conv_2d(filters, kernel_size, lam = NULL, depth = 2, ...) 8 | } 9 | \arguments{ 10 | \item{filters}{number of filters} 11 | 12 | \item{kernel_size}{size of convolutional filter} 13 | 14 | \item{lam}{regularization strength} 15 | 16 | \item{depth}{depth of weight factorization} 17 | 18 | \item{...}{arguments passed to TensorFlow layer} 19 | } 20 | \value{ 21 | layer object 22 | } 23 | \description{ 24 | Sparse 2D Convolutional layer 25 | } 26 | -------------------------------------------------------------------------------- /man/layer_spline.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/psplinelayer.R 3 | \name{layer_spline} 4 | \alias{layer_spline} 5 | \title{Function to define spline as TensorFlow layer} 6 | \usage{ 7 | layer_spline( 8 | units = 1L, 9 | P, 10 | name, 11 | trainable = TRUE, 12 | kernel_initializer = "glorot_uniform" 13 | ) 14 | } 15 | \arguments{ 16 | \item{units}{integer; number of output units} 17 | 18 | \item{P}{matrix; penalty matrix} 19 | 20 | \item{name}{string; string defining the layer's name} 21 | 22 | \item{trainable}{logical; whether layer is trainable} 23 | 24 | \item{kernel_initializer}{initializer; for basis coefficients} 25 | } 26 | \value{ 27 | TensorFlow layer 28 | } 29 | \description{ 30 | Function to define spline as TensorFlow layer 31 | } 32 | -------------------------------------------------------------------------------- /man/layer_spline_torch.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/psplinelayer_torch.R 3 | \name{layer_spline_torch} 4 | \alias{layer_spline_torch} 5 | \title{Function to define spline as Torch layer} 6 | \usage{ 7 | layer_spline_torch( 8 | P, 9 | units = 1L, 10 | name, 11 | trainable = TRUE, 12 | kernel_initializer = "glorot_uniform", 13 | ... 14 | ) 15 | } 16 | \arguments{ 17 | \item{P}{matrix; penalty matrix} 18 | 19 | \item{units}{integer; number of output units} 20 | 21 | \item{name}{string; string defining the layer's name} 22 | 23 | \item{trainable}{logical; whether layer is trainable} 24 | 25 | \item{kernel_initializer}{initializer; for basis coefficients} 26 | 27 | \item{...}{value used for constant kernel initializer} 28 | } 29 | \value{ 30 | Torch spline layer 31 | } 32 | \description{ 33 | Function to define spline as Torch layer 34 | } 35 | -------------------------------------------------------------------------------- /man/log_score.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/methods.R 3 | \name{log_score} 4 | \alias{log_score} 5 | \title{Function to return the log_score} 6 | \usage{ 7 | log_score( 8 | x, 9 | data = NULL, 10 | this_y = NULL, 11 | ind_fun = NULL, 12 | convert_fun = as.matrix, 13 | summary_fun = function(x) x 14 | ) 15 | } 16 | \arguments{ 17 | \item{x}{the fitted deepregression object} 18 | 19 | \item{data}{an optional data set} 20 | 21 | \item{this_y}{new y for optional data} 22 | 23 | \item{ind_fun}{function indicating the dependency; per default (iid assumption) 24 | \code{tfd_independent} is used.} 25 | 26 | \item{convert_fun}{function that converts Tensor; per default \code{as.matrix}} 27 | 28 | \item{summary_fun}{function summarizing the output; per default the identity} 29 | } 30 | \description{ 31 | Function to return the log_score 32 | } 33 | -------------------------------------------------------------------------------- /man/loop_through_pfc_and_call_trafo.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/data_handler.R 3 | \name{loop_through_pfc_and_call_trafo} 4 | \alias{loop_through_pfc_and_call_trafo} 5 | \title{Function to loop through parsed formulas and apply data trafo} 6 | \usage{ 7 | loop_through_pfc_and_call_trafo(pfc, newdata = NULL, engine = "tf") 8 | } 9 | \arguments{ 10 | \item{pfc}{list of processor transformed formulas} 11 | 12 | \item{newdata}{list in the same format as the original data} 13 | 14 | \item{engine}{character; the engine which is used to setup the NN (tf or torch)} 15 | } 16 | \value{ 17 | list of matrices or arrays 18 | } 19 | \description{ 20 | Function to loop through parsed formulas and apply data trafo 21 | } 22 | -------------------------------------------------------------------------------- /man/makeInputs.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/subnetwork_init.R 3 | \name{makeInputs} 4 | \alias{makeInputs} 5 | \title{Convenience layer function} 6 | \usage{ 7 | makeInputs(pp, param_nr) 8 | } 9 | \arguments{ 10 | \item{pp}{processed predictors} 11 | 12 | \item{param_nr}{integer for the parameter} 13 | } 14 | \value{ 15 | input tensors with appropriate names 16 | } 17 | \description{ 18 | Convenience layer function 19 | } 20 | -------------------------------------------------------------------------------- /man/make_folds.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/cross-validation.R 3 | \name{make_folds} 4 | \alias{make_folds} 5 | \title{Generate folds for CV out of one hot encoded matrix} 6 | \usage{ 7 | make_folds(mat, val_train = 0, val_test = 1) 8 | } 9 | \arguments{ 10 | \item{mat}{matrix with columns corresponding to folds 11 | and entries corresponding to a one hot encoding} 12 | 13 | \item{val_train}{the value corresponding to train, per default 0} 14 | 15 | \item{val_test}{the value corresponding to test, per default 1} 16 | } 17 | \description{ 18 | Generate folds for CV out of one hot encoded matrix 19 | } 20 | \details{ 21 | \code{val_train} and \code{val_test} can both be a set of value 22 | } 23 | -------------------------------------------------------------------------------- /man/make_generator.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/generator.R 3 | \name{make_generator} 4 | \alias{make_generator} 5 | \title{creates a generator for training} 6 | \usage{ 7 | make_generator( 8 | input_x, 9 | input_y = NULL, 10 | batch_size, 11 | sizes, 12 | shuffle = TRUE, 13 | seed = 42L 14 | ) 15 | } 16 | \arguments{ 17 | \item{input_x}{list of matrices} 18 | 19 | \item{input_y}{list of matrix} 20 | 21 | \item{batch_size}{integer} 22 | 23 | \item{sizes}{sizes of the image including colour channel} 24 | 25 | \item{shuffle}{logical for shuffling data} 26 | 27 | \item{seed}{seed for shuffling in generators} 28 | } 29 | \value{ 30 | generator for all x and y 31 | } 32 | \description{ 33 | creates a generator for training 34 | } 35 | -------------------------------------------------------------------------------- /man/make_generator_from_matrix.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/generator.R 3 | \name{make_generator_from_matrix} 4 | \alias{make_generator_from_matrix} 5 | \title{Make a DataGenerator from a data.frame or matrix} 6 | \usage{ 7 | make_generator_from_matrix( 8 | x, 9 | y = NULL, 10 | generator = image_data_generator(), 11 | batch_size = 32L, 12 | shuffle = TRUE, 13 | seed = 1L 14 | ) 15 | } 16 | \arguments{ 17 | \item{x}{matrix;} 18 | 19 | \item{y}{vector;} 20 | 21 | \item{generator}{generator as e.g. obtained from `keras::image_data_generator`. 22 | Used for consistent train-test splits.} 23 | 24 | \item{batch_size}{integer} 25 | 26 | \item{shuffle}{logical; Should data be shuffled?} 27 | 28 | \item{seed}{integer; seed for shuffling data.} 29 | } 30 | \description{ 31 | Creates a Python Class that internally iterates over the data. 32 | } 33 | -------------------------------------------------------------------------------- /man/makelayername.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/formula_helpers.R 3 | \name{makelayername} 4 | \alias{makelayername} 5 | \title{Function that takes term and create layer name} 6 | \usage{ 7 | makelayername(term, param_nr, truncate = 60) 8 | } 9 | \arguments{ 10 | \item{term}{term in formula} 11 | 12 | \item{param_nr}{integer; defining number of the distribution's parameter} 13 | 14 | \item{truncate}{integer; value from which on names are truncated} 15 | } 16 | \value{ 17 | name (string) for layer 18 | } 19 | \description{ 20 | Function that takes term and create layer name 21 | } 22 | -------------------------------------------------------------------------------- /man/model_torch.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/deepregression_torch.R 3 | \name{model_torch} 4 | \alias{model_torch} 5 | \title{Function to initialize a nn_module 6 | Forward functions works with a list. The entries of the list are the input of 7 | the subnetworks} 8 | \usage{ 9 | model_torch(submodules_list) 10 | } 11 | \arguments{ 12 | \item{submodules_list}{list; subnetworks} 13 | } 14 | \value{ 15 | nn_module 16 | } 17 | \description{ 18 | Function to initialize a nn_module 19 | Forward functions works with a list. The entries of the list are the input of 20 | the subnetworks 21 | } 22 | -------------------------------------------------------------------------------- /man/multioptimizer.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/models.R 3 | \name{multioptimizer} 4 | \alias{multioptimizer} 5 | \title{Function to define an optimizer combining multiple optimizers} 6 | \usage{ 7 | multioptimizer(optimizers_and_layers) 8 | } 9 | \arguments{ 10 | \item{optimizers_and_layers}{a list if \code{tuple}s of optimizer 11 | and respective layers} 12 | } 13 | \value{ 14 | an optimizer 15 | } 16 | \description{ 17 | Function to define an optimizer combining multiple optimizers 18 | } 19 | -------------------------------------------------------------------------------- /man/na_omit_list.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/data_handler.R 3 | \name{na_omit_list} 4 | \alias{na_omit_list} 5 | \title{Function to exclude NA values} 6 | \usage{ 7 | na_omit_list(datalist) 8 | } 9 | \arguments{ 10 | \item{datalist}{list of data as returned by \code{prepare_data} and 11 | \code{prepare_newdata}} 12 | } 13 | \value{ 14 | list with NA values excluded and locations of original 15 | NA positions as attributes 16 | } 17 | \description{ 18 | Function to exclude NA values 19 | } 20 | -------------------------------------------------------------------------------- /man/names_families.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/families.R 3 | \name{names_families} 4 | \alias{names_families} 5 | \title{Returns the parameter names for a given family} 6 | \usage{ 7 | names_families(family) 8 | } 9 | \arguments{ 10 | \item{family}{character specifying the family as defined by \code{deepregression}} 11 | } 12 | \value{ 13 | vector of parameter names 14 | } 15 | \description{ 16 | Returns the parameter names for a given family 17 | } 18 | -------------------------------------------------------------------------------- /man/nn_init_no_grad_constant_deepreg.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/layers_torch.R 3 | \name{nn_init_no_grad_constant_deepreg} 4 | \alias{nn_init_no_grad_constant_deepreg} 5 | \title{custom nn_linear module to overwrite reset_parameters 6 | # nn_init_constant works only if value is scalar; so warmstarts for gam does'not work} 7 | \usage{ 8 | nn_init_no_grad_constant_deepreg(tensor, value) 9 | } 10 | \arguments{ 11 | \item{tensor}{scalar or vector} 12 | 13 | \item{value}{value used for constant initialization} 14 | } 15 | \value{ 16 | tensor 17 | } 18 | \description{ 19 | custom nn_linear module to overwrite reset_parameters 20 | # nn_init_constant works only if value is scalar; so warmstarts for gam does'not work 21 | } 22 | -------------------------------------------------------------------------------- /man/orthog_P.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/orthogonalization.R 3 | \name{orthog_P} 4 | \alias{orthog_P} 5 | \title{Function to compute adjusted penalty when orthogonalizing} 6 | \usage{ 7 | orthog_P(P, Z) 8 | } 9 | \arguments{ 10 | \item{P}{matrix; original penalty matrix} 11 | 12 | \item{Z}{matrix; constraint matrix} 13 | } 14 | \value{ 15 | adjusted penalty matrix 16 | } 17 | \description{ 18 | Function to compute adjusted penalty when orthogonalizing 19 | } 20 | -------------------------------------------------------------------------------- /man/orthog_control.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/controls.R 3 | \name{orthog_control} 4 | \alias{orthog_control} 5 | \title{Options for orthogonalization} 6 | \usage{ 7 | orthog_control( 8 | split_fun = split_model, 9 | orthog_type = c("tf", "manual"), 10 | orthogonalize = options()$orthogonalize, 11 | identify_intercept = options()$identify_intercept, 12 | deep_top = NULL, 13 | orthog_fun = NULL, 14 | deactivate_oz_at_test = TRUE 15 | ) 16 | } 17 | \arguments{ 18 | \item{split_fun}{a function separating the deep neural network in two parts 19 | so that the orthogonalization can be applied to the first part before 20 | applying the second network part; per default, the function \code{split_model} is 21 | used which assumes a dense layer as penultimate layer and separates the network 22 | into a first part without this last layer and a second part only consisting of a 23 | single dense layer that is fed into the output layer} 24 | 25 | \item{orthog_type}{one of two options; If \code{"manual"}, 26 | the QR decomposition is calculated before model fitting, 27 | otherwise (\code{"tf"}) a QR is calculated in each batch iteration via TF. 28 | The first only works well for larger batch sizes or ideally batch_size == NROW(y).} 29 | 30 | \item{orthogonalize}{logical; if set to \code{TRUE}, automatic orthogonalization is activated} 31 | 32 | \item{identify_intercept}{whether to orthogonalize the deep network w.r.t. the intercept 33 | to make the intercept identifiable} 34 | 35 | \item{deep_top}{function; optional function to put on top of the deep network instead 36 | of splitting the function using \code{split_fun}} 37 | 38 | \item{orthog_fun}{function; for custom orthogonaliuation. if NULL, \code{orthog_type} 39 | is used to define the function that computes the orthogonalization} 40 | 41 | \item{deactivate_oz_at_test}{logical; whether to deactive the orthogonalization cell 42 | at test time when using \code{orthog_tf} for \code{orthog_fun} (the default).} 43 | } 44 | \value{ 45 | Returns a list with options 46 | } 47 | \description{ 48 | Options for orthogonalization 49 | } 50 | -------------------------------------------------------------------------------- /man/orthog_post_fitting.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/orthogonalization.R 3 | \name{orthog_post_fitting} 4 | \alias{orthog_post_fitting} 5 | \title{Orthogonalize a Semi-Structured Model Post-hoc} 6 | \usage{ 7 | orthog_post_fitting(mod, name_penult, param_nr = 1) 8 | } 9 | \arguments{ 10 | \item{mod}{deepregression model} 11 | 12 | \item{name_penult}{character name of the penultimate layer 13 | of the deep part part} 14 | 15 | \item{param_nr}{integer; number of the parameter to be returned} 16 | } 17 | \value{ 18 | a \code{deepregression} object with weights frozen and 19 | deep part specified by \code{name_penult} orthogonalized 20 | } 21 | \description{ 22 | Orthogonalize a Semi-Structured Model Post-hoc 23 | } 24 | -------------------------------------------------------------------------------- /man/orthog_structured_smooths_Z.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/orthogonalization.R 3 | \name{orthog_structured_smooths_Z} 4 | \alias{orthog_structured_smooths_Z} 5 | \title{Orthogonalize structured term by another matrix} 6 | \usage{ 7 | orthog_structured_smooths_Z(S, L) 8 | } 9 | \arguments{ 10 | \item{S}{matrix; matrix to orthogonalize} 11 | 12 | \item{L}{matrix; matrix which defines the projection 13 | and its orthogonal complement, in which \code{S} is projected} 14 | } 15 | \value{ 16 | constraint matrix 17 | } 18 | \description{ 19 | Orthogonalize structured term by another matrix 20 | } 21 | -------------------------------------------------------------------------------- /man/penalty_control.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/controls.R 3 | \name{penalty_control} 4 | \alias{penalty_control} 5 | \title{Options for penalty setup in the pre-processing} 6 | \usage{ 7 | penalty_control( 8 | defaultSmoothing = NULL, 9 | df = 10, 10 | null_space_penalty = FALSE, 11 | absorb_cons = FALSE, 12 | anisotropic = TRUE, 13 | zero_constraint_for_smooths = TRUE, 14 | no_linear_trend_for_smooths = FALSE, 15 | hat1 = FALSE, 16 | sp_scale = function(x) ifelse(is.list(x) | is.data.frame(x), 1/NROW(x[[1]]), 1/NROW(x)) 17 | ) 18 | } 19 | \arguments{ 20 | \item{defaultSmoothing}{function applied to all s-terms, per default (NULL) 21 | the minimum df of all possible terms is used. Must be a function the smooth term 22 | from mgcv's smoothCon and an argument \code{df}.} 23 | 24 | \item{df}{degrees of freedom for all non-linear structural terms (default = 7); 25 | either one common value or a list of the same length as number of parameters; 26 | if different df values need to be assigned to different smooth terms, 27 | use df as an argument for \code{s()}, \code{te()} or \code{ti()}} 28 | 29 | \item{null_space_penalty}{logical value; 30 | if TRUE, the null space will also be penalized for smooth effects. 31 | Per default, this is equal to the value give in \code{variational}.} 32 | 33 | \item{absorb_cons}{logical; adds identifiability constraint to the basis. 34 | See \code{?mgcv::smoothCon} for more details.} 35 | 36 | \item{anisotropic}{whether or not use anisotropic smoothing (default is TRUE)} 37 | 38 | \item{zero_constraint_for_smooths}{logical; the same as absorb_cons, 39 | but done explicitly. If true a constraint is put on each smooth to have zero mean. Can 40 | be a vector of \code{length(list_of_formulas)} for each distribution parameter.} 41 | 42 | \item{no_linear_trend_for_smooths}{logical; see \code{zero_constraint_for_smooths}, but 43 | this removes the linear trend from splines} 44 | 45 | \item{hat1}{logical; if TRUE, the smoothing parameter is defined by the trace of the hat 46 | matrix sum(diag(H)), else sum(diag(2*H-HH))} 47 | 48 | \item{sp_scale}{function of response; for scaling the penalty (1/n per default)} 49 | } 50 | \value{ 51 | Returns a list with options 52 | } 53 | \description{ 54 | Options for penalty setup in the pre-processing 55 | } 56 | -------------------------------------------------------------------------------- /man/pipe.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/utils-pipe.R 3 | \name{\%>\%} 4 | \alias{\%>\%} 5 | \title{Pipe operator} 6 | \usage{ 7 | lhs \%>\% rhs 8 | } 9 | \description{ 10 | See \code{magrittr::\link[magrittr:pipe]{\%>\%}} for details. 11 | } 12 | \keyword{internal} 13 | -------------------------------------------------------------------------------- /man/plot_cv.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/cross-validation.R 3 | \name{plot_cv} 4 | \alias{plot_cv} 5 | \title{Plot CV results from deepregression} 6 | \usage{ 7 | plot_cv(x, what = c("loss", "weight"), engine = "tf", ...) 8 | } 9 | \arguments{ 10 | \item{x}{\code{drCV} object returned by \code{cv.deepregression}} 11 | 12 | \item{what}{character indicating what to plot (currently supported 'loss' 13 | or 'weights')} 14 | 15 | \item{engine}{character indicating which engine was used to setup the NN} 16 | 17 | \item{...}{further arguments passed to \code{matplot}} 18 | } 19 | \description{ 20 | Plot CV results from deepregression 21 | } 22 | -------------------------------------------------------------------------------- /man/precalc_gam.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/psplinelayer.R 3 | \name{precalc_gam} 4 | \alias{precalc_gam} 5 | \title{Pre-calculate all gam parts from the list of formulas} 6 | \usage{ 7 | precalc_gam(lof, data, controls) 8 | } 9 | \arguments{ 10 | \item{lof}{list of formulas} 11 | 12 | \item{data}{the data list} 13 | 14 | \item{controls}{controls from deepregression} 15 | } 16 | \value{ 17 | a list of length 2 with a matching table to 18 | link every unique gam term to formula entries and the respective 19 | data transformation functions 20 | } 21 | \description{ 22 | Pre-calculate all gam parts from the list of formulas 23 | } 24 | -------------------------------------------------------------------------------- /man/predict_gam_handler.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/psplinelayer.R 3 | \name{predict_gam_handler} 4 | \alias{predict_gam_handler} 5 | \title{Handler for prediction with gam terms} 6 | \usage{ 7 | predict_gam_handler(object, newdata) 8 | } 9 | \arguments{ 10 | \item{object}{sterm} 11 | 12 | \item{newdata}{data.frame or list} 13 | } 14 | \description{ 15 | Handler for prediction with gam terms 16 | } 17 | -------------------------------------------------------------------------------- /man/predict_gen.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/generator.R 3 | \name{predict_gen} 4 | \alias{predict_gen} 5 | \title{Generator function for deepregression objects} 6 | \usage{ 7 | predict_gen( 8 | object, 9 | newdata = NULL, 10 | batch_size = NULL, 11 | apply_fun = tfd_mean, 12 | convert_fun = as.matrix, 13 | ret_dist = FALSE 14 | ) 15 | } 16 | \arguments{ 17 | \item{object}{deepregression model;} 18 | 19 | \item{newdata}{data.frame or list; for (optional) new data} 20 | 21 | \item{batch_size}{integer; \code{NULL} will use the default (20)} 22 | 23 | \item{apply_fun}{see \code{?predict.deepregression}} 24 | 25 | \item{convert_fun}{see \code{?predict.deepregression}} 26 | 27 | \item{ret_dist}{logical; whether to return the whole distribution or 28 | only the (mean) prediction} 29 | } 30 | \value{ 31 | matrix or list of distributions 32 | } 33 | \description{ 34 | Generator function for deepregression objects 35 | } 36 | -------------------------------------------------------------------------------- /man/prepare_data.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/data_handler.R 3 | \name{prepare_data} 4 | \alias{prepare_data} 5 | \title{Function to prepare data based on parsed formulas} 6 | \usage{ 7 | prepare_data(pfc, na_handler = na_omit_list, gamdata = NULL, engine = "tf") 8 | } 9 | \arguments{ 10 | \item{pfc}{list of processor transformed formulas} 11 | 12 | \item{na_handler}{function to deal with NAs} 13 | 14 | \item{gamdata}{processor for gam part} 15 | 16 | \item{engine}{the engine which is used to setup the NN (tf or torch)} 17 | } 18 | \value{ 19 | list of matrices or arrays 20 | } 21 | \description{ 22 | Function to prepare data based on parsed formulas 23 | } 24 | -------------------------------------------------------------------------------- /man/prepare_data_torch.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/data_handler_torch.R 3 | \name{prepare_data_torch} 4 | \alias{prepare_data_torch} 5 | \title{Function to additionally prepare data for fit process (torch)} 6 | \usage{ 7 | prepare_data_torch(pfc, input_x, target = NULL, object) 8 | } 9 | \arguments{ 10 | \item{pfc}{list of processor transformed formulas} 11 | 12 | \item{input_x}{output of prepare_data()} 13 | 14 | \item{target}{target values} 15 | 16 | \item{object}{a deepregression object} 17 | } 18 | \value{ 19 | list of matrices or arrays for predict or a dataloader for fit process 20 | } 21 | \description{ 22 | Function to additionally prepare data for fit process (torch) 23 | } 24 | -------------------------------------------------------------------------------- /man/prepare_input_list_model.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/data_handler_torch.R 3 | \name{prepare_input_list_model} 4 | \alias{prepare_input_list_model} 5 | \title{Function to prepare input list for fit process, due to different approaches} 6 | \usage{ 7 | prepare_input_list_model( 8 | input_x, 9 | input_y, 10 | object, 11 | epochs = 10, 12 | batch_size = 32, 13 | validation_split = 0, 14 | validation_data = NULL, 15 | callbacks = NULL, 16 | verbose, 17 | view_metrics, 18 | early_stopping 19 | ) 20 | } 21 | \arguments{ 22 | \item{input_x}{output of prepare_data()} 23 | 24 | \item{input_y}{target} 25 | 26 | \item{object}{a deepregression object} 27 | 28 | \item{epochs}{integer, the number of epochs to fit the model} 29 | 30 | \item{batch_size}{integer, the batch size used for mini-batch training} 31 | 32 | \item{validation_split}{float in [0,1] defining the amount of data used for validation} 33 | 34 | \item{validation_data}{optional specified validation data} 35 | 36 | \item{callbacks}{a list of callbacks for fitting} 37 | 38 | \item{verbose}{logical, whether to print losses during training.} 39 | 40 | \item{view_metrics}{logical, whether to trigger the Viewer in RStudio / Browser.} 41 | 42 | \item{early_stopping}{logical, whether early stopping should be user.} 43 | } 44 | \value{ 45 | list of arguments used in fit function 46 | } 47 | \description{ 48 | Function to prepare input list for fit process, due to different approaches 49 | } 50 | -------------------------------------------------------------------------------- /man/prepare_newdata.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/data_handler.R 3 | \name{prepare_newdata} 4 | \alias{prepare_newdata} 5 | \title{Function to prepare new data based on parsed formulas} 6 | \usage{ 7 | prepare_newdata( 8 | pfc, 9 | newdata, 10 | na_handler = na_omit_list, 11 | gamdata = NULL, 12 | engine = "tf" 13 | ) 14 | } 15 | \arguments{ 16 | \item{pfc}{list of processor transformed formulas} 17 | 18 | \item{newdata}{list in the same format as the original data} 19 | 20 | \item{na_handler}{function to deal with NAs} 21 | 22 | \item{gamdata}{processor for gam part} 23 | 24 | \item{engine}{character; the engine which is used to setup the NN (tf or torch)} 25 | } 26 | \value{ 27 | list of matrices or arrays 28 | } 29 | \description{ 30 | Function to prepare new data based on parsed formulas 31 | } 32 | -------------------------------------------------------------------------------- /man/prepare_torch_distr_mixdistr.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/families_torch.R 3 | \name{prepare_torch_distr_mixdistr} 4 | \alias{prepare_torch_distr_mixdistr} 5 | \title{Prepares distributions for mixture process} 6 | \usage{ 7 | prepare_torch_distr_mixdistr(object, dists) 8 | } 9 | \arguments{ 10 | \item{object}{object of class \code{"drEnsemble"}} 11 | 12 | \item{dists}{fitted distributions} 13 | } 14 | \value{ 15 | distribution parameters used for mixture of same distribution 16 | } 17 | \description{ 18 | Prepares distributions for mixture process 19 | } 20 | -------------------------------------------------------------------------------- /man/process_terms.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/special_processing.R 3 | \name{process_terms} 4 | \alias{process_terms} 5 | \title{Control function to define the processor for terms in the formula} 6 | \usage{ 7 | process_terms( 8 | form, 9 | data, 10 | controls, 11 | output_dim, 12 | param_nr, 13 | parsing_options, 14 | specials_to_oz = c(), 15 | automatic_oz_check = TRUE, 16 | identify_intercept = FALSE, 17 | engine = "tf", 18 | ... 19 | ) 20 | } 21 | \arguments{ 22 | \item{form}{the formula to be processed} 23 | 24 | \item{data}{the data for the terms in the formula} 25 | 26 | \item{controls}{controls for gam terms} 27 | 28 | \item{output_dim}{the output dimension of the response} 29 | 30 | \item{param_nr}{integer; identifier for the distribution parameter} 31 | 32 | \item{parsing_options}{options} 33 | 34 | \item{specials_to_oz}{specials that should be automatically checked for} 35 | 36 | \item{automatic_oz_check}{logical; whether to automatically check for DNNs to be orthogonalized} 37 | 38 | \item{identify_intercept}{logical; whether to make the intercept automatically identifiable} 39 | 40 | \item{engine}{character; the engine which is used to setup the NN (tf or torch)} 41 | 42 | \item{...}{further processors} 43 | } 44 | \value{ 45 | returns a processor function 46 | } 47 | \description{ 48 | Control function to define the processor for terms in the formula 49 | } 50 | -------------------------------------------------------------------------------- /man/processors.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/special_processing.R 3 | \name{layer_generator} 4 | \alias{layer_generator} 5 | \alias{int_processor} 6 | \alias{lin_processor} 7 | \alias{ri_processor} 8 | \alias{gam_processor} 9 | \alias{autogam_processor} 10 | \alias{node_processor} 11 | \title{Function that creates layer for each processor} 12 | \usage{ 13 | layer_generator( 14 | term, 15 | output_dim, 16 | param_nr, 17 | controls, 18 | name = makelayername(term, param_nr), 19 | layer_class = tf$keras$layers$Dense, 20 | without_layer = tf$identity, 21 | further_layer_args = NULL, 22 | layer_args_names = NULL, 23 | units = as.integer(output_dim), 24 | engine = "tf", 25 | ... 26 | ) 27 | 28 | int_processor(term, data, output_dim, param_nr, controls, engine = "tf") 29 | 30 | lin_processor(term, data, output_dim, param_nr, controls, engine = "tf") 31 | 32 | ri_processor(term, data, output_dim, param_nr, controls, engine) 33 | 34 | gam_processor(term, data, output_dim, param_nr, controls, engine = "tf") 35 | 36 | autogam_processor(term, data, output_dim, param_nr, controls, engine = "tf") 37 | 38 | node_processor( 39 | term, 40 | data, 41 | output_dim, 42 | param_nr, 43 | controls = NULL, 44 | engine = "tf" 45 | ) 46 | } 47 | \arguments{ 48 | \item{term}{character; term in the formula} 49 | 50 | \item{output_dim}{integer; number of units in the layer} 51 | 52 | \item{param_nr}{integer; identifier for models with more 53 | than one additive predictor} 54 | 55 | \item{controls}{list; control arguments which allow 56 | to pass further information} 57 | 58 | \item{name}{character; name of layer. 59 | if NULL, \code{makelayername} will be used to create layer name} 60 | 61 | \item{layer_class}{a tf or keras layer function} 62 | 63 | \item{without_layer}{function to be used as 64 | layer if \code{controls$with_layer} is FALSE} 65 | 66 | \item{further_layer_args}{named list; further arguments passed to 67 | the layer} 68 | 69 | \item{layer_args_names}{character vector; if NULL, default 70 | layer args will be used. Needs to be set for layers that do not 71 | provide the arguments of a default Dense layer.} 72 | 73 | \item{units}{integer; number of units for layer} 74 | 75 | \item{engine}{character; the engine which is used to setup the NN (tf or torch)} 76 | 77 | \item{...}{other keras layer parameters} 78 | 79 | \item{data}{data frame; the data used in processors} 80 | } 81 | \value{ 82 | a basic processor list structure 83 | } 84 | \description{ 85 | Function that creates layer for each processor 86 | } 87 | -------------------------------------------------------------------------------- /man/quant.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/methods.R 3 | \name{quant} 4 | \alias{quant} 5 | \title{Generic quantile function} 6 | \usage{ 7 | quant(x, ...) 8 | } 9 | \arguments{ 10 | \item{x}{object} 11 | 12 | \item{...}{further arguments passed to the class-specific function} 13 | } 14 | \description{ 15 | Generic quantile function 16 | } 17 | -------------------------------------------------------------------------------- /man/re_layers.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/layers.R 3 | \name{re_layer} 4 | \alias{re_layer} 5 | \alias{pen_layer} 6 | \title{random effect layer} 7 | \usage{ 8 | re_layer(units, ...) 9 | 10 | pen_layer(units, P, ...) 11 | } 12 | \arguments{ 13 | \item{units}{integer; number of units} 14 | 15 | \item{...}{arguments passed to TensorFlow layer} 16 | 17 | \item{P}{penalty matrix} 18 | } 19 | \value{ 20 | layer object 21 | 22 | layer object 23 | } 24 | \description{ 25 | random effect layer 26 | 27 | trainable penalty layer 28 | } 29 | -------------------------------------------------------------------------------- /man/reinit_weights.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/deep-ensembles.R 3 | \name{reinit_weights} 4 | \alias{reinit_weights} 5 | \title{Generic function to re-intialize model weights} 6 | \usage{ 7 | reinit_weights(object, seed) 8 | } 9 | \arguments{ 10 | \item{object}{model to re-initialize} 11 | 12 | \item{seed}{seed for reproducibility} 13 | } 14 | \description{ 15 | Generic function to re-intialize model weights 16 | } 17 | -------------------------------------------------------------------------------- /man/reinit_weights.deepregression.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/deep-ensembles.R 3 | \name{reinit_weights.deepregression} 4 | \alias{reinit_weights.deepregression} 5 | \title{Method to re-initialize weights of a \code{"deepregression"} model} 6 | \usage{ 7 | \method{reinit_weights}{deepregression}(object, seed) 8 | } 9 | \arguments{ 10 | \item{object}{object of class \code{"deepregression"}} 11 | 12 | \item{seed}{seed for reproducibility} 13 | } 14 | \value{ 15 | invisible \code{NULL} 16 | } 17 | \description{ 18 | Method to re-initialize weights of a \code{"deepregression"} model 19 | } 20 | -------------------------------------------------------------------------------- /man/separate_define_relation.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/orthogonalization.R 3 | \name{separate_define_relation} 4 | \alias{separate_define_relation} 5 | \title{Function to define orthogonalization connections in the formula} 6 | \usage{ 7 | separate_define_relation( 8 | form, 9 | specials, 10 | specials_to_oz, 11 | automatic_oz_check = TRUE, 12 | identify_intercept = FALSE, 13 | simplify = FALSE 14 | ) 15 | } 16 | \arguments{ 17 | \item{form}{a formula for one distribution parameter} 18 | 19 | \item{specials}{specials in formula to handle separately} 20 | 21 | \item{specials_to_oz}{parts of the formula to orthogonalize} 22 | 23 | \item{automatic_oz_check}{logical; automatically check if terms must be orthogonalized} 24 | 25 | \item{identify_intercept}{logical; whether to make the intercept identifiable} 26 | 27 | \item{simplify}{logical; if FALSE, formulas are parsed more carefully.} 28 | } 29 | \value{ 30 | Returns a list of formula components with ids and 31 | assignments for orthogonalization 32 | } 33 | \description{ 34 | Function to define orthogonalization connections in the formula 35 | } 36 | -------------------------------------------------------------------------------- /man/stddev.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/methods.R 3 | \name{stddev} 4 | \alias{stddev} 5 | \title{Generic sd function} 6 | \usage{ 7 | stddev(x, ...) 8 | } 9 | \arguments{ 10 | \item{x}{object} 11 | 12 | \item{...}{further arguments passed to the class-specific function} 13 | } 14 | \description{ 15 | Generic sd function 16 | } 17 | -------------------------------------------------------------------------------- /man/stop_iter_cv_result.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/cross-validation.R 3 | \name{stop_iter_cv_result} 4 | \alias{stop_iter_cv_result} 5 | \title{Function to get the stoppting iteration from CV} 6 | \usage{ 7 | stop_iter_cv_result( 8 | res, 9 | thisFUN = mean, 10 | loss = "validloss", 11 | whichFUN = which.min 12 | ) 13 | } 14 | \arguments{ 15 | \item{res}{result of cv call} 16 | 17 | \item{thisFUN}{aggregating function applied over folds} 18 | 19 | \item{loss}{which loss to use for decision} 20 | 21 | \item{whichFUN}{which function to use for decision} 22 | } 23 | \description{ 24 | Function to get the stoppting iteration from CV 25 | } 26 | -------------------------------------------------------------------------------- /man/subnetwork_init.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/subnetwork_init.R 3 | \name{subnetwork_init} 4 | \alias{subnetwork_init} 5 | \title{Initializes a Subnetwork based on the Processed Additive Predictor} 6 | \usage{ 7 | subnetwork_init( 8 | pp, 9 | deep_top = NULL, 10 | orthog_fun = orthog_tf, 11 | split_fun = split_model, 12 | shared_layers = NULL, 13 | param_nr = 1, 14 | selectfun_in = function(pp) pp[[param_nr]], 15 | selectfun_lay = function(pp) pp[[param_nr]], 16 | gaminputs, 17 | summary_layer = layer_add_identity 18 | ) 19 | } 20 | \arguments{ 21 | \item{pp}{list of processed predictor lists from \code{processor}} 22 | 23 | \item{deep_top}{keras layer if the top part of the deep network after orthogonalization 24 | is different to the one extracted from the provided network} 25 | 26 | \item{orthog_fun}{function used for orthogonalization} 27 | 28 | \item{split_fun}{function to split the network to extract head} 29 | 30 | \item{shared_layers}{list defining shared weights within one predictor; 31 | each list item is a vector of characters of terms as given in the parameter formula} 32 | 33 | \item{param_nr}{integer number for the distribution parameter} 34 | 35 | \item{selectfun_in, selectfun_lay}{functions defining which subset of pp to 36 | take as inputs and layers for this subnetwork; per default the \code{param_nr}'s entry} 37 | 38 | \item{gaminputs}{input tensors for gam terms} 39 | 40 | \item{summary_layer}{keras layer that combines inputs (typically adding or concatenating)} 41 | } 42 | \value{ 43 | returns a list of input and output for this additive predictor 44 | } 45 | \description{ 46 | Initializes a Subnetwork based on the Processed Additive Predictor 47 | } 48 | -------------------------------------------------------------------------------- /man/subnetwork_init_torch.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/subnetwork_init_torch.R 3 | \name{subnetwork_init_torch} 4 | \alias{subnetwork_init_torch} 5 | \title{Initializes a Subnetwork based on the Processed Additive Predictor} 6 | \usage{ 7 | subnetwork_init_torch( 8 | pp, 9 | deep_top = NULL, 10 | orthog_fun = NULL, 11 | split_fun = split_model, 12 | shared_layers = NULL, 13 | param_nr = 1, 14 | selectfun_in = function(pp) pp[[param_nr]], 15 | selectfun_lay = function(pp) pp[[param_nr]], 16 | gaminputs, 17 | summary_layer = model_torch 18 | ) 19 | } 20 | \arguments{ 21 | \item{pp}{list of processed predictor lists from \code{processor}} 22 | 23 | \item{deep_top}{In tf approach: keras layer if the top part of the deep network after orthogonalization; Not yet implemented for torch 24 | is different to the one extracted from the provided network} 25 | 26 | \item{orthog_fun}{function used for orthogonalization; Not yet implemented for torch} 27 | 28 | \item{split_fun}{function to split the network to extract head} 29 | 30 | \item{shared_layers}{list defining shared weights within one predictor; 31 | each list item is a vector of characters of terms as given in the parameter formula} 32 | 33 | \item{param_nr}{integer number for the distribution parameter} 34 | 35 | \item{selectfun_in, selectfun_lay}{functions defining which subset of pp to 36 | take as inputs and layers for this subnetwork; per default the \code{param_nr}'s entry} 37 | 38 | \item{gaminputs}{input tensors for gam terms} 39 | 40 | \item{summary_layer}{torch layer that combines inputs (typically adding or concatenating)} 41 | } 42 | \value{ 43 | returns a list of input and output for this additive predictor 44 | } 45 | \description{ 46 | Initializes a Subnetwork based on the Processed Additive Predictor 47 | } 48 | -------------------------------------------------------------------------------- /man/tf_repeat.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/tf_helpers.R 3 | \name{tf_repeat} 4 | \alias{tf_repeat} 5 | \title{TensorFlow repeat function which is not available for TF 2.0} 6 | \usage{ 7 | tf_repeat(a, dim) 8 | } 9 | \arguments{ 10 | \item{a}{tensor} 11 | 12 | \item{dim}{dimension for repeating} 13 | } 14 | \description{ 15 | TensorFlow repeat function which is not available for TF 2.0 16 | } 17 | -------------------------------------------------------------------------------- /man/tf_row_tensor.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/tf_helpers.R 3 | \name{tf_row_tensor} 4 | \alias{tf_row_tensor} 5 | \title{Row-wise tensor product using TensorFlow} 6 | \usage{ 7 | tf_row_tensor(a, b, ...) 8 | } 9 | \arguments{ 10 | \item{a, b}{tensor} 11 | 12 | \item{...}{arguments passed to TensorFlow layer} 13 | } 14 | \value{ 15 | a TensorFlow layer 16 | } 17 | \description{ 18 | Row-wise tensor product using TensorFlow 19 | } 20 | -------------------------------------------------------------------------------- /man/tf_split_multiple.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/tf_helpers.R 3 | \name{tf_split_multiple} 4 | \alias{tf_split_multiple} 5 | \title{Split tensor in multiple parts} 6 | \usage{ 7 | tf_split_multiple(A, len) 8 | } 9 | \arguments{ 10 | \item{A}{tensor} 11 | 12 | \item{len}{integer; defines the split lengths} 13 | } 14 | \value{ 15 | list of tensors 16 | } 17 | \description{ 18 | Split tensor in multiple parts 19 | } 20 | -------------------------------------------------------------------------------- /man/tf_stride_cols.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/tf_helpers.R 3 | \name{tf_stride_cols} 4 | \alias{tf_stride_cols} 5 | \title{Function to index tensors columns} 6 | \usage{ 7 | tf_stride_cols(A, start, end = NULL) 8 | } 9 | \arguments{ 10 | \item{A}{tensor} 11 | 12 | \item{start}{first index} 13 | 14 | \item{end}{last index (equals start index if NULL)} 15 | } 16 | \value{ 17 | sliced tensor 18 | } 19 | \description{ 20 | Function to index tensors columns 21 | } 22 | -------------------------------------------------------------------------------- /man/tf_stride_last_dim_tensor.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/tf_helpers.R 3 | \name{tf_stride_last_dim_tensor} 4 | \alias{tf_stride_last_dim_tensor} 5 | \title{Function to index tensors last dimension} 6 | \usage{ 7 | tf_stride_last_dim_tensor(A, start, end = NULL) 8 | } 9 | \arguments{ 10 | \item{A}{tensor} 11 | 12 | \item{start}{first index} 13 | 14 | \item{end}{last index (equals start index if NULL)} 15 | } 16 | \value{ 17 | sliced tensor 18 | } 19 | \description{ 20 | Function to index tensors last dimension 21 | } 22 | -------------------------------------------------------------------------------- /man/tfd_mse.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/families.R 3 | \name{tfd_mse} 4 | \alias{tfd_mse} 5 | \title{For using mean squared error via TFP} 6 | \usage{ 7 | tfd_mse(mean) 8 | } 9 | \arguments{ 10 | \item{mean}{parameter for the mean} 11 | } 12 | \value{ 13 | a TFP distribution 14 | } 15 | \description{ 16 | For using mean squared error via TFP 17 | } 18 | \details{ 19 | \code{deepregression} allows to train based on the 20 | MSE by using \code{loss = "mse"} as argument to \code{deepregression}. 21 | This tfd function just provides a dummy \code{family} 22 | } 23 | -------------------------------------------------------------------------------- /man/tfd_zinb.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/families.R 3 | \name{tfd_zinb} 4 | \alias{tfd_zinb} 5 | \title{Implementation of a zero-inflated negbinom distribution for TFP} 6 | \usage{ 7 | tfd_zinb(mu, r, probs) 8 | } 9 | \arguments{ 10 | \item{mu, r}{parameter of the negbin_ls distribution} 11 | 12 | \item{probs}{vector of probabilites of length 2 (probability for poisson and 13 | probability for 0s)} 14 | } 15 | \description{ 16 | Implementation of a zero-inflated negbinom distribution for TFP 17 | } 18 | -------------------------------------------------------------------------------- /man/tfd_zip.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/families.R 3 | \name{tfd_zip} 4 | \alias{tfd_zip} 5 | \title{Implementation of a zero-inflated poisson distribution for TFP} 6 | \usage{ 7 | tfd_zip(lambda, probs) 8 | } 9 | \arguments{ 10 | \item{lambda}{scalar value for rate of poisson distribution} 11 | 12 | \item{probs}{vector of probabilites of length 2 (probability for poisson and 13 | probability for 0s)} 14 | } 15 | \description{ 16 | Implementation of a zero-inflated poisson distribution for TFP 17 | } 18 | -------------------------------------------------------------------------------- /man/torch_dr.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/deepregression_torch.R 3 | \name{torch_dr} 4 | \alias{torch_dr} 5 | \title{Compile a Deep Distributional Regression Model (Torch)} 6 | \usage{ 7 | torch_dr( 8 | list_pred_param, 9 | optimizer = torch::optim_adam, 10 | model_fun = NULL, 11 | monitor_metrics = list(), 12 | from_preds_to_output = from_preds_to_dist_torch, 13 | loss = from_dist_to_loss_torch(family = list(...)$family, weights = NULL), 14 | additional_penalty = NULL, 15 | ... 16 | ) 17 | } 18 | \arguments{ 19 | \item{list_pred_param}{list of output(-lists) generated from 20 | \code{subnetwork_init}} 21 | 22 | \item{optimizer}{optimizer used. Per default Adam} 23 | 24 | \item{model_fun}{NULL not needed for torch} 25 | 26 | \item{monitor_metrics}{Further metrics to monitor} 27 | 28 | \item{from_preds_to_output}{function taking the list_pred_param outputs 29 | and transforms it into a single network output} 30 | 31 | \item{loss}{the model's loss function; per default evaluated based on 32 | the arguments \code{family} and \code{weights} using \code{from_dist_to_loss}} 33 | 34 | \item{additional_penalty}{a penalty that is added to the negative log-likelihood; 35 | must be a function of model$trainable_weights with suitable subsetting (not implemented for torch)} 36 | 37 | \item{...}{arguments passed to \code{from_preds_to_output}} 38 | 39 | \item{weights}{vector of positive values; optional (default = 1 for all observations)} 40 | } 41 | \value{ 42 | a luz_module_generator 43 | } 44 | \description{ 45 | Compile a Deep Distributional Regression Model (Torch) 46 | } 47 | -------------------------------------------------------------------------------- /man/update_miniconda_deepregression.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/zzz.R 3 | \name{update_miniconda_deepregression} 4 | \alias{update_miniconda_deepregression} 5 | \title{Function to update miniconda and packages} 6 | \usage{ 7 | update_miniconda_deepregression( 8 | python = VERSIONPY, 9 | uninstall = TRUE, 10 | also_packages = TRUE 11 | ) 12 | } 13 | \arguments{ 14 | \item{python}{string; version of python} 15 | 16 | \item{uninstall}{logical; whether to uninstall previous conda env} 17 | 18 | \item{also_packages}{logical; whether to install also all required packages} 19 | } 20 | \description{ 21 | Function to update miniconda and packages 22 | } 23 | -------------------------------------------------------------------------------- /man/weight_control.Rd: -------------------------------------------------------------------------------- 1 | % Generated by roxygen2: do not edit by hand 2 | % Please edit documentation in R/controls.R 3 | \name{weight_control} 4 | \alias{weight_control} 5 | \title{Options for weights of layers} 6 | \usage{ 7 | weight_control( 8 | specific_weight_options = NULL, 9 | general_weight_options = list(activation = NULL, use_bias = FALSE, trainable = TRUE, 10 | kernel_initializer = "glorot_uniform", bias_initializer = "zeros", kernel_regularizer 11 | = NULL, bias_regularizer = NULL, activity_regularizer = NULL, kernel_constraint = 12 | NULL, bias_constraint = NULL), 13 | warmstart_weights = NULL, 14 | shared_layers = NULL 15 | ) 16 | } 17 | \arguments{ 18 | \item{specific_weight_options}{specific options for certain 19 | weight terms; must be a list of length \code{length(list_of_formulas)} and 20 | each element in turn a named list (names are term names as in the formula) 21 | with specific options in a list} 22 | 23 | \item{general_weight_options}{default options for layers} 24 | 25 | \item{warmstart_weights}{While all keras layer options are availabe, 26 | the user can further specify a list for each distribution parameter 27 | with list elements corresponding to term names with values as vectors 28 | corresponding to start weights of the respective weights} 29 | 30 | \item{shared_layers}{list for each distribution parameter; 31 | each list item can be again a list of character vectors specifying terms 32 | which share layers} 33 | } 34 | \value{ 35 | Returns a list with options 36 | } 37 | \description{ 38 | Options for weights of layers 39 | } 40 | -------------------------------------------------------------------------------- /tests/testthat.R: -------------------------------------------------------------------------------- 1 | library(testthat) 2 | library(deepregression) 3 | 4 | if (reticulate::py_module_available("tensorflow") & 5 | reticulate::py_module_available("keras") & 6 | .Platform$OS.type != "windows"){ 7 | test_check("deepregression") 8 | } 9 | -------------------------------------------------------------------------------- /tests/testthat/test_controls.R: -------------------------------------------------------------------------------- 1 | context("Controls") 2 | 3 | test_that("penalty_control", { 4 | 5 | sc = penalty_control() 6 | data = data.frame(x = rnorm(100), y = rnorm(100)) 7 | expect_equal(sc$sp_scale(data), 1/nrow(data)) 8 | expect_false(sc$null_space_penalty) 9 | expect_false(sc$hat1) 10 | expect_true(sc$anisotropic) 11 | expect_true(sc$zero_constraint_for_smooths) 12 | expect_is(sc$df, "numeric") 13 | 14 | evaluated_smooth <- suppressWarnings(sc$defaultSmoothing( 15 | smoothCon(s(x), 16 | data=data, 17 | absorb.cons = sc$absorb_cons, 18 | null.space.penalty = sc$null_space_penalty 19 | ), df=6)) 20 | expect_is(evaluated_smooth, "numeric") 21 | 22 | }) 23 | 24 | test_that("orthog_control", { 25 | 26 | oc = orthog_control() 27 | expect_true(oc$orthogonalize) 28 | expect_identical(oc$orthog_type, "tf") 29 | 30 | dummy_fun <- function(x) x %>% layer_dense(5) %>% layer_dense(1) 31 | splitted_fun <- oc$split_fun(dummy_fun) 32 | expect_equal(as.character(body(splitted_fun[[1]])), 33 | c("%>%", "x", "layer_dense(5)")) 34 | expect_equal(as.character(body(splitted_fun[[2]])), 35 | c("%>%", "x", "layer_dense(1)")) 36 | 37 | expect_true(is.null(oc$deep_top)) 38 | expect_equal(get("deactivate_oz_at_test", environment(oc$orthog_fun)), TRUE) 39 | 40 | }) 41 | -------------------------------------------------------------------------------- /tests/testthat/test_customtraining.R: -------------------------------------------------------------------------------- 1 | context("Custom Training") 2 | 3 | if(FALSE){ # deactivate for now 4 | 5 | test_that("Load and fit with custom keras model", { 6 | 7 | n <- 1500 8 | deep_model <- function(x) x %>% 9 | layer_dense(units = 2L, activation = "relu", use_bias = FALSE) %>% 10 | layer_dense(units = 1L, activation = "linear") 11 | 12 | x <- runif(n) %>% as.matrix() 13 | true_mean_fun <- function(xx) sin(10 * apply(xx, 1, mean) + 1) 14 | 15 | data = data.frame(matrix(x, ncol=50)) 16 | y <- true_mean_fun(data) 17 | mod <- deepregression( 18 | y = y, 19 | data = data, 20 | list_of_formulas = list(loc = ~ 1 + d(X1), scale = ~1), 21 | list_of_deep_models = list(d = deep_model), 22 | model_fun = build_customKeras() 23 | ) 24 | 25 | expect_is(mod, "deepregression") 26 | expect_length(mod, 4) 27 | expect_true(length(setdiff(names(mod), 28 | c("model", "init_params", "fit_fun", "engine") 29 | ))==0) 30 | expect_is(mod$model, "models.custom_train_step.customKeras") 31 | 32 | mod %>% fit(epochs = 2) 33 | 34 | mod2 <- deepregression( 35 | y = y, 36 | data = data, 37 | list_of_formulas = list(loc = ~ 1 + d(X1), scale = ~1), 38 | list_of_deep_models = list(d = deep_model) 39 | ) 40 | 41 | mod2 %>% fit(epochs = 2) 42 | 43 | p1 <- mod %>% fitted() 44 | p2 <- mod2 %>% fitted() 45 | 46 | expect_equal(p1, p2) 47 | 48 | }) 49 | 50 | 51 | test_that("Use multiple optimizers", { 52 | 53 | ld1 <- layer_dense(units = 8) 54 | ld2 <- layer_dense(units = 16) 55 | ld3 <- layer_dense(units = 32) 56 | 57 | inp <- layer_input(shape = 4, batch_shape = NULL) 58 | 59 | outp <- inp %>% 60 | ld1 %>% 61 | ld2 %>% 62 | ld3 63 | 64 | model = keras_model(inputs = inp, outputs = outp) 65 | 66 | optimizers = list( 67 | tf$keras$optimizers$Adam(learning_rate=1e-4), 68 | tf$keras$optimizers$Adam(learning_rate=1e-2) 69 | ) 70 | 71 | optimizers_and_layers = list(tuple(optimizers[[1]], model$layers[[2]]), 72 | tuple(optimizers[[2]], model$layers[3:4])) 73 | optimizer = multioptimizer(optimizers_and_layers) 74 | model %>% compile(optimizer=optimizer, loss="mse") 75 | 76 | model %>% fit(x=matrix(rnorm(10*4), ncol=4), y=1:10, 77 | view_metrics = FALSE, verbose = FALSE) 78 | 79 | ### now in deepregression 80 | 81 | n <- 1500 82 | deep_model <- function(x) x %>% 83 | layer_dense(units = 2L, activation = "relu", use_bias = FALSE) %>% 84 | layer_dense(units = 1L, activation = "linear") 85 | 86 | x <- runif(n) %>% as.matrix() 87 | true_mean_fun <- function(xx) sin(10 * apply(xx, 1, mean) + 1) 88 | 89 | data = data.frame(matrix(x, ncol=50)) 90 | y <- true_mean_fun(data) 91 | 92 | optimizer <- function(model){ 93 | optimizers_and_layers = list(tuple(optimizers[[1]], model$layers[c(2,4)]), 94 | tuple(optimizers[[2]], model$layers[c(5,8)])) 95 | optimizer = multioptimizer(optimizers_and_layers) 96 | return(optimizer) 97 | } 98 | 99 | mod <- deepregression( 100 | y = y, 101 | data = data, 102 | list_of_formulas = list(loc = ~ 1 + d(X1), scale = ~1), 103 | list_of_deep_models = list(d = deep_model), 104 | optimizer = optimizer 105 | ) 106 | 107 | expect_is(mod, "deepregression") 108 | expect_length(mod, 4) 109 | expect_true(length(setdiff(names(mod), 110 | c("model", "init_params", "fit_fun", "engine") 111 | ))==0) 112 | 113 | mod %>% fit(epochs = 2) 114 | 115 | mod2 <- deepregression( 116 | y = y, 117 | data = data, 118 | list_of_formulas = list(loc = ~ 1 + d(X1), scale = ~1), 119 | list_of_deep_models = list(d = deep_model) 120 | ) 121 | 122 | mod2 %>% fit(epochs = 2) 123 | 124 | expect_false(all((mod %>% fitted())==(mod2 %>% fitted()))) 125 | 126 | }) 127 | 128 | } -------------------------------------------------------------------------------- /tests/testthat/test_customtraining_torch.R: -------------------------------------------------------------------------------- 1 | context("Custom Training") 2 | 3 | 4 | test_that("Use multiple optimizers torch", { 5 | 6 | fc1 <- nn_linear(1, 50) 7 | fc2 <- nn_linear(50, 1) 8 | net <- nn_module( 9 | "Net", 10 | initialize = function() { 11 | self$fc1 <- fc1 12 | self$fc2 <- fc2 13 | }, 14 | forward = function(x) { 15 | x %>% 16 | self$fc1() %>% 17 | nnf_relu() %>% 18 | self$fc2() 19 | } 20 | ) 21 | 22 | set_optimizers = function(model_parameters, lr_fc1 = 0, lr_fc2 = 0.01) { 23 | list( 24 | opt_fc1 = optim_adam(model_parameters[1:2], lr = lr_fc1), 25 | opt_fc2 = optim_adam(model_parameters[3:4], lr = lr_fc2) 26 | ) 27 | } 28 | 29 | pre_fit <- net %>% luz::setup(loss = nn_mse_loss(), optimizer = set_optimizers) 30 | 31 | pre_fit_weights <- lapply(pre_fit()$parameters, function(x) as_array(x)) 32 | fit(pre_fit, 33 | data = list( 34 | matrix(rnorm(100), ncol = 1), 35 | matrix(rnorm(100), ncol = 1)), 36 | epochs = 10) 37 | 38 | after_fit_weights <- lapply(pre_fit()$parameters, function(x) as_array(x)) 39 | expect_true( 40 | identical(pre_fit_weights[1:2], 41 | after_fit_weights[1:2]) 42 | ) 43 | expect_false( 44 | identical(pre_fit_weights[3:4], 45 | after_fit_weights[3:4])) 46 | 47 | ### now in deepregression 48 | 49 | net <- nn_module( 50 | "Net", 51 | initialize = function() { 52 | self$fc1 <- nn_linear(1, 50) 53 | self$fc2 <- nn_linear(50, 1) 54 | }, 55 | forward = function(x) { 56 | x %>% 57 | self$fc1() %>% 58 | nnf_relu() %>% 59 | self$fc2() 60 | } 61 | ) 62 | 63 | 64 | 65 | n <- 1500 66 | x <- runif(n) %>% as.matrix() 67 | true_mean_fun <- function(xx) sin(10 * apply(xx, 1, mean) + 1) 68 | 69 | data = data.frame(matrix(x, ncol=50)) 70 | y <- true_mean_fun(data) 71 | 72 | set_optimizers = function(model_parameters, 73 | lr_loc_fc1 = 0, 74 | lr_loc_fc2 = 0.01, 75 | lr_scale_inter = 0) { 76 | list( 77 | opt_loc_fc1 = optim_adam(model_parameters[1:2], lr = lr_loc_fc1), 78 | opt_loc_fc2 = optim_adam(model_parameters[3:4], lr = lr_loc_fc2), 79 | opt_scale_intercept = optim_adam(model_parameters[5], lr = lr_scale_inter) 80 | ) 81 | } 82 | 83 | mod <- deepregression( 84 | y = y, 85 | data = data, 86 | list_of_formulas = list(loc = ~-1 + d(X1), scale = ~1), 87 | list_of_deep_models = list(d = net), engine = "torch", 88 | optimizer = set_optimizers 89 | ) 90 | 91 | expect_is(mod, "deepregression") 92 | expect_length(mod, 4) 93 | expect_true(length(setdiff(names(mod), 94 | c("model", "init_params", "fit_fun", "engine") 95 | ))==0) 96 | 97 | pre_fit_weights <- get_weights_torch(mod) 98 | mod %>% fit(epochs = 10) 99 | after_fit_weights <- get_weights_torch(mod) 100 | 101 | expect_equal( 102 | pre_fit_weights[1:2], 103 | after_fit_weights[1:2] 104 | ) 105 | expect_equal( 106 | pre_fit_weights[5], 107 | after_fit_weights[5] 108 | ) 109 | 110 | expect_false( 111 | identical( 112 | list(pre_fit_weights[3:4]), 113 | list(after_fit_weights[3:4]) 114 | ) 115 | ) 116 | 117 | }) 118 | -------------------------------------------------------------------------------- /tests/testthat/test_data_handler.R: -------------------------------------------------------------------------------- 1 | context("Data Handler") 2 | 3 | test_that("loop_through_pfc_and_call_trafo", { 4 | 5 | # only structured 6 | form = ~ 1 + d(x) + s(x) + lasso(z) + ridge(z) + te(y, df = 5) %OZ% (y + s(x)) + d(z) %OZ% s(x) + u 7 | data = data.frame(x = rnorm(100), y = rnorm(100), z = rnorm(100), u = rnorm(100)) 8 | controls = penalty_control() 9 | controls$with_layer <- TRUE 10 | output_dim = 1L 11 | param_nr = 1L 12 | d = dnn_placeholder_processor(function(x) layer_dense(x, units=1L)) 13 | specials = c("s", "te", "ti", "vc", "lasso", "ridge", "offset", "vi", "fm", "vfm") 14 | specials_to_oz = c("d") 15 | gam_terms <- precalc_gam(list(form), data, controls) 16 | controls$gamdata <- gam_terms 17 | 18 | res1 <- suppressWarnings( 19 | process_terms(form = form, 20 | d = dnn_placeholder_processor(function(x) x %>% layer_dense(x, units=1L)), 21 | specials_to_oz = specials_to_oz, 22 | data = data, 23 | output_dim = output_dim, 24 | automatic_oz_check = TRUE, 25 | param_nr = 1, 26 | controls = controls, 27 | parsing_options = form_control()) 28 | ) 29 | 30 | ll <- loop_through_pfc_and_call_trafo(list(res1)) 31 | expect_true(all(!is.null(sapply(ll, dim)))) 32 | expect_is(ll, "list") 33 | ll <- loop_through_pfc_and_call_trafo(list(res1), data) 34 | expect_true(all(!is.null(sapply(ll, dim)))) 35 | expect_is(ll, "list") 36 | 37 | # semi-structured 38 | data <- as.list(data) 39 | mnist <- dataset_mnist() 40 | data$arr <- mnist$train$x[1:100,,] 41 | form = ~ 1 + d(arr) + s(x) + lasso(z) + ridge(z) + te(y, df = 5) %OZ% (y + s(x)) + d(z) %OZ% s(x) + u 42 | gam_terms <- precalc_gam(list(form), data, controls) 43 | controls$gamdata <- gam_terms 44 | 45 | res1 <- suppressWarnings( 46 | process_terms(form = form, 47 | d = dnn_placeholder_processor(function(x) x %>% layer_dense(x, units=1L)), 48 | specials_to_oz = specials_to_oz, 49 | data = data, 50 | output_dim = output_dim, 51 | automatic_oz_check = TRUE, 52 | param_nr = 1, 53 | controls = controls, 54 | parsing_options = form_control()) 55 | ) 56 | ll <- loop_through_pfc_and_call_trafo(list(res1)) 57 | expect_true(all(!is.null(sapply(ll, dim)))) 58 | expect_is(ll, "list") 59 | ll <- loop_through_pfc_and_call_trafo(list(res1), data) 60 | expect_true(all(!is.null(sapply(ll, dim)))) 61 | expect_is(ll, "list") 62 | 63 | }) 64 | 65 | test_that("to_matrix", { 66 | 67 | data <- list(array_input = dataset_mnist()$train[[1]][1:100,,]) 68 | expect_equal(to_matrix(data), data[[1]]) 69 | data <- data.frame(a=1:100,b=1:100) 70 | expect_equal(to_matrix(data), as.matrix(data)) 71 | data <- list(a=1:100,b=1:100) 72 | expect_equal(to_matrix(data), do.call("cbind", data)) 73 | 74 | }) -------------------------------------------------------------------------------- /tests/testthat/test_data_handler_torch.R: -------------------------------------------------------------------------------- 1 | context("Data Handler Torch") 2 | 3 | test_that("loop_through_pfc_and_call_trafo", { 4 | 5 | # only structured 6 | form = ~ 1 + d(x) + s(x) + lasso(z) + ridge(z) + te(y, df = 5) + d(z) + u 7 | data = data.frame(x = rnorm(100), y = rnorm(100), z = rnorm(100), u = rnorm(100)) 8 | controls = penalty_control() 9 | controls$with_layer <- TRUE 10 | output_dim = 1L 11 | param_nr = 1L 12 | d = dnn_placeholder_processor(function(x) nn_linear(in_features = ncol(x), out_features = 1L)) 13 | specials = c("s", "te", "ti", "vc", "lasso", "ridge", "offset", "vi", "fm", "vfm") 14 | specials_to_oz = c("d") 15 | gam_terms <- precalc_gam(list(form), data, controls) 16 | controls$gamdata <- gam_terms 17 | 18 | res1 <- suppressWarnings( 19 | process_terms(form = form, 20 | d = d, 21 | specials_to_oz = specials_to_oz, 22 | data = data, 23 | output_dim = output_dim, 24 | automatic_oz_check = TRUE, 25 | param_nr = 1, 26 | controls = controls, 27 | parsing_options = form_control(), engine = "torch") 28 | ) 29 | 30 | ll <- loop_through_pfc_and_call_trafo(list(res1), engine = "torch") 31 | expect_true(all(!is.null(sapply(ll, dim)))) 32 | expect_is(ll, "list") 33 | ll <- loop_through_pfc_and_call_trafo(list(res1), data, engine = "torch") 34 | expect_true(all(!is.null(sapply(ll, dim)))) 35 | expect_is(ll, "list") 36 | 37 | # semi-structured 38 | data <- as.list(data) 39 | mnist <- dataset_mnist() 40 | data$arr <- mnist$train$x[1:100,,] 41 | form = ~ 1 + d(arr) + s(x) + lasso(z) + ridge(z) + te(y, df = 5)+ u 42 | gam_terms <- precalc_gam(list(form), data, controls) 43 | controls$gamdata <- gam_terms 44 | 45 | res1 <- suppressWarnings( 46 | process_terms(form = form, 47 | d = d, 48 | specials_to_oz = specials_to_oz, 49 | data = data, 50 | output_dim = output_dim, 51 | automatic_oz_check = TRUE, 52 | param_nr = 1, engine = "torch", 53 | controls = controls, 54 | parsing_options = form_control()) 55 | ) 56 | ll <- loop_through_pfc_and_call_trafo(list(res1), engine = "torch") 57 | expect_true(all(!is.null(sapply(ll, dim)))) 58 | expect_is(ll, "list") 59 | ll <- loop_through_pfc_and_call_trafo(list(res1), data, engine = "torch") 60 | expect_true(all(!is.null(sapply(ll, dim)))) 61 | expect_is(ll, "list") 62 | 63 | }) 64 | 65 | test_that("properties of dataset torch", { 66 | n <- 100 67 | loc_x <- matrix(runif(n), ncol = 1) 68 | scale_intercept <- loc_intercept <- matrix(rep(1, n), ncol = 1) 69 | target <- matrix(runif(n = n), ncol = 1) 70 | 71 | data <- c( 72 | list(list(loc_intercept, loc_x)), 73 | list(list(scale_intercept))) 74 | 75 | mod <- deepregression(y = target, list_of_formulas = 76 | list(loc = ~ 1 + x, 77 | scale = ~ 1), data = data.frame("x" = loc_x), 78 | engine = "torch") 79 | 80 | luz_dataset <- get_luz_dataset(df_list = data, object = mod) 81 | 82 | expect_true("deepregression_luz_dataset" %in% class(luz_dataset)) 83 | 84 | # two parameters 85 | expect_equal(length(luz_dataset$.getbatch(1)[[1]]), length(data)[[1]]) 86 | 87 | expect_true( 88 | luz_dataset$.length() == n 89 | ) 90 | 91 | luz_dataset <- get_luz_dataset(df_list = data, target = target, object = mod) 92 | # two parameters 93 | expect_equal(length(luz_dataset$.getbatch(1)[[1]]), attr( 94 | make_torch_dist(mod$init_params$family), "nrparams_dist")) 95 | 96 | expect_true( 97 | luz_dataset$.length() == n 98 | ) 99 | expect_true( 100 | length(luz_dataset$target) == n 101 | ) 102 | expect_true( 103 | ncol(luz_dataset$target) == 1 104 | ) 105 | 106 | 107 | }) 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | -------------------------------------------------------------------------------- /tests/testthat/test_ensemble.R: -------------------------------------------------------------------------------- 1 | context("Deep ensembles") 2 | 3 | test_that("deep ensemble", { 4 | 5 | set.seed(42) 6 | n <- 1000 7 | data <- data.frame(matrix(rnorm(4*n), c(n,4))) 8 | colnames(data) <- c("x1", "x2", "x3", "xa") 9 | 10 | y <- rnorm(n) + data$xa^2 + data$x1 11 | 12 | # check fake custom model 13 | mod <- deepregression( 14 | list_of_formulas = list(loc = ~ 1 + s(xa) + x1, scale = ~ 1), 15 | data = data, y = y 16 | ) 17 | 18 | cf_init <- coef(mod) 19 | ret <- ensemble(mod, epochs = 10, save_weights = TRUE, verbose = TRUE) 20 | cf_post <- coef(mod) 21 | 22 | expect_identical(cf_init, cf_post) 23 | 24 | edist <- get_ensemble_distribution(ret) 25 | nll <- .call_for_all_members(ret, \(x) -mean(tfd_log_prob(get_distribution(x) %>% tfd_independent(), y)$numpy())) 26 | nlle <- - mean(tfd_log_prob(edist %>% tfd_independent(), y)$numpy()) 27 | expect_lte(nlle, mean(unlist(nll))) 28 | 29 | expect_length(cf <- coef.drEnsemble(ret), 3L) 30 | expect_equal(dim(cf$x1), c(1, 5)) 31 | 32 | fitt <- fitted.drEnsemble(ret) 33 | expect_is(fitt, "list") 34 | 35 | }) 36 | 37 | test_that("reinitializing weights", { 38 | 39 | n <- 100 40 | data = data.frame(matrix(rnorm(4*n), c(n,4))) 41 | colnames(data) <- c("x1","x2","x3","xa") 42 | formula <- ~ 1 + deep_model(x1,x2,x3) + s(xa) + x1 43 | 44 | deep_model <- function(x) x %>% 45 | layer_dense(units = 32, activation = "relu", use_bias = FALSE) %>% 46 | layer_dropout(rate = 0.2) %>% 47 | layer_dense(units = 8, activation = "relu") %>% 48 | layer_dense(units = 1, activation = "linear") 49 | 50 | y <- rnorm(n) + data$xa^2 + data$x1 51 | 52 | # check fake custom model 53 | mod <- deepregression( 54 | list_of_formulas = list(loc = ~ 1 + s(xa) + x1, scale = ~ 1), 55 | data = data, y = y, 56 | list_of_deep_models = list(deep_model = deep_model), 57 | model_fun = build_customKeras(), 58 | weight_options = weight_control( 59 | warmstart_weights = list(list("x1" = 0), list()) 60 | ) 61 | ) 62 | 63 | reinit_weights(mod, seed = 1) 64 | cfa <- coef(mod) 65 | reinit_weights(mod, seed = 2) 66 | cfb <- coef(mod) 67 | 68 | expect_false(all(cfa[[1]] == cfb[[1]])) 69 | 70 | fit(mod, epochs = 2) 71 | reinit_weights(mod, seed = 3) 72 | fit(mod, epochs = 2) 73 | 74 | expect_identical(cfa$x1, cfb$x1) 75 | 76 | }) 77 | -------------------------------------------------------------------------------- /tests/testthat/test_ensemble_torch.R: -------------------------------------------------------------------------------- 1 | context("Deep ensembles Torch") 2 | 3 | test_that("deep ensemble", { 4 | 5 | set.seed(42) 6 | n <- 1000 7 | data <- data.frame(matrix(rnorm(4*n), c(n,4))) 8 | colnames(data) <- c("x1", "x2", "x3", "xa") 9 | 10 | y <- rnorm(n) + data$xa^2 + data$x1 11 | 12 | # check fake custom model 13 | mod <- deepregression( 14 | list_of_formulas = list(loc = ~ 1 + s(xa) + x1, scale = ~ 1), 15 | data = data, y = y, engine = "torch", 16 | orthog_options = orthog_control(orthogonalize = F) 17 | ) 18 | 19 | cf_init <- coef(mod) 20 | ret <- ensemble(mod, epochs = 10, save_weights = TRUE, verbose = TRUE, 21 | n_ensemble = 3) 22 | cf_post <- coef(mod) 23 | 24 | expect_identical(cf_init, cf_post) 25 | 26 | expect_length(cf <- coef.drEnsemble(ret), 3L) 27 | expect_equal(dim(cf$x1), c(1, 3)) 28 | 29 | fitt <- fitted.drEnsemble(ret) 30 | expect_is(fitt, "list") 31 | 32 | }) 33 | 34 | test_that("reinitializing weights", { 35 | 36 | n <- 100 37 | data = data.frame(matrix(rnorm(4*n), c(n,4))) 38 | colnames(data) <- c("x1","x2","x3","xa") 39 | formula <- ~ 1 + deep_model(x1,x2,x3) + s(xa) + x1 40 | 41 | deep_model <- function(){ 42 | nn_sequential( 43 | nn_linear(in_features = 3, out_features = 32, bias = F), 44 | nn_relu(), 45 | nn_dropout(p = 0.2), 46 | nn_linear(in_features = 32, out_features = 8), 47 | nn_relu(), 48 | nn_linear(in_features = 8, out_features = 1) 49 | ) 50 | } 51 | 52 | y <- rnorm(n) + data$xa^2 + data$x1 53 | 54 | # check fake custom model 55 | mod <- deepregression( 56 | list_of_formulas = list(loc = ~ 1 + s(xa) + x1, scale = ~ 1), 57 | data = data, y = y, engine = "torch", 58 | orthog_options = orthog_control(orthogonalize = F), 59 | list_of_deep_models = list(deep_model = deep_model), 60 | weight_options = weight_control( 61 | warmstart_weights = list(list("x1" = 0), list()) 62 | ) 63 | ) 64 | 65 | reinit_weights(mod, seed = 1) 66 | cfa <- coef(mod) 67 | 68 | reinit_weights(mod, seed = 2) 69 | cfb <- coef(mod) 70 | 71 | expect_false(all(cfa[[1]] == cfb[[1]])) 72 | 73 | fit(mod, epochs = 2) 74 | reinit_weights(mod, seed = 3) 75 | fit(mod, epochs = 2) 76 | 77 | expect_identical(cfa$x1, cfb$x1) 78 | }) 79 | -------------------------------------------------------------------------------- /tests/testthat/test_families.R: -------------------------------------------------------------------------------- 1 | context("families") 2 | 3 | test_that("tfd families", { 4 | families = c("normal", "bernoulli", "bernoulli_prob", "beta", "betar", 5 | "cauchy", "chi2", "chi", 6 | "exponential", "gamma", "gammar", 7 | "gumbel", "half_cauchy", "half_normal", "horseshoe", 8 | "inverse_gamma", "inverse_gaussian", "laplace", 9 | "log_normal", "logistic", "multinomial", "multinoulli", "negbinom", 10 | "pareto_ls", "poisson", "poisson_lograte", "student_t", "student_t_ls", 11 | "uniform", 12 | "zip" 13 | ) 14 | for (fam in families) { 15 | d = make_tfd_dist(fam) 16 | expect_is(d, "function") 17 | np = attr(d, "nrparams_dist") 18 | expect_true(np %in% c(1:3)) 19 | } 20 | 21 | d = make_tfd_dist("zip", trafo_list = list(exp, exp)) 22 | expect_is(d, "function") 23 | 24 | families = c("categorical", 25 | "dirichlet_multinomial", 26 | "dirichlet", 27 | "gamma_gamma", 28 | "geometric", 29 | "kumaraswamy", 30 | "truncated_normal", 31 | "von_mises", 32 | "von_mises_fisher", 33 | "wishart", 34 | "zipf", 35 | "binomial" 36 | ) 37 | for (fam in families) { 38 | expect_error(make_tfd_dist(fam), "not implemented yet") 39 | } 40 | 41 | }) 42 | 43 | test_that("tfd families can be fitted", { 44 | 45 | n <- 100 46 | 47 | # FIXME: Currently not working: 48 | # NA in fitted: "cauchy", "half_cauchy", "inverse_gamma", "student_t", "student_t_ls", "uniform" 49 | 50 | dists = c( 51 | "normal", "bernoulli", "bernoulli_prob", 52 | "beta", "betar", "chi2", "chi","exponential", 53 | "gamma", "gammar", "gumbel", "half_normal", "horseshoe", 54 | "inverse_gaussian", "laplace", "log_normal", 55 | "logistic", "negbinom", "negbinom", 56 | "pareto_ls", "poisson", "poisson_lograte" 57 | ) 58 | 59 | for(dist in dists) { 60 | set.seed(24) 61 | x <- runif(n) %>% as.matrix() 62 | z <- runif(n) %>% as.matrix() 63 | y <- exp(as.matrix(0.5*x + rnorm(n, 0, 0.1*z) + 1)) 64 | data = data.frame(x = x, z = z) 65 | if (dist %in% c("beta", "betar")) { 66 | y <- (y - min(y)) / (max(y) + 0.01 - min(y)) + runif(n, 1e-5, 1e-4) 67 | } 68 | suppressWarnings( 69 | mod <- deepregression( 70 | y = y, 71 | data = data, 72 | # define how parameters should be modeled 73 | list_of_formulas = list(~ 1 + x, ~ 1 + z, ~ 1), 74 | list_of_deep_models = NULL, 75 | family = dist, seed = 44, 76 | optimizer = tf$keras$optimizers$RMSprop(learning_rate = 0.000001) 77 | ) 78 | ) 79 | cat("Fitting", dist, "\n") 80 | res <- mod %>% fit(epochs=2L, verbose = FALSE, view_metrics = FALSE) 81 | expect_true(!sum(is.nan(unlist(res$metrics))) > 0) 82 | expect_true(!any(unlist(res$metrics)==Inf)) 83 | expect_is(mod, "deepregression") 84 | expect_true(!any(is.nan(unlist(coef(mod))))) 85 | expect_true(!any(is.nan(fitted(mod)))) 86 | suppressWarnings(res <- mod %>% predict(data)) 87 | expect_true(is.numeric(res)) 88 | expect_true(!any(is.nan(res))) 89 | } 90 | }) 91 | 92 | 93 | test_that("tfd_zip", { 94 | zipfun = tfd_zip(probs=c(0.1, 0.9), lambda=2) 95 | expect_is(zipfun, "python.builtin.object") 96 | expect_is(zipfun$cdf, "python.builtin.method") 97 | expect_true(as.numeric(zipfun$log_prob(1)) < 0) 98 | expect_true(as.numeric(zipfun$log_prob(0)) > as.numeric(zipfun$log_prob(1))) 99 | }) 100 | 101 | 102 | test_that("tffuns", { 103 | x = 2 104 | y = 3 105 | expect_is(tfe(x), "tensorflow.tensor") 106 | expect_is(tfsig(x), "tensorflow.tensor") 107 | expect_is(tfsoft(c(x,y)), "tensorflow.tensor") 108 | expect_is(tfsqrt(x), "tensorflow.tensor") 109 | expect_is(tfsq(x), "tensorflow.tensor") 110 | expect_is(tfdiv(x,y), c("numeric","tensorflow.tensor")) 111 | expect_is(tfrec(x), "tensorflow.tensor") 112 | expect_is(tfmult(x,y), "tensorflow.tensor") 113 | }) 114 | 115 | if(FALSE){ 116 | test_that("tfd_mvr", { 117 | 118 | n <- 100 119 | 120 | set.seed(24) 121 | x <- runif(n) %>% as.matrix() 122 | z <- runif(n) %>% as.matrix() 123 | y <- exp(as.matrix(0.5*x + rnorm(n, 0, 0.1*z) + 1)) 124 | data = data.frame(x = x, z = z) 125 | 126 | suppressWarnings( 127 | mod <- deepregression( 128 | y = y, 129 | data = data, 130 | # define how parameters should be modeled 131 | list_of_formulas = list(~ 1 + x, ~ 1 + x), 132 | list_of_deep_models = NULL, 133 | family = "mvr", 134 | seed = 44 135 | ) 136 | ) 137 | res <- mod %>% fit(epochs=2L, verbose = FALSE, view_metrics = FALSE) 138 | expect_true(!sum(is.nan(unlist(res$metrics))) > 0) 139 | expect_true(!any(unlist(res$metrics)==Inf)) 140 | expect_is(mod, "deepregression") 141 | expect_true(!any(is.nan(unlist(coef(mod))))) 142 | expect_true(!any(is.nan(fitted(mod)))) 143 | suppressWarnings(res <- mod %>% predict(data)) 144 | expect_true(is.numeric(res)) 145 | expect_true(!any(is.nan(res))) 146 | 147 | }) 148 | } -------------------------------------------------------------------------------- /tests/testthat/test_families_torch.R: -------------------------------------------------------------------------------- 1 | context("families Torch") 2 | 3 | test_that("torch families", { 4 | families = c("normal", "bernoulli", "bernoulli_prob", "gamma", 5 | "poisson" ) 6 | 7 | for (fam in families) { 8 | d = make_torch_dist(fam) 9 | expect_is(d, "function") 10 | np = attr(d, "nrparams_dist") 11 | expect_true(np %in% c(1:3)) 12 | } 13 | 14 | families = c("categorical", 15 | "dirichlet_multinomial", 16 | "dirichlet", 17 | "gamma_gamma", 18 | "geometric", 19 | "kumaraswamy", 20 | "truncated_normal", 21 | "von_mises", 22 | "von_mises_fisher", 23 | "wishart", 24 | "zipf", "beta", 25 | "betar", 26 | "cauchy", 27 | "chi2", 28 | "chi", 29 | "exponential", 30 | "gammar", 31 | "gumbel", 32 | "half_cauchy", 33 | "half_normal", 34 | "horseshoe", 35 | "inverse_gamma", 36 | "inverse_gaussian", 37 | "laplace", 38 | "log_normal", 39 | "logistic", 40 | "multinomial", 41 | "multinoulli", 42 | "negbinom", 43 | "pareto_ls", 44 | "poisson_lograte", 45 | "student_t", 46 | "student_t_ls", 47 | "uniform", 48 | "zip") 49 | for (fam in families) { 50 | expect_error(make_torch_dist(fam), "not implemented") 51 | } 52 | 53 | }) 54 | 55 | test_that("torch families can be fitted", { 56 | 57 | n <- 100 58 | 59 | dists = c( 60 | "normal", "bernoulli", "bernoulli_prob", 61 | "gamma", "poisson") 62 | 63 | for(dist in dists) { 64 | set.seed(24) 65 | x <- runif(n) %>% as.matrix() 66 | z <- runif(n) %>% as.matrix() 67 | y <- exp(as.matrix(0.5*x + rnorm(n, 0, 0.1*z) + 1)) 68 | data = data.frame(x = x, z = z) 69 | 70 | nr_params <- attr(make_torch_dist(dist), "nrparams_dist") 71 | 72 | list_of_formulas <- switch(nr_params, 73 | "1" = list(~ 1 + x), 74 | "2" = list(~ 1 + x, ~ 1 + z)) 75 | 76 | mod <- deepregression( 77 | y = y, 78 | data = data, 79 | # define how parameters should be modeled 80 | list_of_formulas = list_of_formulas, 81 | list_of_deep_models = NULL, 82 | family = dist, seed = 44, engine = "torch") 83 | 84 | cat("Fitting", dist, "\n") 85 | res <- mod %>% fit(epochs=2L, verbose = FALSE, view_metrics = FALSE) 86 | expect_true(!sum(is.nan(unlist(res$metrics))) > 0) 87 | expect_true(!any(unlist(res$metrics)==Inf)) 88 | expect_is(mod, "deepregression") 89 | expect_true(!any(is.nan(unlist(coef(mod))))) 90 | expect_true(!any(is.nan(fitted(mod)))) 91 | suppressWarnings(res <- mod %>% predict(data)) 92 | expect_true(is.numeric(res)) 93 | expect_true(!any(is.nan(res))) 94 | } 95 | }) 96 | -------------------------------------------------------------------------------- /tests/testthat/test_helperfuns.R: -------------------------------------------------------------------------------- 1 | context("Helper Functions") 2 | 3 | test_that("separate_define_relation", { 4 | 5 | form = ~ 1 + d(x) + s(x) + lasso(z) + ridge(z) + te(y) %OZ% (y + s(x)) + d(z) %OZ% s(x) 6 | specials = c("s", "te", "ti", "vc", "lasso", "ridge", "offset", "vi", "fm", "vfm") 7 | specials_to_oz = c("d") 8 | 9 | # with automatic OZ 10 | res1 <- separate_define_relation(form, specials, specials_to_oz, automatic_oz_check = TRUE) 11 | expect_is(res1, "list") 12 | expect_equal(length(res1), 8) 13 | expect_equal(res1[[2]]$right_from_oz, c(1,5,6)) 14 | # without automatic OZ 15 | res2 <- separate_define_relation(form, specials, specials_to_oz, automatic_oz_check = FALSE) 16 | expect_is(res2, "list") 17 | expect_equal(length(res2), 8) 18 | expect_equal(res2[[2]]$right_from_oz, c(5,6)) 19 | # without DNN 20 | specials_to_oz = c() 21 | form = ~ 1 + s(x) + lasso(z) + ridge(z) + te(y) %OZ% (y + s(x)) 22 | # with automatic OZ 23 | res3 <- separate_define_relation(form, specials, specials_to_oz, automatic_oz_check = TRUE) 24 | # without automatic OZ 25 | res4 <- separate_define_relation(form, specials, specials_to_oz, automatic_oz_check = FALSE) 26 | expect_equal(res3, res4) 27 | 28 | }) 29 | -------------------------------------------------------------------------------- /tests/testthat/test_layers.R: -------------------------------------------------------------------------------- 1 | context("deepregression layers") 2 | 3 | test_that("custom layers", { 4 | 5 | set.seed(42) 6 | tf$random$set_seed(42) 7 | n <- 1000 8 | p <- 50 9 | x <- runif(n*p) %>% matrix(ncol=p) 10 | y <- 10*x[,1] + rnorm(n) 11 | 12 | inp <- layer_input(shape=c(p), 13 | batch_shape = NULL) 14 | out <- layer_hadamard_diff(units=1L, la=1, 15 | initu = tf$initializers$constant(1e-6), 16 | initv = tf$initializers$constant(1e-6))( 17 | inp 18 | ) 19 | mod <- keras_model(inp, out) 20 | 21 | mod %>% compile(loss="mse", 22 | optimizer = tf$optimizers$Adam(learning_rate=1e-2)) 23 | 24 | mod %>% fit(x=x, y=matrix(y), epochs=500L, 25 | verbose=FALSE, 26 | validation_split=0.1) 27 | u <- as.matrix(mod$weights[[1]]) 28 | v <- as.matrix(mod$weights[[2]]) 29 | beta <- u^2-v^2 30 | expect_true(beta[1]>0.25) 31 | # does not work: 32 | expect_true(max(abs(beta[-1]))<1e-4) 33 | 34 | }) 35 | 36 | 37 | test_that("lasso layers", { 38 | 39 | set.seed(42) 40 | tf$random$set_seed(42) 41 | n <- 1000 42 | p <- 50 43 | x <- runif(n*p) %>% matrix(ncol=p) 44 | y <- 10*x[,1] + rnorm(n) 45 | 46 | inp <- layer_input(shape=c(p), 47 | batch_shape = NULL) 48 | out <- tib_layer(units=1L, la=1)(inp) 49 | mod <- keras_model(inp, out) 50 | 51 | mod %>% compile(loss="mse", 52 | optimizer = tf$optimizers$Adam(learning_rate=1e-2)) 53 | 54 | mod %>% fit(x=x, y=matrix(y), epochs=500L, 55 | verbose=FALSE, 56 | validation_split=0.1) 57 | expect_true(abs(Reduce("prod", lapply(mod$get_weights(),c))) < 1) 58 | 59 | }) 60 | -------------------------------------------------------------------------------- /tests/testthat/test_layers_torch.R: -------------------------------------------------------------------------------- 1 | context("deepregression layers Torch") 2 | 3 | test_that("lasso layers", { 4 | 5 | set.seed(42) 6 | torch_manual_seed(42) 7 | n <- 1000 8 | p <- 50 9 | x <- runif(n*p) %>% matrix(ncol=p) 10 | y <- 10*x[,1] + rnorm(n) 11 | 12 | input <- torch_tensor(x) 13 | data_x <- input 14 | data_y <- torch_tensor(y) 15 | 16 | tib_module <- tib_layer_torch(units = 1, la = 1, input_shape = 50) 17 | optimizer_tiblasso <- optim_adam(tib_module$parameters, lr=1e-2) 18 | 19 | batch_size <- 32 20 | num_data_points <- data_y$size(1) 21 | num_batches <- floor(num_data_points/batch_size) 22 | 23 | epochs <- 250 24 | for(epoch in 1:epochs){ 25 | l <- c() 26 | # rearrange the data each epoch 27 | permute <- torch_randperm(num_data_points) + 1L 28 | data_x <- data_x[permute] 29 | data_y <- data_y[permute] 30 | # manually loop through the batches 31 | for(batch_idx in 1:num_batches){ 32 | # here index is a vector of the indices in the batch 33 | index <- (batch_size*(batch_idx-1) + 1):(batch_idx*batch_size) 34 | 35 | x_batch <- data_x[index] 36 | y_batch <- data_y[index] 37 | 38 | optimizer_tiblasso$zero_grad() 39 | output <- tib_module(x_batch) %>% torch_flatten() 40 | l_tib <- nnf_mse_loss(output, y_batch) 41 | l_tib$backward() 42 | optimizer_tiblasso$step() 43 | l <- c(l, l_tib$item()) 44 | } 45 | } 46 | 47 | expect_true( 48 | abs(Reduce(x = apply( 49 | cbind(t(as.array(tib_module$parameters[[1]])), 50 | as.array(tib_module$parameters[[2]])), 51 | MARGIN = 1, 52 | prod), 53 | f = "prod")) < 1) 54 | 55 | }) 56 | -------------------------------------------------------------------------------- /tests/testthat/test_methods.R: -------------------------------------------------------------------------------- 1 | context("deepregression methods") 2 | 3 | test_that("all methods", { 4 | n <- 1500 5 | deep_model <- function(x) x %>% 6 | layer_dense(units = 2L, activation = "relu", use_bias = FALSE) %>% 7 | layer_dense(units = 1L, activation = "linear") 8 | 9 | x <- runif(n) %>% matrix(ncol=3) 10 | true_mean_fun <- function(xx) sin(10 * apply(xx, 1, mean) + 1) + 11 | sapply(xx[, 3], function(x) rnorm(1, mean=0,sd=x)) 12 | 13 | data = data.frame(matrix(x, ncol=3)) 14 | y <- true_mean_fun(data) 15 | mod <- deepregression( 16 | y = y, 17 | data = data, 18 | list_of_formulas = list(loc = ~ X3 + d(X1) + g(X2), scale = ~X3), 19 | list_of_deep_models = list(d = deep_model, g = deep_model) 20 | ) 21 | mod %>% fit(epochs=3L, verbose = FALSE, view_metrics = TRUE) 22 | 23 | mn = mean(mod, data) 24 | expect_is(mn, "matrix") 25 | expect_true(nrow(mn) == 500) 26 | expect_true(length(unique(mn)) > 1L) 27 | 28 | std = stddev(mod, data) 29 | expect_is(std, "matrix") 30 | expect_true(nrow(std) == 500) 31 | expect_true(length(unique(std)) > 1L) 32 | 33 | q95 = quant(mod, data, 0.95) 34 | q05 = quant(mod, data, 0.05) 35 | expect_true(all(q95 > mn & mn > q05)) 36 | 37 | expect_equal(predict(mod, data), mn) 38 | expect_equal(fitted(mod), mn) 39 | expect_true(plot(mod) == "No smooth effects. Nothing to plot.") 40 | 41 | cf = coef(mod) 42 | expect_is(cf, "list") 43 | # lapply(cf, function(x) { 44 | # sl = x$structured_linear 45 | # expect_is(sl, "matrix") 46 | # expect_equal(dim(sl), c(2,1)) 47 | # NULL 48 | # }) 49 | 50 | expect_output(print(mod), "Model") 51 | expect_output(print(mod), "Total params: 14") 52 | 53 | dst = get_distribution(mod) 54 | expect_is(dst, "python.builtin.object") 55 | 56 | ls = log_score(mod, data) 57 | expect_true(all(ls < 0)) 58 | expect_true(all(dim(ls) == c(500, 1))) 59 | }) 60 | -------------------------------------------------------------------------------- /tests/testthat/test_methods_torch.R: -------------------------------------------------------------------------------- 1 | context("deepregression methods Torch") 2 | 3 | test_that("all methods", { 4 | 5 | n <- 1500 6 | deep_model <- function() nn_sequential( 7 | nn_linear(in_features = 1, out_features = 2, bias = F), 8 | nn_relu(), 9 | nn_linear(in_features = 2, out_features = 1) 10 | ) 11 | 12 | x <- runif(n) %>% matrix(ncol=3) 13 | true_mean_fun <- function(xx) sin(10 * apply(xx, 1, mean) + 1) + 14 | sapply(xx[, 3], function(x) rnorm(1, mean=0,sd=x)) 15 | 16 | data = data.frame(matrix(x, ncol=3)) 17 | y <- true_mean_fun(data) 18 | mod <- deepregression( 19 | y = y, 20 | data = data, 21 | list_of_formulas = list(loc = ~ X3 + d(X1) + g(X2), scale = ~X3), 22 | list_of_deep_models = list(d = deep_model, g = deep_model), engine = "torch" 23 | ) 24 | mod %>% fit(epochs=3L, verbose = FALSE, view_metrics = TRUE) 25 | 26 | mn = mean(mod, data) 27 | expect_is(mn, "matrix") 28 | expect_true(nrow(mn) == 500) 29 | expect_true(length(unique(mn)) > 1L) 30 | 31 | std = stddev(mod, data) 32 | expect_is(std, "matrix") 33 | expect_true(nrow(std) == 500) 34 | expect_true(length(unique(std)) > 1L) 35 | 36 | q95 = quant(mod, data, 0.95) 37 | q05 = quant(mod, data, 0.05) 38 | expect_true(all(q95 > mn & mn > q05)) 39 | 40 | expect_equal(predict(mod, data), mn) 41 | expect_equal(fitted(mod), mn) 42 | expect_true(plot(mod) == "No smooth effects. Nothing to plot.") 43 | 44 | cf = coef(mod) 45 | expect_is(cf, "list") 46 | # lapply(cf, function(x) { 47 | # sl = x$structured_linear 48 | # expect_is(sl, "matrix") 49 | # expect_equal(dim(sl), c(2,1)) 50 | # NULL 51 | # }) 52 | 53 | expect_output(print(mod), "Model") 54 | 55 | 56 | dst = get_distribution(mod) 57 | expect_is(dst, "torch_Distribution") 58 | 59 | ls = log_score(mod, data) 60 | expect_true(all(ls < 0)) 61 | expect_true(all(dim(ls) == c(500, 1))) 62 | }) 63 | -------------------------------------------------------------------------------- /tests/testthat/test_models.R: -------------------------------------------------------------------------------- 1 | context("Model Builder") 2 | 3 | test_that("model_builder", { 4 | 5 | n <- 1000 6 | data = data.frame(matrix(rnorm(4*n), c(n,4))) 7 | colnames(data) <- c("x1","x2","x3","xa") 8 | formula <- ~ 1 + deep_model(x1,x2,x3) + s(xa) + x1 9 | 10 | deep_model <- function(x) x %>% 11 | layer_dense(units = 32, activation = "relu", use_bias = FALSE) %>% 12 | layer_dropout(rate = 0.2) %>% 13 | layer_dense(units = 8, activation = "relu") %>% 14 | layer_dense(units = 1, activation = "linear") 15 | 16 | y <- rnorm(n) + data$xa^2 + data$x1 17 | 18 | # check fake custom model 19 | mod <- deepregression( 20 | list_of_formulas = list(loc = ~ 1 + s(xa) + x1, scale = ~ 1), 21 | data = data, y = y, 22 | list_of_deep_models = list(deep_model = deep_model), 23 | model_fun = build_customKeras() 24 | ) 25 | expect_equal(class(mod$model)[1], "models.custom_train_step.customKeras") 26 | ret <- mod %>% fit(epochs = 2) 27 | 28 | }) -------------------------------------------------------------------------------- /tests/testthat/test_orthogonalization_torch.R: -------------------------------------------------------------------------------- 1 | context("Orthogonalization torch") 2 | 3 | test_that("orthogonalization not implemented", { 4 | set.seed(24) 5 | 6 | n <- 150 7 | b0 <- 1 8 | simnr <- 10 9 | true_sd <- 2 10 | 11 | p <- 1 12 | 13 | list_of_funs <- list(function(x) sin(10*x), 14 | function(x) tanh(3*x), 15 | function(x) x^2, 16 | function(x) cos(x*3-2)*(-x*3), 17 | function(x) exp(x*2) - 1 18 | ) 19 | 20 | X <- matrix(runif(p*n), ncol=p) 21 | partpred_l <- sapply(1:p, function(j) 4/j*X[,j]) 22 | partpred_nl <- sapply(1:p, function(j) 23 | list_of_funs[[j]](X[,j])) 24 | 25 | true_mean <- b0 + rowSums(partpred_l) + rowSums(partpred_l) 26 | 27 | # training data 28 | y <- true_mean + rnorm(n = n, mean = 0, sd = true_sd) 29 | 30 | data = data.frame(X) 31 | colnames(data) <- paste0("V", 1:p) 32 | vars <- paste0("V", 1:p) 33 | form <- paste0("~ 1 + ", paste(vars, collapse = " + "), " + s(", 34 | paste(vars, collapse = ") + s("), ") + d(", 35 | paste(vars, collapse = ", "), ")") 36 | 37 | 38 | deep_model <- function() nn_sequential( 39 | nn_linear(1, 32), 40 | nn_relu(), 41 | nn_dropout(p = 0.2), 42 | nn_linear(32, 16), 43 | nn_relu(), 44 | nn_linear(16,1) 45 | ) 46 | 47 | 48 | expect_error( 49 | deepregression( 50 | y = y, 51 | data = data, 52 | list_of_formulas = list(loc = as.formula(form), scale = ~1), 53 | list_of_deep_models = list(d = deep_model), engine = "torch" 54 | ), "Orthogonalization not implemented for torch" 55 | ) 56 | 57 | }) 58 | -------------------------------------------------------------------------------- /tests/testthat/test_reproducibility.R: -------------------------------------------------------------------------------- 1 | context("reproducibility") 2 | 3 | test_that("reproducibility", { 4 | set.seed(24) 5 | 6 | # generate the data 7 | n <- 50 8 | b0 <- 1 9 | # training data; predictor 10 | x <- runif(n) %>% as.matrix() 11 | true_mean_fun <- function(xx) sin(10*xx) + b0 12 | # training data 13 | y <- true_mean_fun(x) + rnorm(n = n, mean = 0, sd = 2) 14 | data = data.frame(x = x) 15 | # test data 16 | x_test <- runif(n) %>% as.matrix() 17 | validation_data = data.frame(x = x_test) 18 | y_test <- true_mean_fun(x_test) + rnorm(n = n, sd = 2) 19 | 20 | deep_model <- function(x) x %>% 21 | layer_dense(units = 64, activation = "relu", use_bias = FALSE) %>% 22 | layer_dense(units = 64, activation = "relu") %>% 23 | layer_dropout(rate = 0.2) %>% 24 | layer_dense(units = 16, activation = "relu") %>% 25 | layer_dense(units = 1, activation = "linear") 26 | 27 | mod1 <- deepregression( 28 | y = y, 29 | data = data, 30 | seed = 1L, 31 | list_of_formulas = list(loc = ~ 1 + d(x), scale = ~1), 32 | list_of_deep_models = list(d = deep_model) 33 | ) 34 | 35 | mod2 <- deepregression( 36 | y = y, 37 | data = data, 38 | seed = 1L, 39 | list_of_formulas = list(loc = ~ 1 + d(x), scale = ~1), 40 | list_of_deep_models = list(d = deep_model) 41 | ) 42 | mean1 <- mod1 %>% fitted() 43 | mean2 <- mod2 %>% fitted() 44 | # before training 45 | expect_equal(coef(mod1), coef(mod2)) 46 | expect_equal(mean1, mean2) 47 | 48 | mod1 %>% fit(epochs=2L, verbose = FALSE, view_metrics = FALSE) 49 | mean1 <- mod1 %>% fitted() 50 | 51 | mod2 %>% fit(epochs=2L, verbose = FALSE, view_metrics = FALSE) 52 | mean2 <- mod2 %>% fitted() 53 | 54 | # after training 55 | expect_equal(coef(mod1), coef(mod2)) 56 | expect_equal(mean1, mean2) 57 | }) 58 | -------------------------------------------------------------------------------- /tests/testthat/test_reproducibility_torch.R: -------------------------------------------------------------------------------- 1 | context("reproducibility Torch") 2 | 3 | test_that("reproducibility", { 4 | 5 | set.seed(24) 6 | 7 | # generate the data 8 | n <- 50 9 | b0 <- 1 10 | # training data; predictor 11 | x <- runif(n) %>% as.matrix() 12 | true_mean_fun <- function(xx) sin(10*xx) + b0 13 | # training data 14 | y <- true_mean_fun(x) + rnorm(n = n, mean = 0, sd = 2) 15 | data = data.frame(x = x) 16 | # test data 17 | x_test <- runif(n) %>% as.matrix() 18 | validation_data = data.frame(x = x_test) 19 | y_test <- true_mean_fun(x_test) + rnorm(n = n, sd = 2) 20 | 21 | deep_model <- function() nn_sequential( 22 | nn_linear(in_features = 1, out_features = 64, bias = F), 23 | nn_relu(), 24 | nn_linear(in_features = 64, out_features = 64), 25 | nn_relu(), 26 | nn_dropout(p = 0.2), 27 | nn_linear(in_features = 64, out_features = 16), 28 | nn_relu(), 29 | nn_linear(in_features = 16, out_features = 1) 30 | ) 31 | 32 | 33 | mod1 <- deepregression( 34 | y = y, 35 | data = data, 36 | seed = 1L, 37 | list_of_formulas = list(loc = ~ 1 + d(x), scale = ~1), 38 | list_of_deep_models = list(d = deep_model), engine = "torch" 39 | ) 40 | 41 | mod2 <- deepregression( 42 | y = y, 43 | data = data, 44 | seed = 1L, 45 | list_of_formulas = list(loc = ~ 1 + d(x), scale = ~1), 46 | list_of_deep_models = list(d = deep_model), engine = "torch" 47 | ) 48 | mean1 <- mod1 %>% fitted() 49 | mean2 <- mod2 %>% fitted() 50 | # before training 51 | expect_equal(coef(mod1), coef(mod2)) 52 | expect_equal(mean1, mean2) 53 | 54 | torch_manual_seed(1L) 55 | mod1 %>% fit(epochs=2L, verbose = FALSE, view_metrics = FALSE) 56 | mean1 <- mod1 %>% fitted() 57 | 58 | torch_manual_seed(1L) 59 | mod2 %>% fit(epochs=2L, verbose = FALSE, view_metrics = FALSE) 60 | mean2 <- mod2 %>% fitted() 61 | 62 | # after training 63 | expect_equal(coef(mod1), coef(mod2)) 64 | expect_equal(mean1, mean2) 65 | }) 66 | -------------------------------------------------------------------------------- /tests/testthat/test_special_processing_torch.R: -------------------------------------------------------------------------------- 1 | context("Processors Torch") 2 | 3 | test_that("lin_processor", { 4 | 5 | data = data.frame(a=rnorm(2), b=rnorm(2), c=rnorm(2)) 6 | term="lin(a + b + c)" 7 | expect_equal(lin_processor(term, data, 1, 1, engine = "torch", 8 | controls = list(with_layer = TRUE))$input_dim, 3) 9 | term="lin(1 + b + c)" 10 | expect_equal(lin_processor(term, data, 1, 1, engine = "torch", 11 | controls = list(with_layer = TRUE))$input_dim, 2) 12 | # -> 2 because intercepts must be added explicitly to the formula 13 | term="lin(a, b, c)" 14 | expect_equal(lin_processor(term, data, 1, 1, engine = "torch", 15 | controls = list(with_layer = TRUE))$input_dim, 3) 16 | term="lin(1, b, c)" # intercept is treated separately 17 | expect_equal(lin_processor(term, data, 1, 1, engine = "torch", 18 | controls = list(with_layer = TRUE))$input_dim, 2) 19 | 20 | }) 21 | 22 | test_that("process_terms", { 23 | 24 | form = ~ 1 + d(x) + s(x) + lasso(z) + ridge(z) + te(y, df = 5) %OZ% (y + s(x)) + d(z) %OZ% s(x) + u 25 | data = data.frame(x = rnorm(100), y = rnorm(100), z = rnorm(100), u = rnorm(100)) 26 | controls = penalty_control() 27 | controls$with_layer <- TRUE 28 | output_dim = 1L 29 | param_nr = 1L 30 | d = dnn_placeholder_processor(function(x) layer_dense(x, units=1L)) 31 | specials = c("s", "te", "ti", "lasso", "ridge", "offset") 32 | specials_to_oz = c("d") 33 | controls$gamdata <- precalc_gam(list(form), data, controls) 34 | 35 | res1 <- suppressWarnings( 36 | process_terms(form = form, 37 | d = dnn_placeholder_processor(function(x) layer_dense(x, units=1L)), 38 | specials_to_oz = specials_to_oz, 39 | data = data, 40 | output_dim = output_dim, 41 | automatic_oz_check = TRUE, 42 | param_nr = 1, 43 | controls = controls, 44 | parsing_options = form_control(), engine = "torch") 45 | 46 | ) 47 | 48 | expect_is(res1, "list") 49 | expect_equal(length(res1), 9) 50 | expect_equal(sapply(res1, "[[", "nr"), 1:9) 51 | expect_type(sapply(res1, "[[", "input_dim"), "integer") 52 | 53 | }) 54 | 55 | test_that("fixed weights", { 56 | 57 | form = ~ 1 + u + s(x) 58 | data = data.frame(x = rnorm(100), y = rnorm(100), z = rnorm(100), u = rnorm(100)) 59 | controls = penalty_control() 60 | controls$with_layer <- TRUE 61 | controls$weight_options$warmstarts <- list("u" = 1.337) 62 | output_dim = 1L 63 | param_nr = 1L 64 | d = dnn_placeholder_processor(function(x) layer_dense(x, units=1L)) 65 | specials = c("s", "te", "ti", "lasso", "ridge", "offset", "rwt") 66 | specials_to_oz = c("d") 67 | controls$gamdata <- precalc_gam(list(form), data, controls) 68 | 69 | res1 <- suppressWarnings( 70 | process_terms(form = form, 71 | d = dnn_placeholder_processor(function(x) layer_dense(x, units=1L)), 72 | specials_to_oz = specials_to_oz, 73 | data = data, 74 | output_dim = output_dim, 75 | automatic_oz_check = TRUE, 76 | param_nr = 1, 77 | controls = controls, 78 | parsing_options = form_control(), engine = "torch") 79 | 80 | ) 81 | 82 | expect_is(res1, "list") 83 | expect_equal(length(res1), 3) 84 | expect_equal(sapply(res1, "[[", "nr"), 1:3) 85 | expect_type(sapply(res1, "[[", "input_dim"), "integer") 86 | expect_true( 87 | identical(get("layer_args", environment(res1[[1]]$layer))$kernel_initializer, 88 | "constant")) 89 | 90 | }) 91 | 92 | 93 | test_that("extractlen", { 94 | 95 | expect_equal(extractlen("a + b", data=list(a=rnorm(3), b=rnorm(3))),2) 96 | expect_equal(extractlen("something(a, b)", data=list(a=rnorm(3), b=rnorm(3))),2) 97 | expect_equal(extractlen("a + b + c", data=data.frame(a=rnorm(3), 98 | b=rnorm(3), 99 | c=rnorm(3))),3) 100 | expect_equal(extractlen("s(a + b)", data=list(a=rnorm(3), b=rnorm(3))),2) 101 | 102 | }) 103 | 104 | test_that("extractval", { 105 | 106 | expect_equal(extractval("lasso(x, la=1)", "la"), 1) 107 | expect_equal(extractval("lasso(x, abcd=1000)", "abcd"), 1000) 108 | expect_equal(extractval("lasso(x, y, z, u, abcd=1000)", "abcd"), 1000) 109 | expect_equal(extractval("lasso(x, y=1, z=2, u=3, abcd=1000)", "abcd"), 1000) 110 | expect_equal(extractval("lasso(x + y + z, abcd=1000)", "abcd"), 1000) 111 | 112 | }) 113 | -------------------------------------------------------------------------------- /tests/testthat/test_subnetwork_init.R: -------------------------------------------------------------------------------- 1 | context("Subnetwork Initilization") 2 | 3 | test_that("subnetwork_init", { 4 | 5 | form = ~ 1 + d(x) + s(x) + lasso(z) + ridge(z) + d(w) %OZ% (y + s(x)) + d(z) %OZ% s(x) + u 6 | data = data.frame(x = rnorm(100), y = rnorm(100), 7 | z = rnorm(100), u = rnorm(100), 8 | w = rnorm(100)) 9 | controls = penalty_control() 10 | controls$with_layer <- TRUE 11 | controls$weight_options$warmstarts <- list("s(x)" = c(-4:4)) 12 | controls$weight_options$general <- weight_control()[[1]]$general 13 | output_dim = 1L 14 | param_nr = 1L 15 | d = dnn_placeholder_processor(function(x) x %>% 16 | layer_dense(units=5L) %>% 17 | layer_dense(units=1L)) 18 | specials = c("s", "te", "ti", "vc", "lasso", "ridge", "offset", "vi", "fm", "vfm") 19 | specials_to_oz = c("d") 20 | controls$gamdata <- precalc_gam(list(form), data, controls) 21 | 22 | pp <- suppressWarnings( 23 | process_terms(form = form, 24 | d = d, 25 | specials_to_oz = specials_to_oz, 26 | data = data, 27 | output_dim = output_dim, 28 | automatic_oz_check = TRUE, 29 | param_nr = 1, 30 | controls = controls, 31 | parsing_options = form_control(), engine = "tf") 32 | ) 33 | 34 | gaminputs <- gaminputs <- makeInputs(controls$gamdata$data_trafos, "gam_inp") 35 | res <- suppressWarnings(subnetwork_init(list(pp), gaminputs = gaminputs)) 36 | expect_true(all(sapply(res[[1]], function(x) "python.builtin.object" %in% class(x)))) 37 | expect_true("python.builtin.object" %in% class(res[[2]])) 38 | # does not work -- depending on the platform and tf version: 39 | # expect_equal(c(unlist(sapply(res[[1]], function(x) x$shape[2]))), 40 | # c(1, 9, rep(1, 7))) 41 | 42 | }) 43 | 44 | test_that("shared layer within formula", { 45 | 46 | form = ~ 1 + s(x) + lasso(z) + s(z) + u 47 | data = data.frame(x = rnorm(100), y = rnorm(100), 48 | z = rnorm(100), u = rnorm(100), 49 | w = rnorm(100)) 50 | controls = penalty_control() 51 | controls$with_layer <- TRUE 52 | controls$weight_options$warmstarts <- list("s(x)" = c(-4:4)) 53 | controls$weight_options$general <- weight_control()[[1]]$general 54 | controls$weight_options$shared_layers <- list(list("s(x)", "s(z)")) 55 | output_dim = 1L 56 | param_nr = 1L 57 | d = dnn_placeholder_processor(function(x) x %>% 58 | layer_dense(units=5L) %>% 59 | layer_dense(units=1L)) 60 | specials = c("s", "te", "ti", "vc", "lasso", "ridge", "offset", "vi", "fm", "vfm") 61 | specials_to_oz = c("d") 62 | controls$gamdata <- precalc_gam(list(form), data, controls) 63 | 64 | pp <- suppressWarnings( 65 | process_terms(form = form, 66 | d = d, 67 | specials_to_oz = specials_to_oz, 68 | data = data, 69 | output_dim = output_dim, 70 | automatic_oz_check = TRUE, 71 | param_nr = 1, 72 | controls = controls, 73 | parsing_options = form_control()) 74 | ) 75 | 76 | gaminputs <- gaminputs <- makeInputs(controls$gamdata$data_trafos, "gam_inp") 77 | res <- suppressWarnings(subnetwork_init(list(pp), gaminputs = gaminputs)) 78 | expect_is(res, class = "list") 79 | 80 | }) 81 | 82 | 83 | test_that("helpers subnetwork_init", { 84 | 85 | a <- tf$keras$Input(list(3L)) 86 | b <- tf$keras$Input(list(3L)) 87 | c <- tf$keras$Input(list(1L)) 88 | d <- tf$keras$Input(list(1L)) 89 | e <- tf$keras$Input(list(1L)) 90 | 91 | # ktclass <- "tf.keras.KerasTensor" 92 | expect_dim <- function(kt, dim){ 93 | expect_equal(kt$shape[[2]], dim) 94 | } 95 | 96 | # layer_add_identity 97 | expect_error(layer_add_identity(a)) 98 | # expect_is(layer_add_identity(list(a)), ktclass) 99 | # expect_is(layer_add_identity(list(c,d,e)), ktclass) 100 | expect_dim(layer_add_identity(list(a)), 3) 101 | expect_dim(layer_add_identity(list(a,b)), 3) 102 | expect_dim(layer_add_identity(list(c,d,e)), 1) 103 | 104 | # layer_concatenate_identity 105 | expect_error(layer_concatenate_identity(a)) 106 | # expect_is(layer_concatenate_identity(list(a)), ktclass) 107 | # expect_is(layer_concatenate_identity(list(c,d,e)), ktclass) 108 | expect_dim(layer_concatenate_identity(list(a)), 3) 109 | expect_dim(layer_concatenate_identity(list(a,b,c)), 7) 110 | 111 | }) 112 | -------------------------------------------------------------------------------- /tests/testthat/test_subnetwork_init_torch.R: -------------------------------------------------------------------------------- 1 | context("Subnetwork Initilization") 2 | 3 | test_that("subnetwork_init", { 4 | 5 | form = ~ 1 + d(x) + ridge(z) + d(w) + u 6 | data = data.frame(x = rnorm(100), y = rnorm(100), 7 | z = rnorm(100), u = rnorm(100), 8 | w = rnorm(100)) 9 | controls = penalty_control() 10 | controls$with_layer <- TRUE 11 | controls$weight_options$warmstarts <- list("s(x)" = c(-4:4)) 12 | controls$weight_options$general <- weight_control()[[1]]$general 13 | output_dim = 1L 14 | param_nr = 1L 15 | d = dnn_placeholder_processor(function() nn_sequential( 16 | nn_linear(in_features = 1, 17 | out_features = 5), 18 | nn_linear(in_features = 5, 19 | out_features = 1) 20 | ) 21 | ) 22 | specials = c("s", "te", "ti", "vc", "lasso", "ridge", "offset", "vi", "fm", "vfm") 23 | specials_to_oz = c("d") 24 | controls$gamdata <- precalc_gam(list(form), data, controls) 25 | 26 | pp <- suppressWarnings( 27 | process_terms(form = form, 28 | d = d, 29 | specials_to_oz = specials_to_oz, 30 | data = data, 31 | output_dim = output_dim, 32 | automatic_oz_check = TRUE, 33 | param_nr = 1, 34 | controls = controls, 35 | parsing_options = form_control(), engine = "torch") 36 | ) 37 | 38 | res <- subnetwork_init_torch(list(pp)) 39 | expect_true("nn_module" %in% class(res())) 40 | # does not work -- depending on the platform and tf version: 41 | # expect_equal(c(unlist(sapply(res[[1]], function(x) x$shape[2]))), 42 | # c(1, 9, rep(1, 7))) 43 | 44 | }) 45 | 46 | -------------------------------------------------------------------------------- /tests/testthat/test_unstructured.R: -------------------------------------------------------------------------------- 1 | context("Unstructured Data") 2 | 3 | test_that("array inputs", { 4 | mnist <- dataset_mnist() 5 | 6 | train_X <- list(x=array(mnist$train$x, 7 | # so that we can use 2d conv later 8 | c(dim(mnist$train$x),1)) 9 | ) 10 | subset <- 1:200 11 | train_X[[1]]<- train_X[[1]][subset,,,,drop=FALSE] 12 | train_y <- to_categorical(mnist$train$y[subset]) 13 | 14 | conv_mod <- function(x) x %>% 15 | layer_conv_2d(filters = 16, kernel_size = c(3,3), 16 | activation= "relu", 17 | input_shape = shape(NULL, NULL, 1)) %>% 18 | layer_global_average_pooling_2d() %>% 19 | layer_dense(units = 10) 20 | 21 | simple_mod <- function(x) x %>% 22 | layer_dense(units = 4, activation = "relu") %>% 23 | layer_dense(units = 1, activation = "linear") 24 | 25 | z <- rnorm(length(subset)) 26 | fac <- gl(4, length(subset)/4) 27 | m <- runif(length(z)) 28 | 29 | list_as_input <- append(train_X, (data.frame(z=z, fac=fac, m=m))) 30 | 31 | mod <- deepregression(y = train_y, list_of_formulas = 32 | list(logit = ~ 1 + simple_mod(z) + fac + conv_mod(x)), 33 | data = list_as_input, 34 | list_of_deep_models = list(simple_mod = simple_mod, 35 | conv_mod = conv_mod), 36 | family = "multinoulli") 37 | 38 | cvres <- mod %>% cv(epochs = 2, cv_folds = 2, batch_size=100, plot = F) 39 | 40 | expect_is(cvres, "drCV") 41 | lapply(cvres, function(x) { 42 | expect_true(is.numeric(x$metrics$loss)) 43 | expect_true(is.numeric(x$metrics$val_loss)) 44 | expect_true(!any(is.nan(x$metrics$loss))) 45 | }) 46 | 47 | expect_equal(dim(coef(mod)[[1]]), c(3, 10)) 48 | mod %>% fit(epochs = 2, 49 | batch_size=100, 50 | view_metrics=FALSE, 51 | validation_split = NULL) 52 | expect_is(mod, "deepregression") 53 | expect_true(!any(is.nan(unlist(coef(mod))))) 54 | }) 55 | 56 | context("Deep Specification") 57 | 58 | test_that("deep specification", { 59 | set.seed(24) 60 | n <- 200 61 | b0 <- 1 62 | x <- runif(n) %>% as.matrix() 63 | z <- runif(n) 64 | fac <- gl(10, n/10) 65 | true_mean_fun <- function(xx) sin(10*xx) + b0 66 | # training data 67 | y <- true_mean_fun(x) + rnorm(n = n, mean = 0, sd = 2) 68 | k <- rnorm(length(x)) 69 | data = data.frame(x = x, fac = fac, z = z) 70 | data$k <- k 71 | 72 | deep_model <- function(x) x %>% 73 | layer_dense(units = 4, activation = "relu") %>% 74 | layer_dense(units = 1, activation = "linear") 75 | 76 | another_deep_model <- function(x) x %>% 77 | layer_dense(units = 4, activation = "relu") %>% 78 | layer_dense(units = 1, activation = "linear") 79 | 80 | third_model <- function(x) x %>% 81 | layer_dense(units = 4, activation = "relu") %>% 82 | layer_dense(units = 1, activation = "linear") 83 | 84 | # works across different fomulae specifications 85 | formulae <- c( 86 | "~ d(x,z) + k", 87 | "~ d(x,z,k)", 88 | "~ d(x) + d(z)", 89 | "~ deep_model(x) + another_deep_model(z)", 90 | "~ deep_model(x,z) + another_deep_model(k)", 91 | "~ deep_model(x) + another_deep_model(z) + third_model(k)" 92 | ) 93 | 94 | list_models <- list(deep_model = deep_model, 95 | another_deep_model = another_deep_model, 96 | third_model = third_model) 97 | list_models_wo_name <- list(deep_model, another_deep_model) 98 | use <- list(1,1,1:2,1:2,1:2,1:3) 99 | 100 | for (i in seq_len(length(formulae))) { 101 | form <- formulae[i] 102 | usei <- use[[i]] 103 | this_list <- list_models[usei] 104 | if (i %in% 1:3) { 105 | use_list <- list_models_wo_name[use[[i]]] 106 | if(i==3) use_list <- use_list[1] 107 | } else { 108 | use_list <- list_models[use[[i]]] 109 | } 110 | suppressWarnings( 111 | mod <- deepregression( 112 | y = y, 113 | data = data, 114 | # define how parameters should be modeled 115 | list_of_formulas = list(loc = as.formula(form), scale = ~1), 116 | list_of_deep_models = use_list 117 | ) 118 | ) 119 | 120 | suppressWarnings( 121 | res <- mod %>% fit(epochs=2, verbose = FALSE, view_metrics = FALSE) 122 | ) 123 | expect_is(mod, "deepregression") 124 | expect_true(!any(is.nan(unlist(coef(mod))))) 125 | expect_true(!any(is.nan(fitted(mod)))) 126 | 127 | suppressWarnings(res <- mod %>% predict(data)) 128 | expect_true(is.numeric(res)) 129 | expect_true(!any(is.nan(res))) 130 | } 131 | }) 132 | -------------------------------------------------------------------------------- /tests/testthat/test_unstructured_torch.R: -------------------------------------------------------------------------------- 1 | context("Unstructured Data") 2 | 3 | test_that("array inputs", { 4 | mnist <- dataset_mnist() 5 | 6 | train_X <- list(x=array(mnist$train$x, 7 | # so that we can use 2d conv later 8 | c(dim(mnist$train$x),1)) 9 | ) 10 | subset <- 1:200 11 | train_X[[1]]<- train_X[[1]][subset,,,,drop=FALSE] 12 | train_y <- to_categorical(mnist$train$y[subset]) 13 | 14 | conv_mod <- function(x) x %>% 15 | layer_conv_2d(filters = 16, kernel_size = c(3,3), 16 | activation= "relu", 17 | input_shape = shape(NULL, NULL, 1)) %>% 18 | layer_global_average_pooling_2d() %>% 19 | layer_dense(units = 10) 20 | 21 | simple_mod <- function(x) x %>% 22 | layer_dense(units = 4, activation = "relu") %>% 23 | layer_dense(units = 1, activation = "linear") 24 | 25 | z <- rnorm(length(subset)) 26 | fac <- gl(4, length(subset)/4) 27 | m <- runif(length(z)) 28 | 29 | list_as_input <- append(train_X, (data.frame(z=z, fac=fac, m=m))) 30 | 31 | mod <- deepregression(y = train_y, list_of_formulas = 32 | list(logit = ~ 1 + simple_mod(z) + fac + conv_mod(x)), 33 | data = list_as_input, 34 | list_of_deep_models = list(simple_mod = simple_mod, 35 | conv_mod = conv_mod), 36 | family = "multinoulli") 37 | 38 | cvres <- mod %>% cv(epochs = 2, cv_folds = 2, batch_size=100, plot = F) 39 | 40 | expect_is(cvres, "drCV") 41 | lapply(cvres, function(x) { 42 | expect_true(is.numeric(x$metrics$loss)) 43 | expect_true(is.numeric(x$metrics$val_loss)) 44 | expect_true(!any(is.nan(x$metrics$loss))) 45 | }) 46 | 47 | expect_equal(dim(coef(mod)[[1]]), c(3, 10)) 48 | mod %>% fit(epochs = 2, 49 | batch_size=100, 50 | view_metrics=FALSE, 51 | validation_split = NULL) 52 | expect_is(mod, "deepregression") 53 | expect_true(!any(is.nan(unlist(coef(mod))))) 54 | }) 55 | 56 | context("Deep Specification") 57 | 58 | test_that("deep specification", { 59 | set.seed(24) 60 | n <- 200 61 | b0 <- 1 62 | x <- runif(n) %>% as.matrix() 63 | z <- runif(n) 64 | fac <- gl(10, n/10) 65 | true_mean_fun <- function(xx) sin(10*xx) + b0 66 | # training data 67 | y <- true_mean_fun(x) + rnorm(n = n, mean = 0, sd = 2) 68 | k <- rnorm(length(x)) 69 | data = data.frame(x = x, fac = fac, z = z) 70 | data$k <- k 71 | 72 | deep_model <- function(x) x %>% 73 | layer_dense(units = 4, activation = "relu") %>% 74 | layer_dense(units = 1, activation = "linear") 75 | 76 | another_deep_model <- function(x) x %>% 77 | layer_dense(units = 4, activation = "relu") %>% 78 | layer_dense(units = 1, activation = "linear") 79 | 80 | third_model <- function(x) x %>% 81 | layer_dense(units = 4, activation = "relu") %>% 82 | layer_dense(units = 1, activation = "linear") 83 | 84 | # works across different fomulae specifications 85 | formulae <- c( 86 | "~ d(x,z) + k", 87 | "~ d(x,z,k)", 88 | "~ d(x) + d(z)", 89 | "~ deep_model(x) + another_deep_model(z)", 90 | "~ deep_model(x,z) + another_deep_model(k)", 91 | "~ deep_model(x) + another_deep_model(z) + third_model(k)" 92 | ) 93 | 94 | list_models <- list(deep_model = deep_model, 95 | another_deep_model = another_deep_model, 96 | third_model = third_model) 97 | list_models_wo_name <- list(deep_model, another_deep_model) 98 | use <- list(1,1,1:2,1:2,1:2,1:3) 99 | 100 | for (i in seq_len(length(formulae))) { 101 | form <- formulae[i] 102 | usei <- use[[i]] 103 | this_list <- list_models[usei] 104 | if (i %in% 1:3) { 105 | use_list <- list_models_wo_name[use[[i]]] 106 | if(i==3) use_list <- use_list[1] 107 | } else { 108 | use_list <- list_models[use[[i]]] 109 | } 110 | suppressWarnings( 111 | mod <- deepregression( 112 | y = y, 113 | data = data, 114 | # define how parameters should be modeled 115 | list_of_formulas = list(loc = as.formula(form), scale = ~1), 116 | list_of_deep_models = use_list 117 | ) 118 | ) 119 | 120 | suppressWarnings( 121 | res <- mod %>% fit(epochs=2, verbose = FALSE, view_metrics = FALSE) 122 | ) 123 | expect_is(mod, "deepregression") 124 | expect_true(!any(is.nan(unlist(coef(mod))))) 125 | expect_true(!any(is.nan(fitted(mod)))) 126 | 127 | suppressWarnings(res <- mod %>% predict(data)) 128 | expect_true(is.numeric(res)) 129 | expect_true(!any(is.nan(res))) 130 | } 131 | }) 132 | --------------------------------------------------------------------------------