Skip to content

Commit

Permalink
Changed to support TensorFlow Probability
Browse files Browse the repository at this point in the history
  • Loading branch information
Jack Baker committed Sep 12, 2018
1 parent fd274fc commit 2f8ee97
Show file tree
Hide file tree
Showing 37 changed files with 288 additions and 80 deletions.
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Package: sgmcmc
Type: Package
Title: Stochastic Gradient Markov Chain Monte Carlo
Version: 0.2.2
Version: 0.2.3
Authors@R: c(
person("Jack", "Baker", email = "[email protected]", role = c("aut", "cre", "cph")),
person( "Christopher", "Nemeth", role = c("aut", "cph") ),
Expand Down
9 changes: 3 additions & 6 deletions R/setup.R
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# Create generic sgmcmc object
createSGMCMC = function( logLik, logPrior, dataset, params, stepsize, minibatchSize, seed ) {
# First check tf installation using tf_status. Throw error if it isn't installed.
checkTFInstall()
# Set seed if required, TensorFlow seeds set inside dynamics
if ( !is.null( seed ) ) {
tf$set_random_seed(seed)
Expand All @@ -16,7 +18,7 @@ createSGMCMC = function( logLik, logPrior, dataset, params, stepsize, minibatchS
# Check for tf$float64 errors (we only use tf$float32), if so throw a more explanatory error
estLogPost = tryCatch({
setupEstLogPost( logLik, logPrior, paramstf, placeholders, N, minibatchSize )
}, error = function ( e ) throwFloat64Error( e ) )
}, error = function ( e ) getPosteriorBuildError( e ) )
# Check stepsize tuning constants are in list format
stepsize = convertList( stepsize, params )
# Declare sgmcmc object as list, return for custom tuning constants to be added by calling method
Expand Down Expand Up @@ -166,8 +168,3 @@ convertList = function( tuningConst, params ) {
}
return( convertedConsts )
}

# If tf$float64 error encountered, provide a more useful message
throwFloat64Error = function( e ) {
stop(paste0("Problem building log posterior estimate from supplied logLik and logPrior functions. This is usually due to one of two things: a problem with the TensorFlow code used to declare logLik or logPrior functions; or that some constants declared in this function are read as type tf$float64. Maybe try to specify all constants as tf$float32. Full TensorFlow output below should make it clear if the issue is a float64 issue, or just a generic TensorFlow code issue.\n\n", e))
}
38 changes: 38 additions & 0 deletions R/tfErrors.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Check tensorflow is installed. If it isn't throw an error.
checkTFInstall <- function() {
if ( !get("TF", envir = tf_status) ) {
stop(tfErrorMsg(), call. = FALSE)
} else if ( !get("TFP", envir = tf_status) ) {
stop(tfpErrorMsg(), call. = FALSE)
}
}

# If there is an error building the posterior print a hopefully more readable error message
getPosteriorBuildError <- function(e) {
stop(buildErrorMsg(e), call. = FALSE)
}


tfErrorMsg <- function() {
msg <- "\nNo TensorFlow python installation found.\n"
msg <- paste0(msg, "This can be installed using the installTF() function.\n")
return(msg)
}


tfpErrorMsg <- function() {
msg <- "\nNo TensorFlow Probability python installation found.\n"
msg <- paste0(msg, "This can be installed using the installTF() function.\n")
return(msg)
}


buildErrorMsg = function(e) {
msg <- "Problem building log posterior estimate from supplied logLik and logPrior functions.\n\n"
msg <- paste0(msg, "Python error output:\n", e)
msg <- paste0(msg, "\n",
"Check your tensorflow code specifying the logLik and logPrior functions is correct.\n")
msg <- paste0(msg, "Ensure constants in logLik and logPrior functions are specified as ",
"type float32 using \ntf$constant(.., dtype = tf$float32) -- see the tutorials for some examples.")
return(msg)
}
71 changes: 36 additions & 35 deletions R/zzz.R
Original file line number Diff line number Diff line change
@@ -1,51 +1,52 @@
# Environment determining status of the TensorFlow Installation.
# This allows a custom error message to be displayed.
tf_status <- new.env()


# Load TensorFlow Probability and add the contents to tf$distributions.
.onLoad <- function(libname, pkgname) {
# Check TensorFlow is installed and load tensorflow_probability
# If either are not installed display a custom install message
# Set tf$distributions to be tfp$distributions
tryCatch(tfp <- loadTF(),
error = function(e) {
tfMissing()
}
)

# Set default tf_status that everything is installed correctly.
assign("TF", TRUE, envir = tf_status)
assign("TFP", TRUE, envir = tf_status)
# Check TensorFlow is installed. Update tf_status accordingly.
checkTF()
# If checkTF was not successful, return to avoid printing multiple messages
if (!get("TF", envir = tf_status)) {
return()
}
# Check TensorFlow Probability is installed, and load in. Update tf_status accordingly.
tryCatch(loadTFP(), error = function(e) tfpMissing(e))
}


# Build message if TensorFlow Probability missing
tfMissing <- function() {
message("\nNo TensorFlow or TensorFlow Probability python installation found.")
message("This can be installed using the installTF() function.\n")
# Set custom error message incase user still tries to use tf
assign("on_error", function (e) error_fn(e), env = tf)
# Check tensorflow installed by doing a dummy operation that will throw an error
checkTF = function() {
tryCatch(temp <- tf$constant(4),
error = function (e) tfMissing())
}


# Check TensorFlow installed and load TensorFlow probability
loadTF = function() {
# Check tensorflow installed by doing a dummy operation that will throw an error
temp <- tf$constant(4)

# Delay load tensorflow_probability as tfp using reticulate package.
tfp <- reticulate::import("tensorflow_probability", delay_load = list(
priority = 5,
environment = "r-tensorflow"
))

# Set tfp$distributions to be tf$distributions
# Load tensorflow probability and assign distns to tf$distributions.
# If this fails, print message and update tf_status
loadTFP <- function() {
import_opts <- list(priority = 5, environment = "r-tensorflow")
tfp <- reticulate::import("tensorflow_probability", delay_load = import_opts)
tf$distributions <- tfp$distributions
}


error_fn = function(e) {
stop(tfErrorMsg(), call. = FALSE)
# Build message if TensorFlow missing. Update tf_status
tfMissing <- function() {
message("\nNo TensorFlow python installation found.")
message("This can be installed using the installTF() function.\n")
assign("TF", FALSE, envir = tf_status)
assign("TFP", FALSE, envir = tf_status)
}


# Build error message for TensorFlow configuration errors
tfErrorMsg <- function() {
message <- "Installation of TensorFlow or TensorFlow Probability not found.\n"
message <- paste0(message,
"These can be installed by running the installTF() function.")
return(message)
# Build message if TensorFlow Probability missing. Update tf_status
tfpMissing <- function(e) {
message("\nNo TensorFlow Probability python installation found.")
message("This can be installed using the installTF() function.\n")
assign("TFP", FALSE, envir = tf_status)
}
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,16 @@

`sgmcmc` implements popular stochastic gradient Markov chain Monte Carlo (SGMCMC) methods including [stochastic gradient Langevin dynamics (SGLD)](http://people.ee.duke.edu/~lcarin/398_icmlpaper.pdf), [stochastic gradient Hamiltonian Monte Carlo (SGHMC)](https://arxiv.org/pdf/1402.4102v2.pdf) and [stochastic gradient Nos&eacute;-Hoover thermostat (SGNHT)](http://papers.nips.cc/paper/5592-bayesian-sampling-using-stochastic-gradient-thermostats.pdf). The package uses automatic differentiation, so all the differentiation needed for the methods is calculated automatically. Control variate methods can be used in order to improve the efficiency of the methods as proposed in the [recent publication](https://arxiv.org/pdf/1706.05439.pdf).

The package is built on top of the [TensorFlow library for R](https://tensorflow.rstudio.com/), which has a lot of support for statistical distributions and operations, which allows a large class of posteriors to be built. For more details can be found at the [TensorFlow R library webpage](https://tensorflow.rstudio.com/), also see the [TensorFlow API](https://www.tensorflow.org/api_docs/) for full documentation.
The package is built on top of the [TensorFlow library for R](https://tensorflow.rstudio.com/), which has a lot of support for statistical distributions and operations, which allows a large class of posteriors to be built. More details can be found at the [TensorFlow R library webpage](https://tensorflow.rstudio.com/), also see the [TensorFlow API](https://www.tensorflow.org/api_docs/) for full documentation.

## Installation

`sgmcmc` requires [TensorFlow for R](https://github.com/rstudio/tensorflow) to be installed, which requires packages that can't be automatically built by `R`, so has a few steps:
- Install [TensorFlow for R](https://github.com/rstudio/tensorflow), first run `install.packages("tensorflow")`, then after run `tensorflow::install_tensorflow()`.
- Now run `install.packages("sgmcmc")`.
- Install [TensorFlow for R](https://github.com/rstudio/tensorflow), run `install.packages("tensorflow")`.
- Install the `sgmcmc` R package: `install.packages("sgmcmc")`.
- Install the required python packages (including TensorFlow and TensorFlow Probability) by running: `sgmcmc::installTF()`.

The TensorFlow API changes a lot, so it's best to make sure your TensorFlow for python installation is up to date.
If you already have the TensorFlow and TensorFlow probability packages installed, then this should be autodetected by the package and you can skip the final step. Make sure these are up to date though, as the TensorFlow API is under active development and still changes quite regularly.

## Documentation

Expand Down
4 changes: 4 additions & 0 deletions _pkgdown.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,10 @@ reference:
- initSess
- sgmcmcStep
- getParams
- title: "Installation"
desc: "Install python packages depended on by sgmcmc, TensorFlow and TensorFlow Probability."
contents:
- installTF
- title: "Datasets"
desc: "Download and load datasets used in the examples and vignettes"
contents:
Expand Down
2 changes: 1 addition & 1 deletion docs/articles/gaussMixture.html

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion docs/articles/index.html

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion docs/articles/logisticRegression.html

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 2f8ee97

Please sign in to comment.