{"id":4420,"date":"2021-02-21T18:00:04","date_gmt":"2021-02-21T18:00:04","guid":{"rendered":"https:\/\/www.aiproblog.com\/index.php\/2021\/02\/21\/prediction-intervals-for-deep-learning-neural-networks\/"},"modified":"2021-02-21T18:00:04","modified_gmt":"2021-02-21T18:00:04","slug":"prediction-intervals-for-deep-learning-neural-networks","status":"publish","type":"post","link":"https:\/\/www.aiproblog.com\/index.php\/2021\/02\/21\/prediction-intervals-for-deep-learning-neural-networks\/","title":{"rendered":"Prediction Intervals for Deep Learning Neural Networks"},"content":{"rendered":"<p>Author: Jason Brownlee<\/p>\n<div>\n<p><strong>Prediction intervals<\/strong> provide a measure of uncertainty for predictions on regression problems.<\/p>\n<p>For example, a 95% prediction interval indicates that 95 out of 100 times, the true value will fall between the lower and upper values of the range. This is different from a simple point prediction that might represent the center of the uncertainty interval.<\/p>\n<p>There are no standard techniques for calculating a prediction interval for deep learning neural networks on regression predictive modeling problems. Nevertheless, a quick and dirty prediction interval can be estimated using an ensemble of models that, in turn, provide a distribution of point predictions from which an interval can be calculated.<\/p>\n<p>In this tutorial, you will discover how to calculate a prediction interval for deep learning neural networks.<\/p>\n<p>After completing this tutorial, you will know:<\/p>\n<ul>\n<li>Prediction intervals provide a measure of uncertainty on regression predictive modeling problems.<\/li>\n<li>How to develop and evaluate a simple Multilayer Perceptron neural network on a standard regression problem.<\/li>\n<li>How to calculate and report a prediction interval using an ensemble of neural network models.<\/li>\n<\/ul>\n<p>Let\u2019s get started.<\/p>\n<div id=\"attachment_12209\" style=\"width: 810px\" class=\"wp-caption aligncenter\">\n<img decoding=\"async\" aria-describedby=\"caption-attachment-12209\" loading=\"lazy\" class=\"size-full wp-image-12209\" src=\"https:\/\/machinelearningmastery.com\/wp-content\/uploads\/2021\/05\/Prediction-Intervals-for-Deep-Learning-Neural-Networks.jpg\" alt=\"Prediction Intervals for Deep Learning Neural Networks\" width=\"800\" height=\"532\" srcset=\"http:\/\/3qeqpr26caki16dnhd19sv6by6v.wpengine.netdna-cdn.com\/wp-content\/uploads\/2021\/05\/Prediction-Intervals-for-Deep-Learning-Neural-Networks.jpg 800w, http:\/\/3qeqpr26caki16dnhd19sv6by6v.wpengine.netdna-cdn.com\/wp-content\/uploads\/2021\/05\/Prediction-Intervals-for-Deep-Learning-Neural-Networks-300x200.jpg 300w, http:\/\/3qeqpr26caki16dnhd19sv6by6v.wpengine.netdna-cdn.com\/wp-content\/uploads\/2021\/05\/Prediction-Intervals-for-Deep-Learning-Neural-Networks-768x511.jpg 768w\" sizes=\"(max-width: 800px) 100vw, 800px\"><\/p>\n<p id=\"caption-attachment-12209\" class=\"wp-caption-text\">Prediction Intervals for Deep Learning Neural Networks<br \/>Photo by <a href=\"https:\/\/www.flickr.com\/photos\/eugene_o\/40886909870\/\">eugene_o<\/a>, some rights reserved.<\/p>\n<\/div>\n<h2>Tutorial Overview<\/h2>\n<p>This tutorial is divided into three parts; they are:<\/p>\n<ol>\n<li>Prediction Interval<\/li>\n<li>Neural Network for Regression<\/li>\n<li>Neural Network Prediction Interval<\/li>\n<\/ol>\n<h2>Prediction Interval<\/h2>\n<p>Generally, predictive models for regression problems (i.e. predicting a numerical value) make a point prediction.<\/p>\n<p>This means they predict a single value but do not give any indication of the uncertainty about the prediction.<\/p>\n<p>By definition, a prediction is an estimate or an approximation and contains some uncertainty. The uncertainty comes from the errors in the model itself and noise in the input data. The model is an approximation of the relationship between the input variables and the output variables.<\/p>\n<p>A prediction interval is a quantification of the uncertainty on a prediction.<\/p>\n<p>It provides a probabilistic upper and lower bounds on the estimate of an outcome variable.<\/p>\n<blockquote>\n<p>A prediction interval for a single future observation is an interval that will, with a specified degree of confidence, contain a future randomly selected observation from a distribution.<\/p>\n<\/blockquote>\n<p>\u2014 Page 27, <a href=\"http:\/\/amzn.to\/2G8w3IL\">Statistical Intervals: A Guide for Practitioners and Researchers<\/a>, 2017.<\/p>\n<p>Prediction intervals are most commonly used when making predictions or forecasts with a regression model, where a quantity is being predicted.<\/p>\n<p>The prediction interval surrounds the prediction made by the model and hopefully covers the range of the true outcome.<\/p>\n<p>For more on prediction intervals in general, see the tutorial:<\/p>\n<ul>\n<li><a href=\"https:\/\/machinelearningmastery.com\/prediction-intervals-for-machine-learning\/\">Prediction Intervals for Machine Learning<\/a><\/li>\n<\/ul>\n<p>Now that we are familiar with what a prediction interval is, we can consider how we might calculate an interval for a neural network. Let\u2019s start by defining a regression problem and a neural network model to address it.<\/p>\n<h2>Neural Network for Regression<\/h2>\n<p>In this section, we will define a regression predictive modeling problem and a neural network model to address it.<\/p>\n<p>First, let\u2019s introduce a standard regression dataset. We will use the housing dataset.<\/p>\n<p>The housing dataset is a standard machine learning dataset comprising 506 rows of data with 13 numerical input variables and a numerical target variable.<\/p>\n<p>Using a test harness of repeated stratified 10-fold cross-validation with three repeats, a naive model can achieve a mean absolute error (MAE) of about 6.6. A <a href=\"https:\/\/machinelearningmastery.com\/results-for-standard-classification-and-regression-machine-learning-datasets\/\">top-performing model<\/a> can achieve a MAE on this same test harness of about 1.9. This provides the bounds of expected performance on this dataset.<\/p>\n<p>The dataset involves predicting the house price given details of the house\u2019s suburb in the American city of Boston.<\/p>\n<ul>\n<li><a href=\"https:\/\/raw.githubusercontent.com\/jbrownlee\/Datasets\/master\/housing.csv\">Housing Dataset (housing.csv)<\/a><\/li>\n<li><a href=\"https:\/\/raw.githubusercontent.com\/jbrownlee\/Datasets\/master\/housing.names\">Housing Description (housing.names)<\/a><\/li>\n<\/ul>\n<p>No need to download the dataset; we will download it automatically as part of our worked examples.<\/p>\n<p>The example below downloads and loads the dataset as a Pandas DataFrame and summarizes the shape of the dataset and the first five rows of data.<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\"># load and summarize the housing dataset\r\nfrom pandas import read_csv\r\nfrom matplotlib import pyplot\r\n# load dataset\r\nurl = 'https:\/\/raw.githubusercontent.com\/jbrownlee\/Datasets\/master\/housing.csv'\r\ndataframe = read_csv(url, header=None)\r\n# summarize shape\r\nprint(dataframe.shape)\r\n# summarize first few lines\r\nprint(dataframe.head())<\/pre>\n<p>Running the example confirms the 506 rows of data and 13 input variables and a single numeric target variable (14 in total). We can also see that all input variables are numeric.<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\">(506, 14)\r\n        0     1     2   3      4      5   ...  8      9     10      11    12    13\r\n0  0.00632  18.0  2.31   0  0.538  6.575  ...   1  296.0  15.3  396.90  4.98  24.0\r\n1  0.02731   0.0  7.07   0  0.469  6.421  ...   2  242.0  17.8  396.90  9.14  21.6\r\n2  0.02729   0.0  7.07   0  0.469  7.185  ...   2  242.0  17.8  392.83  4.03  34.7\r\n3  0.03237   0.0  2.18   0  0.458  6.998  ...   3  222.0  18.7  394.63  2.94  33.4\r\n4  0.06905   0.0  2.18   0  0.458  7.147  ...   3  222.0  18.7  396.90  5.33  36.2\r\n\r\n[5 rows x 14 columns]<\/pre>\n<p>Next, we can prepare the dataset for modeling.<\/p>\n<p>First, the dataset can be split into input and output columns, and then the rows can be <a href=\"https:\/\/machinelearningmastery.com\/train-test-split-for-evaluating-machine-learning-algorithms\/\">split into train and test datasets<\/a>.<\/p>\n<p>In this case, we will use approximately 67% of the rows to train the model and the remaining 33% to estimate the performance of the model.<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\">...\r\n# split into input and output values\r\nX, y = values[:,:-1], values[:,-1]\r\n# split into train and test sets\r\nX_train, X_test, y_train, y_test = train_test_split(X, y, train_size=0.67)<\/pre>\n<p>You can learn more about the train-test split in this tutorial:<\/p>\n<ul>\n<li><a href=\"https:\/\/machinelearningmastery.com\/train-test-split-for-evaluating-machine-learning-algorithms\/\">Train-Test Split for Evaluating Machine Learning Algorithms<\/a><\/li>\n<\/ul>\n<p>We will then scale all input columns (variables) to have the range 0-1, called data normalization, which is a good practice when working with neural network models.<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\">...\r\n# scale input data\r\nscaler = MinMaxScaler()\r\nscaler.fit(X_train)\r\nX_train = scaler.transform(X_train)\r\nX_test = scaler.transform(X_test)<\/pre>\n<p>You can learn more about normalizing input data with the MinMaxScaler in this tutorial:<\/p>\n<ul>\n<li><a href=\"https:\/\/machinelearningmastery.com\/standardscaler-and-minmaxscaler-transforms-in-python\/\">How to Use StandardScaler and MinMaxScaler Transforms in Python<\/a><\/li>\n<\/ul>\n<p>The complete example of preparing the data for modeling is listed below.<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\"># load and prepare the dataset for modeling\r\nfrom pandas import read_csv\r\nfrom sklearn.model_selection import train_test_split\r\nfrom sklearn.preprocessing import MinMaxScaler\r\n# load dataset\r\nurl = 'https:\/\/raw.githubusercontent.com\/jbrownlee\/Datasets\/master\/housing.csv'\r\ndataframe = read_csv(url, header=None)\r\nvalues = dataframe.values\r\n# split into input and output values\r\nX, y = values[:,:-1], values[:,-1]\r\n# split into train and test sets\r\nX_train, X_test, y_train, y_test = train_test_split(X, y, train_size=0.67)\r\n# scale input data\r\nscaler = MinMaxScaler()\r\nscaler.fit(X_train)\r\nX_train = scaler.transform(X_train)\r\nX_test = scaler.transform(X_test)\r\n# summarize\r\nprint(X_train.shape, X_test.shape, y_train.shape, y_test.shape)<\/pre>\n<p>Running the example loads the dataset as before, then splits the columns into input and output elements, rows into train and test sets, and finally scales all input variables to the range [0,1]<\/p>\n<p>The shape of the train and test sets is printed, showing we have 339 rows to train the model and 167 to evaluate it.<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\">(339, 13) (167, 13) (339,) (167,)<\/pre>\n<p>Next, we can define, train and evaluate a Multilayer Perceptron (MLP) model on the dataset.<\/p>\n<p>We will define a simple model with two hidden layers and an output layer that predicts a numeric value. We will use the <a href=\"https:\/\/machinelearningmastery.com\/rectified-linear-activation-function-for-deep-learning-neural-networks\/\">ReLU activation function<\/a> and \u201c<em>he<\/em>\u201d weight initialization, which are a good practice.<\/p>\n<p>The number of nodes in each hidden layer was chosen after a little trial and error.<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\">...\r\n# define neural network model\r\nfeatures = X_train.shape[1]\r\nmodel = Sequential()\r\nmodel.add(Dense(20, kernel_initializer='he_normal', activation='relu', input_dim=features))\r\nmodel.add(Dense(5, kernel_initializer='he_normal', activation='relu'))\r\nmodel.add(Dense(1))<\/pre>\n<p>We will use the efficient Adam version of stochastic gradient descent with close to default learning rate and momentum values and fit the model using the mean squared error (MSE) loss function, a standard for regression predictive modeling problems.<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\">...\r\n# compile the model and specify loss and optimizer\r\nopt = Adam(learning_rate=0.01, beta_1=0.85, beta_2=0.999)\r\nmodel.compile(optimizer=opt, loss='mse')<\/pre>\n<p>You can learn more about the Adam optimization algorithm in this tutorial:<\/p>\n<ul>\n<li><a href=\"https:\/\/machinelearningmastery.com\/adam-optimization-from-scratch\/\">Code Adam Gradient Descent Optimization From Scratch<\/a><\/li>\n<\/ul>\n<p>The model will then be fit for 300 epochs with a batch size of 16 samples. This configuration was chosen after a little trial and error.<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\">...\r\n# fit the model on the training dataset\r\nmodel.fit(X_train, y_train, verbose=2, epochs=300, batch_size=16)<\/pre>\n<p>You can learn more about batches and epochs in this tutorial:<\/p>\n<ul>\n<li><a href=\"https:\/\/machinelearningmastery.com\/difference-between-a-batch-and-an-epoch\/\">Difference Between a Batch and an Epoch in a Neural Network<\/a><\/li>\n<\/ul>\n<p>Finally, the model can be used to make predictions on the test dataset and we can evaluate the predictions by comparing them to the expected values in the test set and calculate the mean absolute error (MAE), a useful measure of model performance.<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\">...\r\n# make predictions on the test set\r\nyhat = model.predict(X_test, verbose=0)\r\n# calculate the average error in the predictions\r\nmae = mean_absolute_error(y_test, yhat)\r\nprint('MAE: %.3f' % mae)<\/pre>\n<p>Tying this together, the complete example is listed below.<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\"># train and evaluate a multilayer perceptron neural network on the housing regression dataset\r\nfrom pandas import read_csv\r\nfrom sklearn.model_selection import train_test_split\r\nfrom sklearn.metrics import mean_absolute_error\r\nfrom sklearn.preprocessing import MinMaxScaler\r\nfrom tensorflow.keras.models import Sequential\r\nfrom tensorflow.keras.layers import Dense\r\nfrom tensorflow.keras.optimizers import Adam\r\n# load dataset\r\nurl = 'https:\/\/raw.githubusercontent.com\/jbrownlee\/Datasets\/master\/housing.csv'\r\ndataframe = read_csv(url, header=None)\r\nvalues = dataframe.values\r\n# split into input and output values\r\nX, y = values[:, :-1], values[:,-1]\r\n# split into train and test sets\r\nX_train, X_test, y_train, y_test = train_test_split(X, y, train_size=0.67, random_state=1)\r\n# scale input data\r\nscaler = MinMaxScaler()\r\nscaler.fit(X_train)\r\nX_train = scaler.transform(X_train)\r\nX_test = scaler.transform(X_test)\r\n# define neural network model\r\nfeatures = X_train.shape[1]\r\nmodel = Sequential()\r\nmodel.add(Dense(20, kernel_initializer='he_normal', activation='relu', input_dim=features))\r\nmodel.add(Dense(5, kernel_initializer='he_normal', activation='relu'))\r\nmodel.add(Dense(1))\r\n# compile the model and specify loss and optimizer\r\nopt = Adam(learning_rate=0.01, beta_1=0.85, beta_2=0.999)\r\nmodel.compile(optimizer=opt, loss='mse')\r\n# fit the model on the training dataset\r\nmodel.fit(X_train, y_train, verbose=2, epochs=300, batch_size=16)\r\n# make predictions on the test set\r\nyhat = model.predict(X_test, verbose=0)\r\n# calculate the average error in the predictions\r\nmae = mean_absolute_error(y_test, yhat)\r\nprint('MAE: %.3f' % mae)<\/pre>\n<p>Running the example loads and prepares the dataset, defines and fits the MLP model on the training dataset, and evaluates its performance on the test set.<\/p>\n<p><strong>Note<\/strong>: Your <a href=\"https:\/\/machinelearningmastery.com\/different-results-each-time-in-machine-learning\/\">results may vary<\/a> given the stochastic nature of the algorithm or evaluation procedure, or differences in numerical precision. Consider running the example a few times and compare the average outcome.<\/p>\n<p>In this case, we can see that the model achieves a mean absolute error of approximately 2.3, which is better than a naive model and getting close to an optimal model.<\/p>\n<p>No doubt we could achieve near-optimal performance with further tuning of the model, but this is good enough for our investigation of prediction intervals.<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\">...\r\nEpoch 296\/300\r\n22\/22 - 0s - loss: 7.1741\r\nEpoch 297\/300\r\n22\/22 - 0s - loss: 6.8044\r\nEpoch 298\/300\r\n22\/22 - 0s - loss: 6.8623\r\nEpoch 299\/300\r\n22\/22 - 0s - loss: 7.7010\r\nEpoch 300\/300\r\n22\/22 - 0s - loss: 6.5374\r\nMAE: 2.300<\/pre>\n<p>Next, let\u2019s look at how we might calculate a prediction interval using our MLP model on the housing dataset.<\/p>\n<h2>Neural Network Prediction Interval<\/h2>\n<p>In this section, we will develop a prediction interval using the regression problem and model developed in the previous section.<\/p>\n<p>Calculating prediction intervals for nonlinear regression algorithms like neural networks is challenging compared to linear methods like linear regression where the prediction interval calculation is trivial. There is no standard technique.<\/p>\n<p>There are many ways to calculate an effective prediction interval for neural network models. I recommend some of the papers listed in the \u201c<em>further reading<\/em>\u201d section to learn more.<\/p>\n<p>In this tutorial, we will use a very simple approach that has plenty of room for extension. I refer to it as \u201c<em>quick and dirty<\/em>\u201d because it is fast and easy to calculate, but is limited.<\/p>\n<p>It involves fitting multiple final models (e.g. 10 to 30). The distribution of the point predictions from ensemble members is then used to calculate both a point prediction and a prediction interval.<\/p>\n<p>For example, a point prediction can be taken as the mean of the point predictions from ensemble members, and a 95% prediction interval can be taken as <a href=\"https:\/\/en.wikipedia.org\/wiki\/1.96\">1.96 standard deviations<\/a> from the mean.<\/p>\n<p>This is a simple Gaussian prediction interval, although alternatives could be used, such as the min and max of the point predictions. Alternatively, the bootstrap method could be used to train each ensemble member on a different bootstrap sample and the 2.5th and 97.5th percentiles of the point predictions can be used as prediction intervals.<\/p>\n<p>For more on the bootstrap method, see the tutorial:<\/p>\n<ul>\n<li><a href=\"https:\/\/machinelearningmastery.com\/a-gentle-introduction-to-the-bootstrap-method\/\">A Gentle Introduction to the Bootstrap Method<\/a><\/li>\n<\/ul>\n<p>These extensions are left as exercises; we will stick with the simple Gaussian prediction interval.<\/p>\n<p>Let\u2019s assume that the training dataset, defined in the previous section, is the entire dataset and we are training a final model or models on this entire dataset. We can then make predictions with prediction intervals on the test set and evaluate how effective the interval might be in the future.<\/p>\n<p>We can simplify the code by dividing the elements developed in the previous section into functions.<\/p>\n<p>First, let\u2019s define a function for loading and preparing a regression dataset defined by a URL.<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\"># load and prepare the dataset\r\ndef load_dataset(url):\r\n\tdataframe = read_csv(url, header=None)\r\n\tvalues = dataframe.values\r\n\t# split into input and output values\r\n\tX, y = values[:, :-1], values[:,-1]\r\n\t# split into train and test sets\r\n\tX_train, X_test, y_train, y_test = train_test_split(X, y, train_size=0.67, random_state=1)\r\n\t# scale input data\r\n\tscaler = MinMaxScaler()\r\n\tscaler.fit(X_train)\r\n\tX_train = scaler.transform(X_train)\r\n\tX_test = scaler.transform(X_test)\r\n\treturn X_train, X_test, y_train, y_test<\/pre>\n<p>Next, we can define a function that will define and train an MLP model given the training dataset, then return the fit model ready for making predictions.<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\"># define and fit the model\r\ndef fit_model(X_train, y_train):\r\n\t# define neural network model\r\n\tfeatures = X_train.shape[1]\r\n\tmodel = Sequential()\r\n\tmodel.add(Dense(20, kernel_initializer='he_normal', activation='relu', input_dim=features))\r\n\tmodel.add(Dense(5, kernel_initializer='he_normal', activation='relu'))\r\n\tmodel.add(Dense(1))\r\n\t# compile the model and specify loss and optimizer\r\n\topt = Adam(learning_rate=0.01, beta_1=0.85, beta_2=0.999)\r\n\tmodel.compile(optimizer=opt, loss='mse')\r\n\t# fit the model on the training dataset\r\n\tmodel.fit(X_train, y_train, verbose=0, epochs=300, batch_size=16)\r\n\treturn model<\/pre>\n<p>We require multiple models to make point predictions that will define a distribution of point predictions from which we can estimate the interval.<\/p>\n<p>As such, we will need to fit multiple models on the training dataset. Each model must be different so that it makes different predictions. This can be achieved given the stochastic nature of training MLP models, given the random initial weights, and given the use of the stochastic gradient descent optimization algorithm.<\/p>\n<p>The more models, the better the point predictions will estimate the capability of the model. I would recommend at least 10 models, and perhaps not much benefit beyond 30 models.<\/p>\n<p>The function below fits an ensemble of models and stores them in a list that is returned.<\/p>\n<p>For interest, each fit model is also evaluated on the test set which is reported after each model is fit. We would expect that each model will have a slightly different estimated performance on the hold-out test set and the reported scores will help us confirm this expectation.<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\"># fit an ensemble of models\r\ndef fit_ensemble(n_members, X_train, X_test, y_train, y_test):\r\n\tensemble = list()\r\n\tfor i in range(n_members):\r\n\t\t# define and fit the model on the training set\r\n\t\tmodel = fit_model(X_train, y_train)\r\n\t\t# evaluate model on the test set\r\n\t\tyhat = model.predict(X_test, verbose=0)\r\n\t\tmae = mean_absolute_error(y_test, yhat)\r\n\t\tprint('&gt;%d, MAE: %.3f' % (i+1, mae))\r\n\t\t# store the model\r\n\t\tensemble.append(model)\r\n\treturn ensemble<\/pre>\n<p>Finally, we can use the trained ensemble of models to make point predictions, which can be summarized into a prediction interval.<\/p>\n<p>The function below implements this. First, each model makes a point prediction on the input data, then the 95% prediction interval is calculated and the lower, mean, and upper values of the interval are returned.<\/p>\n<p>The function is designed to take a single row as input, but could easily be adapted for multiple rows.<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\"># make predictions with the ensemble and calculate a prediction interval\r\ndef predict_with_pi(ensemble, X):\r\n\t# make predictions\r\n\tyhat = [model.predict(X, verbose=0) for model in ensemble]\r\n\tyhat = asarray(yhat)\r\n\t# calculate 95% gaussian prediction interval\r\n\tinterval = 1.96 * yhat.std()\r\n\tlower, upper = yhat.mean() - interval, yhat.mean() + interval\r\n\treturn lower, yhat.mean(), upper<\/pre>\n<p>Finally, we can call these functions.<\/p>\n<p>First, the dataset is loaded and prepared, then the ensemble is defined and fit.<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\">...\r\n# load dataset\r\nurl = 'https:\/\/raw.githubusercontent.com\/jbrownlee\/Datasets\/master\/housing.csv'\r\nX_train, X_test, y_train, y_test = load_dataset(url)\r\n# fit ensemble\r\nn_members = 30\r\nensemble = fit_ensemble(n_members, X_train, X_test, y_train, y_test)<\/pre>\n<p>We can then use a single row of data from the test set and make a prediction with a prediction interval, the results of which are then reported.<\/p>\n<p>We also report the expected value which we would expect would be covered by the prediction interval (perhaps close to 95% of the time; this is not entirely accurate, but is a rough approximation).<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\">...\r\n# make predictions with prediction interval\r\nnewX = asarray([X_test[0, :]])\r\nlower, mean, upper = predict_with_pi(ensemble, newX)\r\nprint('Point prediction: %.3f' % mean)\r\nprint('95%% prediction interval: [%.3f, %.3f]' % (lower, upper))\r\nprint('True value: %.3f' % y_test[0])<\/pre>\n<p>Tying this together, the complete example of making predictions with a prediction interval with a Multilayer Perceptron neural network is listed below.<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\"># prediction interval for mlps on the housing regression dataset\r\nfrom numpy import asarray\r\nfrom pandas import read_csv\r\nfrom sklearn.model_selection import train_test_split\r\nfrom sklearn.metrics import mean_absolute_error\r\nfrom sklearn.preprocessing import MinMaxScaler\r\nfrom tensorflow.keras.models import Sequential\r\nfrom tensorflow.keras.layers import Dense\r\nfrom tensorflow.keras.optimizers import Adam\r\n\r\n# load and prepare the dataset\r\ndef load_dataset(url):\r\n\tdataframe = read_csv(url, header=None)\r\n\tvalues = dataframe.values\r\n\t# split into input and output values\r\n\tX, y = values[:, :-1], values[:,-1]\r\n\t# split into train and test sets\r\n\tX_train, X_test, y_train, y_test = train_test_split(X, y, train_size=0.67, random_state=1)\r\n\t# scale input data\r\n\tscaler = MinMaxScaler()\r\n\tscaler.fit(X_train)\r\n\tX_train = scaler.transform(X_train)\r\n\tX_test = scaler.transform(X_test)\r\n\treturn X_train, X_test, y_train, y_test\r\n\r\n# define and fit the model\r\ndef fit_model(X_train, y_train):\r\n\t# define neural network model\r\n\tfeatures = X_train.shape[1]\r\n\tmodel = Sequential()\r\n\tmodel.add(Dense(20, kernel_initializer='he_normal', activation='relu', input_dim=features))\r\n\tmodel.add(Dense(5, kernel_initializer='he_normal', activation='relu'))\r\n\tmodel.add(Dense(1))\r\n\t# compile the model and specify loss and optimizer\r\n\topt = Adam(learning_rate=0.01, beta_1=0.85, beta_2=0.999)\r\n\tmodel.compile(optimizer=opt, loss='mse')\r\n\t# fit the model on the training dataset\r\n\tmodel.fit(X_train, y_train, verbose=0, epochs=300, batch_size=16)\r\n\treturn model\r\n\r\n# fit an ensemble of models\r\ndef fit_ensemble(n_members, X_train, X_test, y_train, y_test):\r\n\tensemble = list()\r\n\tfor i in range(n_members):\r\n\t\t# define and fit the model on the training set\r\n\t\tmodel = fit_model(X_train, y_train)\r\n\t\t# evaluate model on the test set\r\n\t\tyhat = model.predict(X_test, verbose=0)\r\n\t\tmae = mean_absolute_error(y_test, yhat)\r\n\t\tprint('&gt;%d, MAE: %.3f' % (i+1, mae))\r\n\t\t# store the model\r\n\t\tensemble.append(model)\r\n\treturn ensemble\r\n\r\n# make predictions with the ensemble and calculate a prediction interval\r\ndef predict_with_pi(ensemble, X):\r\n\t# make predictions\r\n\tyhat = [model.predict(X, verbose=0) for model in ensemble]\r\n\tyhat = asarray(yhat)\r\n\t# calculate 95% gaussian prediction interval\r\n\tinterval = 1.96 * yhat.std()\r\n\tlower, upper = yhat.mean() - interval, yhat.mean() + interval\r\n\treturn lower, yhat.mean(), upper\r\n\r\n# load dataset\r\nurl = 'https:\/\/raw.githubusercontent.com\/jbrownlee\/Datasets\/master\/housing.csv'\r\nX_train, X_test, y_train, y_test = load_dataset(url)\r\n# fit ensemble\r\nn_members = 30\r\nensemble = fit_ensemble(n_members, X_train, X_test, y_train, y_test)\r\n# make predictions with prediction interval\r\nnewX = asarray([X_test[0, :]])\r\nlower, mean, upper = predict_with_pi(ensemble, newX)\r\nprint('Point prediction: %.3f' % mean)\r\nprint('95%% prediction interval: [%.3f, %.3f]' % (lower, upper))\r\nprint('True value: %.3f' % y_test[0])<\/pre>\n<p>Running the example fits each ensemble member in turn and reports its estimated performance on the hold out tests set; finally, a single prediction with prediction interval is made and reported.<\/p>\n<p><strong>Note<\/strong>: Your <a href=\"https:\/\/machinelearningmastery.com\/different-results-each-time-in-machine-learning\/\">results may vary<\/a> given the stochastic nature of the algorithm or evaluation procedure, or differences in numerical precision. Consider running the example a few times and compare the average outcome.<\/p>\n<p>In this case, we can see that each model has a slightly different performance, confirming our expectation that the models are indeed different.<\/p>\n<p>Finally, we can see that the ensemble made a point prediction of about 30.5 with a 95% prediction interval of [26.287, 34.822]. We can also see that the true value was 28.2 and that the interval does capture this value, which is great.<\/p>\n<pre class=\"urvanov-syntax-highlighter-plain-tag\">&gt;1, MAE: 2.259\r\n&gt;2, MAE: 2.144\r\n&gt;3, MAE: 2.732\r\n&gt;4, MAE: 2.628\r\n&gt;5, MAE: 2.483\r\n&gt;6, MAE: 2.551\r\n&gt;7, MAE: 2.505\r\n&gt;8, MAE: 2.299\r\n&gt;9, MAE: 2.706\r\n&gt;10, MAE: 2.145\r\n&gt;11, MAE: 2.765\r\n&gt;12, MAE: 3.244\r\n&gt;13, MAE: 2.385\r\n&gt;14, MAE: 2.592\r\n&gt;15, MAE: 2.418\r\n&gt;16, MAE: 2.493\r\n&gt;17, MAE: 2.367\r\n&gt;18, MAE: 2.569\r\n&gt;19, MAE: 2.664\r\n&gt;20, MAE: 2.233\r\n&gt;21, MAE: 2.228\r\n&gt;22, MAE: 2.646\r\n&gt;23, MAE: 2.641\r\n&gt;24, MAE: 2.492\r\n&gt;25, MAE: 2.558\r\n&gt;26, MAE: 2.416\r\n&gt;27, MAE: 2.328\r\n&gt;28, MAE: 2.383\r\n&gt;29, MAE: 2.215\r\n&gt;30, MAE: 2.408\r\nPoint prediction: 30.555\r\n95% prediction interval: [26.287, 34.822]\r\nTrue value: 28.200<\/pre>\n<p>This is a quick and dirty technique for making predictions with a prediction interval for neural networks, as we discussed above.<\/p>\n<p>There are easy extensions such as using the bootstrap method applied to point predictions that may be more reliable, and more advanced techniques described in some of the papers listed below that I recommend that you explore.<\/p>\n<h2>Further Reading<\/h2>\n<p>This section provides more resources on the topic if you are looking to go deeper.<\/p>\n<h3>Tutorials<\/h3>\n<ul>\n<li><a href=\"https:\/\/machinelearningmastery.com\/prediction-intervals-for-machine-learning\/\">Prediction Intervals for Machine Learning<\/a><\/li>\n<li><a href=\"https:\/\/machinelearningmastery.com\/standardscaler-and-minmaxscaler-transforms-in-python\/\">How to Use StandardScaler and MinMaxScaler Transforms in Python<\/a><\/li>\n<li><a href=\"https:\/\/machinelearningmastery.com\/results-for-standard-classification-and-regression-machine-learning-datasets\/\">Best Results for Standard Machine Learning Datasets<\/a><\/li>\n<li><a href=\"https:\/\/machinelearningmastery.com\/difference-between-a-batch-and-an-epoch\/\">Difference Between a Batch and an Epoch in a Neural Network<\/a><\/li>\n<li><a href=\"https:\/\/machinelearningmastery.com\/adam-optimization-from-scratch\/\">Code Adam Gradient Descent Optimization From Scratch<\/a><\/li>\n<\/ul>\n<h3>Papers<\/h3>\n<ul>\n<li>\n<a href=\"https:\/\/arxiv.org\/abs\/1802.07167\">High-Quality Prediction Intervals for Deep Learning: A Distribution-Free, Ensembled Approach<\/a>, 2018.<\/li>\n<li>\n<a href=\"https:\/\/papers.nips.cc\/paper\/1306-practicalconfidence-and-prediction-intervals\">Practical confidence and prediction intervals<\/a>, 1994.<\/li>\n<\/ul>\n<h3>Articles<\/h3>\n<ul>\n<li>\n<a href=\"https:\/\/en.wikipedia.org\/wiki\/1.96\">1.96, Wikipedia<\/a>.<\/li>\n<\/ul>\n<h2>Summary<\/h2>\n<p>In this tutorial, you discovered how to calculate a prediction interval for deep learning neural networks.<\/p>\n<p>Specifically, you learned:<\/p>\n<ul>\n<li>Prediction intervals provide a measure of uncertainty on regression predictive modeling problems.<\/li>\n<li>How to develop and evaluate a simple Multilayer Perceptron neural network on a standard regression problem.<\/li>\n<li>How to calculate and report a prediction interval using an ensemble of neural network models.<\/li>\n<\/ul>\n<p><strong>Do you have any questions?<\/strong><br \/>\nAsk your questions in the comments below and I will do my best to answer.<\/p>\n<p>The post <a rel=\"nofollow\" href=\"https:\/\/machinelearningmastery.com\/prediction-intervals-for-deep-learning-neural-networks\/\">Prediction Intervals for Deep Learning Neural Networks<\/a> appeared first on <a rel=\"nofollow\" href=\"https:\/\/machinelearningmastery.com\/\">Machine Learning Mastery<\/a>.<\/p>\n<\/div>\n<p><a href=\"https:\/\/machinelearningmastery.com\/prediction-intervals-for-deep-learning-neural-networks\/\">Go to Source<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Author: Jason Brownlee Prediction intervals provide a measure of uncertainty for predictions on regression problems. For example, a 95% prediction interval indicates that 95 out [&hellip;] <span class=\"read-more-link\"><a class=\"read-more\" href=\"https:\/\/www.aiproblog.com\/index.php\/2021\/02\/21\/prediction-intervals-for-deep-learning-neural-networks\/\">Read More<\/a><\/span><\/p>\n","protected":false},"author":1,"featured_media":4421,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_bbp_topic_count":0,"_bbp_reply_count":0,"_bbp_total_topic_count":0,"_bbp_total_reply_count":0,"_bbp_voice_count":0,"_bbp_anonymous_reply_count":0,"_bbp_topic_count_hidden":0,"_bbp_reply_count_hidden":0,"_bbp_forum_subforum_count":0,"footnotes":""},"categories":[24],"tags":[],"_links":{"self":[{"href":"https:\/\/www.aiproblog.com\/index.php\/wp-json\/wp\/v2\/posts\/4420"}],"collection":[{"href":"https:\/\/www.aiproblog.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.aiproblog.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.aiproblog.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.aiproblog.com\/index.php\/wp-json\/wp\/v2\/comments?post=4420"}],"version-history":[{"count":0,"href":"https:\/\/www.aiproblog.com\/index.php\/wp-json\/wp\/v2\/posts\/4420\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.aiproblog.com\/index.php\/wp-json\/wp\/v2\/media\/4421"}],"wp:attachment":[{"href":"https:\/\/www.aiproblog.com\/index.php\/wp-json\/wp\/v2\/media?parent=4420"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.aiproblog.com\/index.php\/wp-json\/wp\/v2\/categories?post=4420"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.aiproblog.com\/index.php\/wp-json\/wp\/v2\/tags?post=4420"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}