{'fraction_non_alphanumeric': 0.02716365009732431, 'fraction_numerical': 0.006507655210481973, 'mean_word_length': 4.7638981915606164, 'pattern_counts': {'":': 0, '<': 0, '<?xml version=': 0, '>': 0, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 5, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
TensorBNN: Bayesian Inference for Neural Networks using Tensorflow

TensorBNN is a new package based on TensorFlow that implements Bayesian inference for modern neural network models. The posterior density of neural network model parameters is represented as a point cloud sampled using Hamiltonian Monte Carlo. The TensorBNN package leverages TensorFlow's architecture and training features as well as its ability to use modern graphics processing units (GPU) in both the training and prediction stages.


Introduction
TensorBNN is a flexible implementation of Bayesian neural networks (BNNs) built with TensorFlow [1] and TensorFlow-Probability (TFP) [2], a popular machine learning platform with efficient co-processor computations. This implementation takes a Monte Carlo approach to make Bayesian predictions, in contrast to many current gradient descent-based approaches.
The Flexible Bayesian Modeling (FBM) toolkit, developed by Radford Neal [3,4], provides extensive capabilities for Bayesian inference for neural networks. However, machine learning technologies have evolved significantly since the first release of FBM. Robust, flexible machine learning platforms such as Google's TensorFlow [1] and Facebook's PyTorch [5] contain functionality in architecture design and optimization methods that are unmatched in frameworks with smaller user and development support. In addition, these packages provide a seamless interface with highly-parallel co-processors such as Graphics Processing Units (GPUs) and Tensor Processing Units (TPUs), enabling large-scale computations, often with orders of magnitude speedup over CPU-only software. The TensorBNN package leverages these recent developments in order to provide an environment for Bayesian inference using the methods proposed by Neal [3].
Implementations of approximate BNNs, which train efficiently on coprocessors, such as the DenseFlipout layers in TFP based on [6], have recently appeared. These DenseFlipout layers approximate the prior and posterior densities with explicit functional forms, such as a Gaussian density, and optimize the parameters these functional forms using gradient descent. While such methods can be effective and are much less computationally expensive than a full Bayesian analysis, they are limited by the choice of the functional form of the posterior densities and, therefore, are unlikely to be able to capture the full complexity of the posterior density over the parameter space of a neural network.
The TensorBNN package approximates the posterior density of the parameters of a neural network as a point cloud, that is, a neural network model is "trained" not by finding a single neural network that best fits the training data, but rather by creating an ensemble of neural networks by sampling their parameters from the posterior density using a Markov chain Monte Carlo (MCMC) method.
The paper is organized as follows. We begin in Section 2 with a description of the salient mathematical underpinning of BNNs and TensorBNN, in particular. This is followed by a description of the TensorBNN package in Section 3. In Section 4 the performance of TensorBNN is illustrated with a simple example. A summary is given in Section 5.

Mathematical Details
Neural networks are widely used supervised machine learning models in which the training data comprises known inputs and outputs from which regression or classification models can be constructed. The standard approach to training such a model, that is, fitting the model to data, is to minimize a suitable empirical risk function, which in practice is proportional to the average of a loss function. If the average loss is a linear function of the negative log likelihood, − ln p(D | θ) of the data D, then minimizing the average loss is identical to estimation of the neural network parameters θ via maximum likelihood. In this case, fitting a model, that is, a function f (x, θ), to data can be construed as an inference problem. Furthermore, if a prior density π(θ) over the parameter space can be defined, then the inference can be performed using the Bayesian approach [3].
A Bayesian neural network can be represented as follows where is the posterior density over the parameter space Θ of the neural network with parameters θ ∈ Θ. Since each set of parameters θ corresponds to a different neural network, each set of parameters is associated with a different output value y = f (x, θ) for the same input x. Therefore, the posterior density and neural network f (x, θ) together induce a predictive distribution given by The quantity D = {(t k , x k )} denotes the training data, which consists of the targets t k associated with data x k . In practice, the posterior density is approximated by a point cloud {θ i } sampled using a Monte Carlo method and Eq. (3) is approximated by binning the values y = f (x, θ) with θ ∈ {θ i }. A practical advantage of the Monte Carlo sampling approach is that it provides a straightforward method to estimate the uncertainty due to the finite size of the training data in any quantity that depends on the network parameters: one simply computes the quantity for every sampled parameter point which yields an ensemble of estimates.
The Monte Carlo sampling approach makes no assumptions about the form of the posterior density of the neural network parameters, whereas uncertainty quantification using methods such as the DenseFlipout [6] approximate the posterior density using a specific functional form. However, the Bayesian approach requires the specification of a prior, which introduces its own complication. But, since the network parameters are sampled from the posterior density, the sensitivity of inferences to the choice of prior can be assessed by re-weighting the sampled points by the ratio of the new prior to the one with which the sample was generated. Moreover, this flexibility can even be used to optimize the choice of prior.
The current version of TensorBNN is restricted to fully-connected deep neural networks (DNN), The quantities b j and w j -the biases and weights-are matrices of parameters and h j and g are the activation and output functions, respectively; j is the layer number. In Eq. (4), the functions h j and g are applied element-wise to their matrix arguments. TensorBNN maintains many of the standard activation function options available in TensorFlow, shown in Table 1, with the addition of one custom activation function, a modified PReLU [7] function, called SquarePReLU We opted to choose the trainable parameter to be a j rather than a 2 j to ensure that the slope remains positive thereby keeping the activation function oneto-one.
The function f is f (x) = 1/(1 + exp(−x)) for a classifier and x for regression models.
The weights and biases of the network along with any parameters associated with the activation function are the free parameters of the neural network model. In the following subsection, we describe the pertinent details of this implementation, while the second subsection contains relevant information on the hardware used to perform the sampling for the examples described in Section 4.

Name Description
Sigmoid

Likelihood and Prior
Likelihood. The likelihood functions included in the package are modeled as follows: p(D | θ) = k y t k k (1 − y k ) 1−t k for classification models and k N (t k , y k , σ) for regression models, where y k ≡ f (x k , θ) and N (x, µ, σ) is a Gaussian density with mean µ and standard deviation σ. For classifiers, the targets t k are 1 and 0 for true and false identification, while for regression models they are the desired regression values.
Prior. Constructing a prior for a multi-parameter likelihood function is exceedingly challenging and is especially so for functions as complicated as those in Eq. (7). For an excellent and thorough review of this problem we recommend Nalisnick [8]). We sidestep this challenge by proceeding pragmatically and relying instead on ex post facto justification of the choices we make: the choices are justified based on the quality of the results. Moreover, TensorBNN includes a re-weighting mechanism for studying the sensitivity of the results to these choices. Each layer of the DNN contains three kinds of parameter: weights, biases, and the slope parameters of the activation functions. In the FBM toolkit of Neal [3], the prior for each weight and bias is a zero mean Gaussian density, with the precisions, σ −2 , of these densities constrained by gamma hyperpriors. In TensorBNN, there are several options. Specifically, users can choose between using Gaussian or Cauchy priors, and whether to use Gaussian hyper-priors or no hyper-priors. Using the default GaussianDenseLayer, the weights w i of a given layer are assigned the hierarchical prior comprising a product of Gaussian densities with mean and standard deviation parameters, α and β, respectively, constrained by hyper-priors modeled as Gaussian densities. A hierarchical prior of the same form is assigned to the biases of a given layer, but with different mean and standard deviation parameters. The Gaussian density is chosen to constrain the weights and biases within a reasonable range, with the option of effectively increasing the tails through the use of the hyper-priors. Using the Cauchy distributions would create even larger tails that accommodate a larger dynamic range in the magnitude of the parameters, while still enforcing the clustering of weights near zero. The hyper-priors were chosen to be Gaussian as the hyperparameters are not expected to deviate greatly from their nominal values. The prior for the slope parameter of the activation function can be either an exponential density with its rate parameter constrained by an exponential hyper-prior or a Gaussian prior with mean and standard deviation parameters constrained by Gaussian density hyper-priors as follows The slope parameter, m, should remain close to zero. To this end, we choose a exponential density, Eq. (10), when this slope is positive, and a Gaussian density, Eq. (11), when the slope can also be negative.
The overall prior π(θ) is a product of the priors for all weights, biases, and slope parameters, and the associated hyper-priors. For regression models, there is an additional hyper-parameter, the standard deviation of the likelihood function given in Eq. (7). The initial value of this hyper-parameter, which can be optimized during training, should reflect the user's best guess as to the approximate average error in the prediction, though an initial value of 0.1 is reasonable. See Table 2 for a summary of the parameters in the priors.

Sampling the posterior density
Since the high-dimensional integral in Eq. (1) is intractable it is typically approximated using a Monte Carlo method to sample from the posterior density p(θ | D). The Monte Carlo method of choice is Hamiltonian Monte Carlo (HMC) [3,9] in which the posterior density is written as is viewed as a "potential" to which a "kinetic" term T = p 2 /2 is added to form a "Hamiltonian" H = T + V . The dimensionality of the "momentum" p equals that of the parameter space Θ. The HMC sampling algorithm alternates between deterministic traversals of the space Θ governed by a finite difference approximation of Hamilton's equations and random changes of direction. In order to achieve detailed balance and, therefore, ensure asymptotic convergence to the correct posterior density, the deterministic trajectories are computed using a reversible, leapfrog approximation, to Hamilton's equations. The HMC method has two free parameters, the step size along the trajectories and the number of steps to take before executing a random change in direction. The method used to determine these parameters is described in Section 3.5.

Implementation Details
TensorBNN, which is built using the TensorFlow [1] and TensorFlow-Probability [2], follows the design of BNNs described in Neal [3] with some improvements and modifications. Here we summarize the general structure of TensorBNN and the improvements, which include the HMC parameter adaptation scheme and the addition of pre-training.

Model Declaration
TensorBNN provides a framework for the user-friendly construction of BNNs in a manner similar to the Keras [10] interface for building neural networks with TensorFlow. The main object in the package is the network object, which is the base for all operations in the package. The options that can be specified when instantiating this object are the data type, e.g. float32 or float64, the training and validation data, and the normalization scaling for the output. An example network declaration is shown below. After the network object is instantiated, the layers and activation functions are added. Each of these is a variant of the Layer object. For example, a GaussianDenseLayer and a CauchyDenseLayer are included in the package with multiple activation functions, but users can create their own Layer variants and activation functions with custom priors.
The layer objects can be initialized either randomly or with pre-trained weights and biases. When using random initialization, the Gaussian He [11] initialization is used to determine starting values of the weights, and the biases are extracted from the same random distribution. This is done to keep the starting values small, while allowing variation. As discussed in Section 2.2, the priors for the weights and biases are either Gaussian or Cauchy densities, with their parameters constrained by Gaussian hyper-priors (see Eq. (9)). These values, which are summarized in Table 3,cannot be changed within the layer objects, though it is a simple matter to create a new Layer variant.
In the code snippet below, a DenseLayer and an activation function are added to the network. This process would be the same for any layer or activation function with a different object added. Within the package there are eight options for activation functions, which are listed in Table 1. All the activation functions except SquarePReLU are standard. The SquarePReLU was developed specifically for TensorBNN. Both PReLU and SquarePReLU have trainable slope parameters α. They have, however, different priors and hyper-priors, given in Eqs. (10) and (11), with the fixed and initial values of their parameters listed in Table 4. For PReLU, the exponential distribution was chosen to model the prior belief that the slopes should be close to zero. The rates were picked to allow for larger slopes, while still enforcing the belief that smaller slopes are preferred. For SquarePReLU, as we are considering the square root of the slope, which can be positive or negative, the Gaussian prior was chosen because it is continuous at 0 and enforces the prior preference for small slopes. Once again, the priors for these activation functions cannot be changed, but a custom activation function with different priors can be created. When the add method of the network class is called, the layer or activation function is added to a list of layers. Additionally, the weights, biases, and trainable activation functions from the layer along with the hyper-parameters are stored.

Hamiltonian Monte Carlo Initialization
After building the network architecture, the Hamiltonian Monte Carlo (HMC) sampler must be initialized. This is done through a method of the network class. An example usage is presented below. As described in Section 2.3, HMC is a Markov chain Monte Carlo method where sampling is performed by moving through the parameter space in a manner governed by a fictitious potential energy function determined by the posterior density of the neural network parameters. The numerical approximation used is the leapfrog method, in which the number of leapfrog steps together with the step size determine the distance traveled to the next proposed point. Here leapfrog steps refers to the number of steps of the integrator for a single trajectory through the parameter space, leading to the next potential sample point. Naturally, larger step sizes yield longer deterministic trajectories, but they also increase the accumulated error due to the numerical approximation and so lower the acceptance rate. Unfortunately, choosing good values for the number of steps and the step size can be challenging. Therefore, TensorBNN contains an algorithm, called the parameter adapter, to find these parameters automatically.
The adapter searches a discrete space of step sizes and number of leapfrog steps using the algorithm of [12]. This discrete space is determined by a minimum and maximum step size and a minimum and maximum number of steps. In addition, the adapter accepts the number of iterations before a reset is performed. A reset is performed if after this number of iterations no point has been accepted. It is also given the number random pairs of step size and leapfrog steps to try before using the search algorithm from [12]. Finally, it also accepts two constants a and δ, which assume the values 4 and 0.1, respectively as suggested in [12]. An example of the code used to initialize this is shown below.
While the parameter adapter will be able to find a good choice in the region specified, if one exists, some tuning is still needed for ideal parameter values. As discussed in [13], a reasonable criterion for selecting an initial step size and the number of leapfrog steps is to require the total trajectory length, determined by the step size times the number of leapfrog steps, be roughly π/2. Similarly, the number of burn-in steps is a hyper-parameter of the algorithm.
One of the changes from Neal's procedure is the use of HMC to sample the hyper-parameter space instead of Gibbs sampling. This was done because Gibbs sampling requires knowledge of the conditional distribution for each hyper-parameter given that the rest are fixed. While this is possible to calculate for some hyper-priors the package allows these to be changed to custom priors, for which it may not be possible to compute the conditional densities. It was, therefore, simpler to use a second HMC sampler to sample the hyper-parameters since this works for any hyper-prior. The number of steps for the HMC hyper-parameter sampler is kept constant, but the step size is modified using the Dual-Averaging algorithm [14] depending on the acceptance rate of the sample for 80% of the burn-in period. The TensorFlow -Probability HMC implementation is used for the sampling.

Model Parameter Sampling
The model parameters are sampled using the the train method of the network class. The parameters of the train method determine 1) the likelihood function, 2) the metrics to be calculated during training, 3) whether to use the hyper-priors, 4) the number of burn-in epochs, 5) how often to save networks, and 6) the directory in which to store the models. An example is provided below. The prior is determined by the Likelihood object. The priors included in the package are those described in Section 2.2, though any desired likelihood function can be used through a custom Likelihood object. The built-in Gaussian likelihoods used for regression allow specification of the initial value of the standard deviation. If FixedGaussianLikelihood is used the standard deviation will remain constant, but if GaussianLikelihood is used, the standard deviation will be treated like a hyper-parameter.
The metrics to be computed are specified by including a list of all desired Metric objects. The built-in metrics are PercentError, SquaredError, and Accuracy. All three accept the normalization scalars of mean and standard deviation to calculate the metrics for unnormalized data, as well as an option to take the exponential of output values before computing for the metrics, for the case of log-scaled outputs. The PercentError metric is defined as Squared Error is defined as In both cases, the expectation is with respect to the input data, y pred is the predicted value for a given input, and y true is the target. Finally, Accuracy is simply the number of correct predictions divided by the total number of predictions for a classification task.  In training, the HMC samplers run for the specified number of epochs. An epoch corresponds to iterating the differential equations inside the main HMC sampler for the specified number of leapfrog steps, updating the weights, biases, and activation functions, and then repeating this process with the hyper-parameters.

