class: center, middle, inverse, title-slide # TMB Basics ## TMB Training Session I ### Andrea Havron
NOAA Fisheries, OST --- layout: true .footnote[U.S. Department of Commerce | National Oceanic and Atmospheric Administration | National Marine Fisheries Service] <style type="text/css"> code.cpp{ font-size: 14px; } code.r{ font-size: 14px; } </style> <!-- modified from Cole Monnahan's TMB training series: https://github.com/colemonnahan/tmb_workshop--> --- # ML with TMB: <br><br> 1. Write C++ model to specify the negative log-likelihood for a set of parameters and data 2. Compile the model and link to R 3. Construct the computational graph (tape) 3. Pass the following to a R minimizer: * objective function: specified by user in C++ * initial parameters and data: specified by user in R * gradient functions: calculated by TMB based on objective function 4. At each step of minimization: * Parameter values are updated * The negative log-likelihood is calculated * The gradient functions return the gradients (vector of 1st derivatives) based on the new parameter values 5. Model convergence is reached when: * The gradients are near zero * The negative log-likelihood is at a minimum --- # TMB Model .pull-left[ linReg.cpp ```cpp // Simple linear regression #include <TMB.hpp> template <class Type> Type objective_function<Type>::operator()() { DATA_VECTOR(y); DATA_MATRIX(X); PARAMETER_VECTOR(beta); PARAMETER(lnSigma); Type nll = 0; Type sigma = exp(lnSigma); int n = y.size(); vector<Type> mu = X * beta; for(int i=0; i<n; i++){ nll -= dnorm(y(i), mu(i), sigma, true); } Type sig2 = pow(sigma,2); REPORT(sig2); ADREPORT(sig2); return nll; } ``` ] .pull-right[ **C++ preliminaries** * Lines end in semi-colons * Everything must be declared * Type is generic and assigned based on input * Indexing starts at 0! * x -= 1: x = x-1 * Math operators similar to R (+,-,/,*) * Use pow(x,p) for x^p * if statements cannot be based on a parameter ] --- # Data: Importing data from R<br><br> * Pass data to TMB with these 'macros' * Note: do not specify the object dimension <br><br> |TMB Syntax |C++ Type |R Type | |:---------------|:----------------------|:----------| |DATA_VECTOR(x) |tmbutils::vector<Type> |vector | |DATA_MATRIX(x) |tmbutils::matrix<Type> |matrix | |DATA_SCALAR(x) |Type |numeric(1) | |DATA_INTEGER(x) |int |integer(1) | |DATA_FACTOR(x) |Eigen::vector<int> |factor | |DATA_ARRAY(x) |tmbutils::array<Type> |array | --- # Data: Importing data from R<br><br> .pull-left-narrow[ TMB code ```cpp DATA_VECTOR(y); DATA_MATRIX(X); DATA_INTEGER(i); DATA_FACTOR(ngroup); ``` ] .pull-right-wide[ R script ```r Data <- list( y = c(30.2, 45.3, 12.1), X = matrix(0,3,3), i = 11, ngroup = c(1,1,2,2,2) ) str(Data) ``` ``` ## List of 4 ## $ y : num [1:3] 30.2 45.3 12.1 ## $ X : num [1:3, 1:3] 0 0 0 0 0 0 0 0 0 ## $ i : num 11 ## $ ngroup: num [1:5] 1 1 2 2 2 ``` ] --- # Declaring model parameters<br><br> * No PARAMETER_INTEGER * Again, do not specify the object dimension <br><br> |TMB Syntax |C++ Type |R Type | |:-------------------|:----------------------|:----------| |PARAMETER_VECTOR(x) |tmbutils::vector<Type> |vector | |PARAMETER_MATRIX(x) |tmbutils::matrix<Type> |matrix | |PARAMETER_ARRAY(x) |tmbutils::array<Type> |array | |PARAMETER(x) |Type |numeric(1) | --- # Declaring model parameters<br><br> .pull-left-narrow[ TMB code ```cpp PARAMETER_VECTOR(beta); PARAMETER(ln_sigma); PARAMETER_MATRIX(u); ``` ] .pull-right-wide[ R script ```r Pars <- list( beta = c(0,0), lnSigma = 0, u = matrix(0,3,3) ) str(Pars) ``` ``` ## List of 3 ## $ beta : num [1:2] 0 0 ## $ lnSigma: num 0 ## $ u : num [1:3, 1:3] 0 0 0 0 0 0 0 0 0 ``` ]