Predictions and Post Processing
In order to prevent the output files in which the networks are saved from becoming too large and to allow predictions midway through training, the number of networks written to each file can be specified by the user, as noted above. One file is saved with the shapes of each matrix that defines the network architecture so that they can be properly extracted. Another file is saved that contains the layer names so the network can be reconstructed.
The predictor object, which is instantiated as follows, # instantiate a predictor object network = predictor ( " modelDir / " , # Directory where model is located dtype = dtype ) # Data type of model uses these files to make predictions. Once the object is instantiated, predictions can be made by calling its predict method with an input data matrix and specifying that every n saved networks are to be used. predictions = network . predict ( inputData , # Input data for model n =10) # Predict using every 10 networks Beyond making predictions from saved networks, the predictor class is also capable of re-weighting networks given a new set of priors. The ability to re-weight the point cloud of networks makes it possible to study the sensitivity of results to the choice of prior. We can compute the posterior density p 1 (θ|D) with the prior used in the generation of the point cloud and we can calculate the posterior density p 2 (θ|D) using a different prior. By weighting each network j by the ratio p 2 (θ j |D)/p 1 (θ j |D), given the network parameters θ j , we can approximate the point cloud that would have been generated had we used the alternative prior. In general, however, the only components of p 1 (θ|D) and p 2 (θ|D) that differ are their priors. Therefore, we can substitute π 2 (θ j )/π 1 (θ j ) for p 2 (θ j |D)/p 1 (θ j |D). But since it may be useful to study the effect of different likelihoods on the results, the code includes the option to supply new likelihoods. The option to re-weight allows fine tuning of the networks after training and makes it possible to explore the impact of different priors on the results.
Re-weighting is implemented in the reweight method of the predictor, which requires an architecture file containing the architecture of the network with different priors. The method can also accept the training data and a likelihood object for use in calculating the network probabilities should the impact of the likelihood need to be studied. The user can choose to use only every n networks when making predictions as illustrated in the code snippet below. In order to use these features a separate Layer object must be created for each new prior. These objects are then passed as a dictionary to the predictor object when it is instantiated. Optionally, a modified version of the likelihood object used while training can be included to study the impact of the modifications. The code below shows the instantiation of a predictor object with a custom Layer added and a call of the reweight method which returns a weight for each network.
# declare predictor object network = predictor ( " / path / to / saved / network " , dtype = dtype , # data type used by network customLayerDict ={ " dense2 " : Dense2 } # A dense layer with a different # prior likelihood = m odi fi ed Li ke li ho od ) # An optional likelihood function weights = network . reweight ( n =10 , # Use every 10 saved networks architecture = " architecture2 . txt " ) # New architecture file The predictor can also calculate the autocorrelation function of the networks, which is useful for choosing a suitable value for n in the predictor. Given the sequence of networks f 1 , f 2 , · · · , the autocorrelation and normalized autocorrelation are defined by respectively, wheref is the average prediction over the networks and n is the autocorrelation lag. One expects an approximately exponential decrease of ρ(n) with n. The larger the value of n the smaller the correlation between the networks separated by a lag of n and, therefore, the more independent the resulting ensemble of networks. The autocorrelation is computed with the autocorrelation method to which an input data matrix inputData is passed along with the maximum lag n max . The output of the method is a list containing the average autocorrelation for each value of n from 1 to n max , where n enters the calculation as in Eq. (12). The average is taken with respect to the input data matrix. The user can also opt to calculate the autocorrelation length, which may be taken to be the smallest recommended lag n. The autoCorrelationLength method accepts the same inputs as autocorrelation and returns a single float. Both of these methods make use of the emcee package [15]. Here is an example of the usage of both methods. autocorrelations = network . autocorrelation ( inputData , 75) # nmax corrLength = network . a ut o C o r r e l a t i o n L e n g t h ( inputData , 75) # nmax

Algorithmic Adjustments to Prior Algorithms
The HMC parameter adaptation scheme briefly mentioned in Section 3.2 is a modified version of the method described in Ref. [12]. Our method adapts the number of steps and stepsize in a leapfrog trajectory in attempt to maximize the length of the trajectories in the network parameter space in each iteration of the HMC sampler.
In TensorBNN, two variations are introduced. First, in the case that the HMC sampler iterates through 50 leapfrog trajectories without having accepted a point during burn-in, the algorithm resets and begins with the stepsize maximum and minimum values decreased by a factor of two. This was empirically observed to prevent the HMC sampler from remaining stagnant with an extremely low acceptance rate. Additionally, after each reset of the parameter adapter, the value of the step size and number of leapfrog steps were randomized for the first 20 iterations in order to prevent the algorithm from converging to a boundary point of the interval that had a high acceptance, but was not optimal, as it was observed to do without this randomization. This algorithm was implemented using a combination of TensorFlow and NumPy [16].
In order to begin the Markov chain sampling of network parameters at a position that reduces the number of needed burn-in steps, we trained a fully connected neural network using AMSGrad [17] with the version of Keras in TensorFlow. This can be done using TensorBNN or independently by the user should additional control be desired. We observed empirically that choosing a starting point for the Markov chain from a pre-training with gradient descent led to a faster burn-in time. The pre-training is done through three training cycles, each containing a fixed maximum number of epochs. Each cycle runs until the specified maximum number of epochs or until the validation loss has not decreased for a chosen number of epochs, which we call the patience parameter. After each cycle the learning rate was decreased by a factor of ten, and the best network, judged by the loss computed using the validation data, is selected as the starting point for the next cycle.

Use Cases
Here we present a simple application of TensorBNN in which we train a BNN to learn the function To accomplish this task we construct two datasests. One has 11 evenly spaced points (x i , y i ) for x i ∈ [−2, 2], called the sparse dataset, and the second,  Figure 1. In addition, we present results demonstrating the performance of a model, trained using gradient descent, for approximating BNNs using current TensorFlow and TensorFlow-Probability functionality. The model uses DenseFlipout layers to approximates the posterior density of network parameters using Gaussian densities and using Gaussian priors. Both models are tested on data with x i ∈ [−3, 3]. The goal is assess the performance of the models on sparse data, dense data, variably distributed data, and extrapolation. The network architecture for these tests consists of three fully connected hidden layers with 10 nodes each using the hyperbolic tangent activation function. The starting point for sampling was obtained by pre-training the model with the AMSGrad optimizer for 100 epochs with a patience of 10 at learning rates of 0.01, 0.001, and 0.0001. The values for each of the remaining training parameters can be found in Table 5. As the dataset used for this task is small and the network is not especially large training can be completed using either a GPU or a CPU in a matter of minutes. The TensorFlow-Probability models are trained with the same network architecture with the AMSGrad optimizer for 1000 epochs with a patience of 100 at learning rates of 0.01, 0.001, and 0.0001.
A graphical representation of the training results for using TensorBNN is shown in Figure 2. These plots demonstrate several important properties of BNN. Firstly, we see generally that as the test points get further from the training points the variability of the output of the BNN increases. This is consistent with the fact that there are more predictions that are consistent with the training data, while the variability is small near the training points as expected and desired.
Secondly, the credible intervals of the BNN do not always contain the true value. In the left graph in Figure 2, it is clear that the BNN is quite wrong about the behavior of the curve between the first two and last two training points. This, however, is not unreasonable, as the value of the curve decreases dramatically between those values, without any training data to indicate this behavior. The BNN predicts that the curve should follow a roughly straight path between the points, but correctly suggests that the prediction in that region is very uncertain. But while the BNN will predict greater uncertainty in regions without data, as desired, it remains true, nevertheless, that one should be cautious about any extrapolation into a region with no data because the predicted uncertainty will depend on details of the model, in particular, the prior. It is therefore good practice to study the sensitivity of conclusions to modifications of the prior in any real-world analysis. TensorBNN provides tools for such sensitivity studies.
An interesting approximation to the posterior density of neural network parameters, and therefore to Bayesian neural networks, is available through the DenseFlipout and DenseVariational layers of TFP [2]. This method approximates a Bayesian neural network using a combination of variational inference and sampling. A forward pass through the network samples the network parameters from a variational density, a diagonal multivariate Gaussian whose means and standard deviations are optimized during training, a method originally proposed in [18]. TensorBNN on the other hand makes no assumption about the form of the posterior density and, therefore, in principle can account for posterior densities containing non-trivial dependencies between the network parameters. Given the fundamentally different approximations used in TensorBNN and TensorFlow-Probability, a priori, it is not be surprising if these approximations sometimes yielded different predictive distributions. A systematic comparison of the two approaches is beyond the scope of this paper, but in Figure 3 we see an example of how the results can differ. Figure 3 shows the results of our toy problems using DenseFlipout layers, which may be compared with the results obtained using TensorBNN in Figure 2. The results using the different approaches are reasonable under the respective assumptions including the choice of priors. It would be interesting to investigate whether the results of the two approaches would converge as the priors permitted a greater and greater dynamic range in the values of the network parameters. Additionally, BNNs in the style of those in TensorFlow-Probability have been used successfully in HEP, such as in [19,20].
Beyond these simple examples, a more complex application of TensorBNN can be found in [21]. In that paper, the package is used to predict the cross sections for supersymmetric particle creation at the Large Hadron Collider, predict which supersymmetric model points are theoretically viable, and predict the mass of the lightest neural Higgs boson, which is generally identified with the Higgs boson discovered at CERN [22,23].

Summary
TensorBNN is a framework that allows for the full Bayesian treatment of neural networks while leveraging GPU computing through the TensorFlow platform. Through an automation of the search for the parameters needed for an effective Hamiltonian Monte Carlo sampler and the ease of using a pre-trained network, TensorBNN is able to decrease the computation needed to converge to a sample from the posterior density of the neural network parameters. The algorithm automatically adapts hyper-parameters to reduce the amount of fine-tuning required by the user. As shown through the simple examples, the distribution of the network predictions behave according to expectations and can be yield good results even on difficult learning problems. The package provides a flexible means to perform regression and binary classification and is designed with the potential for expansion in terms of allowed network architectures and output possibilities.  Table 3: GaussianDenseLayer and CauchyDenseLayer initial values of prior hyperparameters, α and β, and the fixed hyper-prior parameters.

Name
Parameter Description leakyReLU m = 0.3 fixed slope parameter PReLU m = 0.2 initial slope parameter λ = 0.3 initial rate parameter for the m prior γ λ = 0.3 rate parameter for the λ hyper-prior SquarePReLU m = 0.2 initial slope parameter γ = 0.3 initial mean for the m prior ω = 0.3 initial standard deviation for the m prior µ γ = 0.0 mean for the hyper-prior of γ σ γ = 0.1 standard deviation for the γ hyper-prior µ ω = 0.3 mean for the ω hyper-prior σ ω = 0.3 standard deviation for the ω hyper-prior