{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Deep Gaussian Processes\n", "### [Neil D. Lawrence](http://inverseprobability.com), Amazon Cambridge and University of Sheffield\n", "### 2019-01-11\n", "\n", "**Abstract**: Classical machine learning and statistical approaches to learning, such\n", "as neural networks and linear regression, assume a parametric form for\n", "functions. Gaussian process models are an alternative approach that\n", "assumes a probabilistic prior over functions. This brings benefits, in\n", "that uncertainty of function estimation is sustained throughout\n", "inference, and some challenges: algorithms for fitting Gaussian\n", "processes tend to be more complex than parametric models. In these\n", "sessions I will introduce Gaussian processes and explain why sustaining\n", "uncertainty is important. We’ll then look at some extensions of Gaussian\n", "process models, in particular composition of Gaussian processes, or deep\n", "Gaussian processes.\n", "\n", "$$\n", "\\newcommand{\\Amatrix}{\\mathbf{A}}\n", "\\newcommand{\\KL}[2]{\\text{KL}\\left( #1\\,\\|\\,#2 \\right)}\n", "\\newcommand{\\Kaast}{\\kernelMatrix_{\\mathbf{ \\ast}\\mathbf{ \\ast}}}\n", "\\newcommand{\\Kastu}{\\kernelMatrix_{\\mathbf{ \\ast} \\inducingVector}}\n", "\\newcommand{\\Kff}{\\kernelMatrix_{\\mappingFunctionVector \\mappingFunctionVector}}\n", "\\newcommand{\\Kfu}{\\kernelMatrix_{\\mappingFunctionVector \\inducingVector}}\n", "\\newcommand{\\Kuast}{\\kernelMatrix_{\\inducingVector \\bf\\ast}}\n", "\\newcommand{\\Kuf}{\\kernelMatrix_{\\inducingVector \\mappingFunctionVector}}\n", "\\newcommand{\\Kuu}{\\kernelMatrix_{\\inducingVector \\inducingVector}}\n", "\\newcommand{\\Kuui}{\\Kuu^{-1}}\n", "\\newcommand{\\Qaast}{\\mathbf{Q}_{\\bf \\ast \\ast}}\n", "\\newcommand{\\Qastf}{\\mathbf{Q}_{\\ast \\mappingFunction}}\n", "\\newcommand{\\Qfast}{\\mathbf{Q}_{\\mappingFunctionVector \\bf \\ast}}\n", "\\newcommand{\\Qff}{\\mathbf{Q}_{\\mappingFunctionVector \\mappingFunctionVector}}\n", "\\newcommand{\\aMatrix}{\\mathbf{A}}\n", "\\newcommand{\\aScalar}{a}\n", "\\newcommand{\\aVector}{\\mathbf{a}}\n", "\\newcommand{\\acceleration}{a}\n", "\\newcommand{\\bMatrix}{\\mathbf{B}}\n", "\\newcommand{\\bScalar}{b}\n", "\\newcommand{\\bVector}{\\mathbf{b}}\n", "\\newcommand{\\basisFunc}{\\phi}\n", "\\newcommand{\\basisFuncVector}{\\boldsymbol{ \\basisFunc}}\n", "\\newcommand{\\basisFunction}{\\phi}\n", "\\newcommand{\\basisLocation}{\\mu}\n", "\\newcommand{\\basisMatrix}{\\boldsymbol{ \\Phi}}\n", "\\newcommand{\\basisScalar}{\\basisFunction}\n", "\\newcommand{\\basisVector}{\\boldsymbol{ \\basisFunction}}\n", "\\newcommand{\\activationFunction}{\\phi}\n", "\\newcommand{\\activationMatrix}{\\boldsymbol{ \\Phi}}\n", "\\newcommand{\\activationScalar}{\\basisFunction}\n", "\\newcommand{\\activationVector}{\\boldsymbol{ \\basisFunction}}\n", "\\newcommand{\\bigO}{\\mathcal{O}}\n", "\\newcommand{\\binomProb}{\\pi}\n", "\\newcommand{\\cMatrix}{\\mathbf{C}}\n", "\\newcommand{\\cbasisMatrix}{\\hat{\\boldsymbol{ \\Phi}}}\n", "\\newcommand{\\cdataMatrix}{\\hat{\\dataMatrix}}\n", "\\newcommand{\\cdataScalar}{\\hat{\\dataScalar}}\n", "\\newcommand{\\cdataVector}{\\hat{\\dataVector}}\n", "\\newcommand{\\centeredKernelMatrix}{\\mathbf{ \\MakeUppercase{\\centeredKernelScalar}}}\n", "\\newcommand{\\centeredKernelScalar}{b}\n", "\\newcommand{\\centeredKernelVector}{\\centeredKernelScalar}\n", "\\newcommand{\\centeringMatrix}{\\mathbf{H}}\n", "\\newcommand{\\chiSquaredDist}[2]{\\chi_{#1}^{2}\\left(#2\\right)}\n", "\\newcommand{\\chiSquaredSamp}[1]{\\chi_{#1}^{2}}\n", "\\newcommand{\\conditionalCovariance}{\\boldsymbol{ \\Sigma}}\n", "\\newcommand{\\coregionalizationMatrix}{\\mathbf{B}}\n", "\\newcommand{\\coregionalizationScalar}{b}\n", "\\newcommand{\\coregionalizationVector}{\\mathbf{ \\coregionalizationScalar}}\n", "\\newcommand{\\covDist}[2]{\\text{cov}_{#2}\\left(#1\\right)}\n", "\\newcommand{\\covSamp}[1]{\\text{cov}\\left(#1\\right)}\n", "\\newcommand{\\covarianceScalar}{c}\n", "\\newcommand{\\covarianceVector}{\\mathbf{ \\covarianceScalar}}\n", "\\newcommand{\\covarianceMatrix}{\\mathbf{C}}\n", "\\newcommand{\\covarianceMatrixTwo}{\\boldsymbol{ \\Sigma}}\n", "\\newcommand{\\croupierScalar}{s}\n", "\\newcommand{\\croupierVector}{\\mathbf{ \\croupierScalar}}\n", "\\newcommand{\\croupierMatrix}{\\mathbf{ \\MakeUppercase{\\croupierScalar}}}\n", "\\newcommand{\\dataDim}{p}\n", "\\newcommand{\\dataIndex}{i}\n", "\\newcommand{\\dataIndexTwo}{j}\n", "\\newcommand{\\dataMatrix}{\\mathbf{Y}}\n", "\\newcommand{\\dataScalar}{y}\n", "\\newcommand{\\dataSet}{\\mathcal{D}}\n", "\\newcommand{\\dataStd}{\\sigma}\n", "\\newcommand{\\dataVector}{\\mathbf{ \\dataScalar}}\n", "\\newcommand{\\decayRate}{d}\n", "\\newcommand{\\degreeMatrix}{\\mathbf{ \\MakeUppercase{\\degreeScalar}}}\n", "\\newcommand{\\degreeScalar}{d}\n", "\\newcommand{\\degreeVector}{\\mathbf{ \\degreeScalar}}\n", "% Already defined by latex\n", "%\\newcommand{\\det}[1]{\\left|#1\\right|}\n", "\\newcommand{\\diag}[1]{\\text{diag}\\left(#1\\right)}\n", "\\newcommand{\\diagonalMatrix}{\\mathbf{D}}\n", "\\newcommand{\\diff}[2]{\\frac{\\text{d}#1}{\\text{d}#2}}\n", "\\newcommand{\\diffTwo}[2]{\\frac{\\text{d}^2#1}{\\text{d}#2^2}}\n", "\\newcommand{\\displacement}{x}\n", "\\newcommand{\\displacementVector}{\\textbf{\\displacement}}\n", "\\newcommand{\\distanceMatrix}{\\mathbf{ \\MakeUppercase{\\distanceScalar}}}\n", "\\newcommand{\\distanceScalar}{d}\n", "\\newcommand{\\distanceVector}{\\mathbf{ \\distanceScalar}}\n", "\\newcommand{\\eigenvaltwo}{\\ell}\n", "\\newcommand{\\eigenvaltwoMatrix}{\\mathbf{L}}\n", "\\newcommand{\\eigenvaltwoVector}{\\mathbf{l}}\n", "\\newcommand{\\eigenvalue}{\\lambda}\n", "\\newcommand{\\eigenvalueMatrix}{\\boldsymbol{ \\Lambda}}\n", "\\newcommand{\\eigenvalueVector}{\\boldsymbol{ \\lambda}}\n", "\\newcommand{\\eigenvector}{\\mathbf{ \\eigenvectorScalar}}\n", "\\newcommand{\\eigenvectorMatrix}{\\mathbf{U}}\n", "\\newcommand{\\eigenvectorScalar}{u}\n", "\\newcommand{\\eigenvectwo}{\\mathbf{v}}\n", "\\newcommand{\\eigenvectwoMatrix}{\\mathbf{V}}\n", "\\newcommand{\\eigenvectwoScalar}{v}\n", "\\newcommand{\\entropy}[1]{\\mathcal{H}\\left(#1\\right)}\n", "\\newcommand{\\errorFunction}{E}\n", "\\newcommand{\\expDist}[2]{\\left<#1\\right>_{#2}}\n", "\\newcommand{\\expSamp}[1]{\\left<#1\\right>}\n", "\\newcommand{\\expectation}[1]{\\left\\langle #1 \\right\\rangle }\n", "\\newcommand{\\expectationDist}[2]{\\left\\langle #1 \\right\\rangle _{#2}}\n", "\\newcommand{\\expectedDistanceMatrix}{\\mathcal{D}}\n", "\\newcommand{\\eye}{\\mathbf{I}}\n", "\\newcommand{\\fantasyDim}{r}\n", "\\newcommand{\\fantasyMatrix}{\\mathbf{ \\MakeUppercase{\\fantasyScalar}}}\n", "\\newcommand{\\fantasyScalar}{z}\n", "\\newcommand{\\fantasyVector}{\\mathbf{ \\fantasyScalar}}\n", "\\newcommand{\\featureStd}{\\varsigma}\n", "\\newcommand{\\gammaCdf}[3]{\\mathcal{GAMMA CDF}\\left(#1|#2,#3\\right)}\n", "\\newcommand{\\gammaDist}[3]{\\mathcal{G}\\left(#1|#2,#3\\right)}\n", "\\newcommand{\\gammaSamp}[2]{\\mathcal{G}\\left(#1,#2\\right)}\n", "\\newcommand{\\gaussianDist}[3]{\\mathcal{N}\\left(#1|#2,#3\\right)}\n", "\\newcommand{\\gaussianSamp}[2]{\\mathcal{N}\\left(#1,#2\\right)}\n", "\\newcommand{\\given}{|}\n", "\\newcommand{\\half}{\\frac{1}{2}}\n", "\\newcommand{\\heaviside}{H}\n", "\\newcommand{\\hiddenMatrix}{\\mathbf{ \\MakeUppercase{\\hiddenScalar}}}\n", "\\newcommand{\\hiddenScalar}{h}\n", "\\newcommand{\\hiddenVector}{\\mathbf{ \\hiddenScalar}}\n", "\\newcommand{\\identityMatrix}{\\eye}\n", "\\newcommand{\\inducingInputScalar}{z}\n", "\\newcommand{\\inducingInputVector}{\\mathbf{ \\inducingInputScalar}}\n", "\\newcommand{\\inducingInputMatrix}{\\mathbf{Z}}\n", "\\newcommand{\\inducingScalar}{u}\n", "\\newcommand{\\inducingVector}{\\mathbf{ \\inducingScalar}}\n", "\\newcommand{\\inducingMatrix}{\\mathbf{U}}\n", "\\newcommand{\\inlineDiff}[2]{\\text{d}#1/\\text{d}#2}\n", "\\newcommand{\\inputDim}{q}\n", "\\newcommand{\\inputMatrix}{\\mathbf{X}}\n", "\\newcommand{\\inputScalar}{x}\n", "\\newcommand{\\inputSpace}{\\mathcal{X}}\n", "\\newcommand{\\inputVals}{\\inputVector}\n", "\\newcommand{\\inputVector}{\\mathbf{ \\inputScalar}}\n", "\\newcommand{\\iterNum}{k}\n", "\\newcommand{\\kernel}{\\kernelScalar}\n", "\\newcommand{\\kernelMatrix}{\\mathbf{K}}\n", "\\newcommand{\\kernelScalar}{k}\n", "\\newcommand{\\kernelVector}{\\mathbf{ \\kernelScalar}}\n", "\\newcommand{\\kff}{\\kernelScalar_{\\mappingFunction \\mappingFunction}}\n", "\\newcommand{\\kfu}{\\kernelVector_{\\mappingFunction \\inducingScalar}}\n", "\\newcommand{\\kuf}{\\kernelVector_{\\inducingScalar \\mappingFunction}}\n", "\\newcommand{\\kuu}{\\kernelVector_{\\inducingScalar \\inducingScalar}}\n", "\\newcommand{\\lagrangeMultiplier}{\\lambda}\n", "\\newcommand{\\lagrangeMultiplierMatrix}{\\boldsymbol{ \\Lambda}}\n", "\\newcommand{\\lagrangian}{L}\n", "\\newcommand{\\laplacianFactor}{\\mathbf{ \\MakeUppercase{\\laplacianFactorScalar}}}\n", "\\newcommand{\\laplacianFactorScalar}{m}\n", "\\newcommand{\\laplacianFactorVector}{\\mathbf{ \\laplacianFactorScalar}}\n", "\\newcommand{\\laplacianMatrix}{\\mathbf{L}}\n", "\\newcommand{\\laplacianScalar}{\\ell}\n", "\\newcommand{\\laplacianVector}{\\mathbf{ \\ell}}\n", "\\newcommand{\\latentDim}{q}\n", "\\newcommand{\\latentDistanceMatrix}{\\boldsymbol{ \\Delta}}\n", "\\newcommand{\\latentDistanceScalar}{\\delta}\n", "\\newcommand{\\latentDistanceVector}{\\boldsymbol{ \\delta}}\n", "\\newcommand{\\latentForce}{f}\n", "\\newcommand{\\latentFunction}{u}\n", "\\newcommand{\\latentFunctionVector}{\\mathbf{ \\latentFunction}}\n", "\\newcommand{\\latentFunctionMatrix}{\\mathbf{ \\MakeUppercase{\\latentFunction}}}\n", "\\newcommand{\\latentIndex}{j}\n", "\\newcommand{\\latentScalar}{z}\n", "\\newcommand{\\latentVector}{\\mathbf{ \\latentScalar}}\n", "\\newcommand{\\latentMatrix}{\\mathbf{Z}}\n", "\\newcommand{\\learnRate}{\\eta}\n", "\\newcommand{\\lengthScale}{\\ell}\n", "\\newcommand{\\rbfWidth}{\\ell}\n", "\\newcommand{\\likelihoodBound}{\\mathcal{L}}\n", "\\newcommand{\\likelihoodFunction}{L}\n", "\\newcommand{\\locationScalar}{\\mu}\n", "\\newcommand{\\locationVector}{\\boldsymbol{ \\locationScalar}}\n", "\\newcommand{\\locationMatrix}{\\mathbf{M}}\n", "\\newcommand{\\variance}[1]{\\text{var}\\left( #1 \\right)}\n", "\\newcommand{\\mappingFunction}{f}\n", "\\newcommand{\\mappingFunctionMatrix}{\\mathbf{F}}\n", "\\newcommand{\\mappingFunctionTwo}{g}\n", "\\newcommand{\\mappingFunctionTwoMatrix}{\\mathbf{G}}\n", "\\newcommand{\\mappingFunctionTwoVector}{\\mathbf{ \\mappingFunctionTwo}}\n", "\\newcommand{\\mappingFunctionVector}{\\mathbf{ \\mappingFunction}}\n", "\\newcommand{\\scaleScalar}{s}\n", "\\newcommand{\\mappingScalar}{w}\n", "\\newcommand{\\mappingVector}{\\mathbf{ \\mappingScalar}}\n", "\\newcommand{\\mappingMatrix}{\\mathbf{W}}\n", "\\newcommand{\\mappingScalarTwo}{v}\n", "\\newcommand{\\mappingVectorTwo}{\\mathbf{ \\mappingScalarTwo}}\n", "\\newcommand{\\mappingMatrixTwo}{\\mathbf{V}}\n", "\\newcommand{\\maxIters}{K}\n", "\\newcommand{\\meanMatrix}{\\mathbf{M}}\n", "\\newcommand{\\meanScalar}{\\mu}\n", "\\newcommand{\\meanTwoMatrix}{\\mathbf{M}}\n", "\\newcommand{\\meanTwoScalar}{m}\n", "\\newcommand{\\meanTwoVector}{\\mathbf{ \\meanTwoScalar}}\n", "\\newcommand{\\meanVector}{\\boldsymbol{ \\meanScalar}}\n", "\\newcommand{\\mrnaConcentration}{m}\n", "\\newcommand{\\naturalFrequency}{\\omega}\n", "\\newcommand{\\neighborhood}[1]{\\mathcal{N}\\left( #1 \\right)}\n", "\\newcommand{\\neilurl}{http://inverseprobability.com/}\n", "\\newcommand{\\noiseMatrix}{\\boldsymbol{ E}}\n", "\\newcommand{\\noiseScalar}{\\epsilon}\n", "\\newcommand{\\noiseVector}{\\boldsymbol{ \\epsilon}}\n", "\\newcommand{\\norm}[1]{\\left\\Vert #1 \\right\\Vert}\n", "\\newcommand{\\normalizedLaplacianMatrix}{\\hat{\\mathbf{L}}}\n", "\\newcommand{\\normalizedLaplacianScalar}{\\hat{\\ell}}\n", "\\newcommand{\\normalizedLaplacianVector}{\\hat{\\mathbf{ \\ell}}}\n", "\\newcommand{\\numActive}{m}\n", "\\newcommand{\\numBasisFunc}{m}\n", "\\newcommand{\\numComponents}{m}\n", "\\newcommand{\\numComps}{K}\n", "\\newcommand{\\numData}{n}\n", "\\newcommand{\\numFeatures}{K}\n", "\\newcommand{\\numHidden}{h}\n", "\\newcommand{\\numInducing}{m}\n", "\\newcommand{\\numLayers}{\\ell}\n", "\\newcommand{\\numNeighbors}{K}\n", "\\newcommand{\\numSequences}{s}\n", "\\newcommand{\\numSuccess}{s}\n", "\\newcommand{\\numTasks}{m}\n", "\\newcommand{\\numTime}{T}\n", "\\newcommand{\\numTrials}{S}\n", "\\newcommand{\\outputIndex}{j}\n", "\\newcommand{\\paramVector}{\\boldsymbol{ \\theta}}\n", "\\newcommand{\\parameterMatrix}{\\boldsymbol{ \\Theta}}\n", "\\newcommand{\\parameterScalar}{\\theta}\n", "\\newcommand{\\parameterVector}{\\boldsymbol{ \\parameterScalar}}\n", "\\newcommand{\\partDiff}[2]{\\frac{\\partial#1}{\\partial#2}}\n", "\\newcommand{\\precisionScalar}{j}\n", "\\newcommand{\\precisionVector}{\\mathbf{ \\precisionScalar}}\n", "\\newcommand{\\precisionMatrix}{\\mathbf{J}}\n", "\\newcommand{\\pseudotargetScalar}{\\widetilde{y}}\n", "\\newcommand{\\pseudotargetVector}{\\mathbf{ \\pseudotargetScalar}}\n", "\\newcommand{\\pseudotargetMatrix}{\\mathbf{ \\widetilde{Y}}}\n", "\\newcommand{\\rank}[1]{\\text{rank}\\left(#1\\right)}\n", "\\newcommand{\\rayleighDist}[2]{\\mathcal{R}\\left(#1|#2\\right)}\n", "\\newcommand{\\rayleighSamp}[1]{\\mathcal{R}\\left(#1\\right)}\n", "\\newcommand{\\responsibility}{r}\n", "\\newcommand{\\rotationScalar}{r}\n", "\\newcommand{\\rotationVector}{\\mathbf{ \\rotationScalar}}\n", "\\newcommand{\\rotationMatrix}{\\mathbf{R}}\n", "\\newcommand{\\sampleCovScalar}{s}\n", "\\newcommand{\\sampleCovVector}{\\mathbf{ \\sampleCovScalar}}\n", "\\newcommand{\\sampleCovMatrix}{\\mathbf{s}}\n", "\\newcommand{\\scalarProduct}[2]{\\left\\langle{#1},{#2}\\right\\rangle}\n", "\\newcommand{\\sign}[1]{\\text{sign}\\left(#1\\right)}\n", "\\newcommand{\\sigmoid}[1]{\\sigma\\left(#1\\right)}\n", "\\newcommand{\\singularvalue}{\\ell}\n", "\\newcommand{\\singularvalueMatrix}{\\mathbf{L}}\n", "\\newcommand{\\singularvalueVector}{\\mathbf{l}}\n", "\\newcommand{\\sorth}{\\mathbf{u}}\n", "\\newcommand{\\spar}{\\lambda}\n", "\\newcommand{\\trace}[1]{\\text{tr}\\left(#1\\right)}\n", "\\newcommand{\\BasalRate}{B}\n", "\\newcommand{\\DampingCoefficient}{C}\n", "\\newcommand{\\DecayRate}{D}\n", "\\newcommand{\\Displacement}{X}\n", "\\newcommand{\\LatentForce}{F}\n", "\\newcommand{\\Mass}{M}\n", "\\newcommand{\\Sensitivity}{S}\n", "\\newcommand{\\basalRate}{b}\n", "\\newcommand{\\dampingCoefficient}{c}\n", "\\newcommand{\\mass}{m}\n", "\\newcommand{\\sensitivity}{s}\n", "\\newcommand{\\springScalar}{\\kappa}\n", "\\newcommand{\\springVector}{\\boldsymbol{ \\kappa}}\n", "\\newcommand{\\springMatrix}{\\boldsymbol{ \\mathcal{K}}}\n", "\\newcommand{\\tfConcentration}{p}\n", "\\newcommand{\\tfDecayRate}{\\delta}\n", "\\newcommand{\\tfMrnaConcentration}{f}\n", "\\newcommand{\\tfVector}{\\mathbf{ \\tfConcentration}}\n", "\\newcommand{\\velocity}{v}\n", "\\newcommand{\\sufficientStatsScalar}{g}\n", "\\newcommand{\\sufficientStatsVector}{\\mathbf{ \\sufficientStatsScalar}}\n", "\\newcommand{\\sufficientStatsMatrix}{\\mathbf{G}}\n", "\\newcommand{\\switchScalar}{s}\n", "\\newcommand{\\switchVector}{\\mathbf{ \\switchScalar}}\n", "\\newcommand{\\switchMatrix}{\\mathbf{S}}\n", "\\newcommand{\\tr}[1]{\\text{tr}\\left(#1\\right)}\n", "\\newcommand{\\loneNorm}[1]{\\left\\Vert #1 \\right\\Vert_1}\n", "\\newcommand{\\ltwoNorm}[1]{\\left\\Vert #1 \\right\\Vert_2}\n", "\\newcommand{\\onenorm}[1]{\\left\\vert#1\\right\\vert_1}\n", "\\newcommand{\\twonorm}[1]{\\left\\Vert #1 \\right\\Vert}\n", "\\newcommand{\\vScalar}{v}\n", "\\newcommand{\\vVector}{\\mathbf{v}}\n", "\\newcommand{\\vMatrix}{\\mathbf{V}}\n", "\\newcommand{\\varianceDist}[2]{\\text{var}_{#2}\\left( #1 \\right)}\n", "% Already defined by latex\n", "%\\newcommand{\\vec}{#1:}\n", "\\newcommand{\\vecb}[1]{\\left(#1\\right):}\n", "\\newcommand{\\weightScalar}{w}\n", "\\newcommand{\\weightVector}{\\mathbf{ \\weightScalar}}\n", "\\newcommand{\\weightMatrix}{\\mathbf{W}}\n", "\\newcommand{\\weightedAdjacencyMatrix}{\\mathbf{A}}\n", "\\newcommand{\\weightedAdjacencyScalar}{a}\n", "\\newcommand{\\weightedAdjacencyVector}{\\mathbf{ \\weightedAdjacencyScalar}}\n", "\\newcommand{\\onesVector}{\\mathbf{1}}\n", "\\newcommand{\\zerosVector}{\\mathbf{0}}\n", "$$\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "
\n", "\n", "\n", "\n", "
\n", "\n", "
\n", "The cosmic microwave background is, to a very high degree of\n", "precision, a Gaussian process. The parameters of its covariance function\n", "are given by fundamental parameters of the universe, such as the amount\n", "of dark matter and mass.\n", "
\n", "
\n", "\n", "$=f\\Bigg($$\\Bigg)$\n", "\n", "
\n", "\n", "
\n", "What we observe today is some non-linear function of the cosmic\n", "microwave background.\n", "
\n", "
\n", "Image credit: Kai Arulkumaran\n", "
\n", "Inference in a Gaussian process has computational complexity of\n", "$\\bigO(\\numData^3)$ and storage demands of $\\bigO(\\numData^2)$. This is\n", "too large for many modern data sets.\n", "\n", "Low rank approximations allow us to work with Gaussian processes with\n", "computational complexity of $\\bigO(\\numData\\numInducing^2)$ and storage\n", "demands of $\\bigO(\\numData\\numInducing)$, where $\\numInducing$ is a user\n", "chosen parameter.\n", "\n", "In machine learning, low rank approximations date back to\n", "@Smola:sparsegp00, @Williams:nystrom00, who considered the Nystr\"om\n", "approximation and @Csato:sparse02;@Csato:thesis02 who considered low\n", "rank approximations in the context of on-line learning. Selection of\n", "active points for the approximation was considered by @Seeger:fast03 and\n", "@Snelson:pseudo05 first proposed that the active set could be optimized\n", "directly. Those approaches were reviewed by @Quinonero:unifying05 under\n", "a unifying likelihood approximation perspective. General rules for\n", "deriving the maximum likelihood for these sparse approximations were\n", "given in @Lawrence:larger07.\n", "\n", "Modern variational interpretations of these low rank approaches were\n", "first explored in @Titsias:variational09. A more modern summary which\n", "considers each of these approximations as an $\\alpha$-divergence is\n", "given by @Thang:unifying17.\n", "\n", "### Variational Compression\n", "\n", "Inducing variables are a compression of the real observations. The basic\n", "idea is can I create a new data set that summarizes all the information\n", "in the original data set. If this data set is smaller, I've compressed\n", "the information in the original data set.\n", "\n", "Inducing variables can be thought of as pseudo-data, indeed in\n", "@Snelson:pseudo05 they were referred to as *pseudo-points*.\n", "\n", "The only requirement for inducing variables is that they are jointly\n", "distributed as a Gaussian process with the original data. This means\n", "that they can be from the space $\\mappingFunctionVector$ or a space that\n", "is related through a linear operator (see e.g. @Alvarez:efficient10).\n", "For example we could choose to store the gradient of the function at\n", "particular points or a value from the frequency spectrum of the function\n", "[@Lazaro:spectrum10].\n", "\n", "### Variational Compression II\n", "\n", "Inducing variables don't only allow for the compression of the\n", "non-parameteric information into a reduced data aset but they also allow\n", "for computational scaling of the algorithms through, for example\n", "stochastic variational approaches @Hensman:bigdata13 or parallelization\n", "@Gal:Distributed14,@Dai:gpu14, @Seeger:auto17.\n", "\n", "\n", "We’ve seen how we go from parametric to non-parametric. The limit\n", "implies infinite dimensional $\\mappingVector$. Gaussian processes are\n", "generally non-parametric: combine data with covariance function to get\n", "model. This representation *cannot* be summarized by a parameter vector\n", "of a fixed size.\n", "\n", "Parametric models have a representation that does not respond to\n", "increasing training set size. Bayesian posterior distributions over\n", "parameters contain the information about the training data, for example\n", "if we use use Bayes’ rule from training data, $$\n", "p\\left(\\mappingVector|\\dataVector, \\inputMatrix\\right),\n", "$$ to make predictions on test data $$\n", "p\\left(\\dataScalar_*|\\inputMatrix_*, \\dataVector, \\inputMatrix\\right) = \\int\n", " p\\left(\\dataScalar_*|\\mappingVector,\\inputMatrix_*\\right)p\\left(\\mappingVector|\\dataVector,\n", " \\inputMatrix)\\text{d}\\mappingVector\\right)\n", "$$ then $\\mappingVector$ becomes a bottleneck for information about the\n", "training set to pass to the test set. The solution is to increase\n", "$\\numBasisFunc$ so that the bottleneck is so large that it no longer\n", "presents a problem. How big is big enough for $\\numBasisFunc$?\n", "Non-parametrics says $\\numBasisFunc \\rightarrow \\infty$.\n", "\n", "Now no longer possible to manipulate the model through the standard\n", "parametric form. However, it *is* possible to express *parametric* as\n", "GPs: $$\n", "\\kernelScalar\\left(\\inputVector_i,\\inputVector_j\\right)=\\basisFunction_:\\left(\\inputVector_i\\right)^\\top\\basisFunction_:\\left(\\inputVector_j\\right).\n", "$$ These are known as degenerate covariance matrices. Their rank is at\n", "most $\\numBasisFunc$, non-parametric models have full rank covariance\n", "matrices. Most well known is the “linear kernel”, $$\n", "\\kernelScalar(\\inputVector_i, \\inputVector_j) = \\inputVector_i^\\top\\inputVector_j.\n", "$$ For non-parametrics prediction at a new point,\n", "$\\mappingFunctionVector_*$, is made by conditioning on\n", "$\\mappingFunctionVector$ in the joint distribution. In GPs this involves\n", "combining the training data with the covariance function and the mean\n", "function. Parametric is a special case when conditional prediction can\n", "be summarized in a *fixed* number of parameters. Complexity of\n", "parametric model remains fixed regardless of the size of our training\n", "data set. For a non-parametric model the required number of parameters\n", "grows with the size of the training data.\n", "\n", "### Augment Variable Space\n", "\n", "In inducing variable approximations, we augment the variable space with\n", "a set of inducing points, $\\inducingVector$. These inducing points are\n", "jointly Gaussian distributed with the points from our function,\n", "$\\mappingFunctionVector$. So we have a joint Gaussian process with\n", "covariance, $$\n", "\\begin{bmatrix}\n", "\\mappingFunctionVector\\\\\n", "\\inducingVector\n", "\\end{bmatrix} \\sim \\gaussianSamp{\\zerosVector}{\\kernelMatrix}\n", "$$ where the kernel matrix itself can be decomposed into $$\n", "\\kernelMatrix =\n", "\\begin{bmatrix}\n", "\\Kff & \\Kfu \\\\\n", "\\Kuf & \\Kuu\n", "\\end{bmatrix}\n", "$$\n", "\n", "This defines a joint density between the original function points,\n", "$\\mappingFunctionVector$ and our inducing points, $\\inducingVector$.\n", "This can be decomposed through the product rule to give. $$\n", "p(\\mappingFunctionVector, \\inducingVector) = p(\\mappingFunctionVector| \\inducingVector) p(\\inducingVector)\n", "$$ The Gaussian process is (typically) given by a noise corrupted form\n", "of $\\mappingFunctionVector$, i.e., $$\n", "\\dataScalar(\\inputVector) = \\mappingFunction(\\inputVector) + \\noiseScalar,\n", "$$ which can be written probabilisticlly as, $$\n", "p(\\dataVector) = \\int p(\\dataVector|\\mappingFunctionVector) p(\\mappingFunctionVector) \\text{d}\\mappingFunctionVector,\n", "$$ where for the independent case we have\n", "$p(\\dataVector | \\mappingFunctionVector) = \\prod_{i=1}^\\numData p(\\dataScalar_i|\\mappingFunction_i)$.\n", "\n", "Inducing variables are like auxilliary variables in Monte Carlo\n", "algorithms. We introduce the inducing variables by augmenting this\n", "integral with an additional integral over $\\inducingVector$, $$\n", "p(\\dataVector) = \\int p(\\dataVector|\\mappingFunctionVector) p(\\mappingFunctionVector|\\inducingVector) p(\\inducingVector) \\text{d}\\inducingVector \\text{d}\\mappingFunctionVector.\n", "$$ Now, conceptually speaking we are going to integrate out\n", "\\$\\mappingFunctionVector\\#, initially leaving \\$\\inducingVector in\n", "place. This gives, $$\n", "p(\\dataVector) = \\int p(\\dataVector|\\inducingVector) p(\\inducingVector) \\text{d}\\inducingVector.\n", "$$\n", "\n", "Note the similarity between this form and our standard *parametric*\n", "form. If we had defined our model through standard basis functions we\n", "would have, $$\n", "\\dataScalar(\\inputVector) = \\weightVector^\\top\\basisVector(\\inputVector) + \\noiseScalar\n", "$$ and the resulting probabilistic representation would be $$\n", "p(\\dataVector) = \\int p(\\dataVector|\\weightVector) p(\\weightVector) \\text{d} \\weightVector\n", "$$ allowing us to predict $$\n", "p(\\dataVector^*|\\dataVector) = \\int p(\\dataVector^*|\\weightVector) p(\\weightVector|\\dataVector) \\text{d} \\weightVector\n", "$$\n", "\n", "The new prediction algorithm involves $$\n", "p(\\dataVector^*|\\dataVector) = \\int p(\\dataVector^*|\\inducingVector) p(\\inducingVector|\\dataVector) \\text{d} \\inducingVector\n", "$$ but *importantly* the length of $\\inducingVector$ is not fixed at\n", "*design* time like the number of parameters were. We can vary the number\n", "of inducing variables we use to give us the model capacity we require.\n", "\n", "Unfortunately, computation of $p(\\dataVector|\\inducingVector)$ turns out\n", "to be intractable. As a result, we need to turn to approximations to\n", "make progress.\n", "\n", "### Variational Bound on $p(\\dataVector |\\inducingVector)$\n", "\n", "The conditional density of the data given the inducing points can be\n", "*lower* bounded variationally $$\n", "\\begin{aligned}\n", " \\log p(\\dataVector|\\inducingVector) & = \\log \\int p(\\dataVector|\\mappingFunctionVector) p(\\mappingFunctionVector|\\inducingVector) \\text{d}\\mappingFunctionVector\\\\ & = \\int q(\\mappingFunctionVector) \\log \\frac{p(\\dataVector|\\mappingFunctionVector) p(\\mappingFunctionVector|\\inducingVector)}{q(\\mappingFunctionVector)}\\text{d}\\mappingFunctionVector + \\KL{q(\\mappingFunctionVector)}{p(\\mappingFunctionVector|\\dataVector, \\inducingVector)}.\n", "\\end{aligned}\n", "$$\n", "\n", "The key innovation from @Titsias:variational09 was to then make a\n", "particular choice for $q(\\mappingFunctionVector)$. If we set\n", "$q(\\mappingFunctionVector)=p(\\mappingFunctionVector|\\inducingVector)$,\n", "$$\n", " \\log p(\\dataVector|\\inducingVector) \\geq \\log \\int p(\\mappingFunctionVector|\\inducingVector) \\log p(\\dataVector|\\mappingFunctionVector)\\text{d}\\mappingFunctionVector.\n", " $$ $$\n", " p(\\dataVector|\\inducingVector) \\geq \\exp \\int p(\\mappingFunctionVector|\\inducingVector) \\log p(\\dataVector|\\mappingFunctionVector)\\text{d}\\mappingFunctionVector.\n", " $$\n", "\n", "### Optimal Compression in Inducing Variables\n", "\n", "Maximizing the lower bound minimizes the Kullback-Leibler divergence (or\n", "*information gain*) between our approximating density,\n", "$p(\\mappingFunctionVector|\\inducingVector)$ and the true posterior\n", "density, $p(\\mappingFunctionVector|\\dataVector, \\inducingVector)$.\n", "\n", "$$\n", " \\KL{p(\\mappingFunctionVector|\\inducingVector)}{p(\\mappingFunctionVector|\\dataVector, \\inducingVector)} = \\int p(\\mappingFunctionVector|\\inducingVector) \\log \\frac{p(\\mappingFunctionVector|\\inducingVector)}{p(\\mappingFunctionVector|\\dataVector, \\inducingVector)}\\text{d}\\inducingVector\n", " $$\n", "\n", "This bound is minimized when the information stored about $\\dataVector$\n", "is already stored in $\\inducingVector$. In other words, maximizing the\n", "bound seeks an *optimal compression* from the *information gain*\n", "perspective.\n", "\n", "For the case where $\\inducingVector = \\mappingFunctionVector$ the bound\n", "is exact ($\\mappingFunctionVector$ $d$-separates $\\dataVector$ from\n", "$\\inducingVector$).\n", "\n", "### Choice of Inducing Variables\n", "\n", "The quality of the resulting bound is determined by the choice of the\n", "inducing variables. You are free to choose whichever heuristics you like\n", "for the inducing variables, as long as they are drawn jointly from a\n", "valid Gaussian process, i.e. such that $$\n", "\\begin{bmatrix}\n", "\\mappingFunctionVector\\\\\n", "\\inducingVector\n", "\\end{bmatrix} \\sim \\gaussianSamp{\\zerosVector}{\\kernelMatrix}\n", "$$ where the kernel matrix itself can be decomposed into $$\n", "\\kernelMatrix =\n", "\\begin{bmatrix}\n", "\\Kff & \\Kfu \\\\\n", "\\Kuf & \\Kuu\n", "\\end{bmatrix}\n", "$$ Choosing the inducing variables amounts to specifying $\\Kfu$ and\n", "$\\Kuu$ such that $\\kernelMatrix$ remains positive definite. The typical\n", "choice is to choose $\\inducingVector$ in the same domain as\n", "$\\mappingFunctionVector$, associating each inducing output,\n", "$\\inducingScalar_i$ with a corresponding input location\n", "$\\inducingInputVector$. However, more imaginative choices are absolutely\n", "possible. In particular, if $\\inducingVector$ is related to\n", "$\\mappingFunctionVector$ through a linear operator (see e.g.\n", "@Alvarez:efficient10), then valid $\\Kuu$ and $\\Kuf$ can be constructed.\n", "For example we could choose to store the gradient of the function at\n", "particular points or a value from the frequency spectrum of the function\n", "[@Lazaro:spectrum10].\n", "\n", "### Variational Compression II\n", "\n", "Inducing variables don't only allow for the compression of the\n", "non-parameteric information into a reduced data set but they also allow\n", "for computational scaling of the algorithms through, for example\n", "stochastic variational\n", "approaches[@Hoffman:stochastic12; @Hensman:bigdata13] or parallelization\n", "@Gal:Distributed14,@Dai:gpu14, @Seeger:auto17.\n", "\n", "\n", "### A Simple Regression Problem\n", "\n", "Here we set up a simple one dimensional regression problem. The input\n", "locations, $\\inputMatrix$, are in two separate clusters. The response\n", "variable, $\\dataVector$, is sampled from a Gaussian process with an\n", "exponentiated quadratic covariance." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import GPy" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "np.random.seed(101)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "N = 50\n", "noise_var = 0.01\n", "X = np.zeros((50, 1))\n", "X[:25, :] = np.linspace(0,3,25)[:,None] # First cluster of inputs/covariates\n", "X[25:, :] = np.linspace(7,10,25)[:,None] # Second cluster of inputs/covariates\n", "\n", "# Sample response variables from a Gaussian process with exponentiated quadratic covariance.\n", "k = GPy.kern.RBF(1)\n", "y = np.random.multivariate_normal(np.zeros(N),k.K(X)+np.eye(N)*np.sqrt(noise_var)).reshape(-1,1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "First we perform a full Gaussian process regression on the data. We\n", "create a GP model, `m_full`, and fit it to the data, plotting the\n", "resulting fit." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "m_full = GPy.models.GPRegression(X,y)\n", "_ = m_full.optimize(messages=True) # Optimize parameters of covariance function" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import matplotlib.pyplot as plt\n", "import mlai\n", "import teaching_plots as plot \n", "from gp_tutorial import gpplot" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "fig, ax = plt.subplots(figsize=plot.big_wide_figsize)\n", "plot.model_output(m_full, ax=ax, xlabel='$x$', ylabel='$y$', fontsize=20, portion=0.2)\n", "xlim = ax.get_xlim()\n", "ylim = ax.get_ylim()\n", "mlai.write_figure(figure=fig,\n", " filename='../slides/diagrams/gp/sparse-demo-full-gp.svg', \n", " transparent=True, frameon=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "
\n", "Full Gaussian process fitted to the data set.\n", "
\n", "Now we set up the inducing variables, $\\mathbf{u}$. Each inducing\n", "variable has its own associated input index, $\\mathbf{Z}$, which lives\n", "in the same space as $\\inputMatrix$. Here we are using the true\n", "covariance function parameters to generate the fit." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "kern = GPy.kern.RBF(1)\n", "Z = np.hstack(\n", " (np.linspace(2.5,4.,3),\n", " np.linspace(7,8.5,3)))[:,None]\n", "m = GPy.models.SparseGPRegression(X,y,kernel=kern,Z=Z)\n", "m.noise_var = noise_var\n", "m.inducing_inputs.constrain_fixed()\n", "display(m)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "fig, ax = plt.subplots(figsize=plot.big_wide_figsize)\n", "plot.model_output(m, ax=ax, xlabel='$x$', ylabel='$y$', fontsize=20, portion=0.2, xlim=xlim, ylim=ylim)\n", "mlai.write_figure(figure=fig,\n", " filename='../slides/diagrams/gp/sparse-demo-constrained-inducing-6-unlearned-gp.svg', \n", " transparent=True, frameon=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "
\n", "Sparse Gaussian process fitted with six inducing variables, no\n", "optimization of parameters or inducing variables.\n", "
" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "_ = m.optimize(messages=True)\n", "display(m)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "fig, ax = plt.subplots(figsize=plot.big_wide_figsize)\n", "plot.model_output(m, ax=ax, xlabel='$x$', ylabel='$y$', fontsize=20, portion=0.2, xlim=xlim, ylim=ylim)\n", "mlai.write_figure(figure=fig,\n", " filename='../slides/diagrams/gp/sparse-demo-constrained-inducing-6-learned-gp.svg', \n", " transparent=True, frameon=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "
\n", "Gaussian process fitted with inducing variables fixed and parameters\n", "optimized\n", "
" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "m.randomize()\n", "m.inducing_inputs.unconstrain()\n", "_ = m.optimize(messages=True)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "fig, ax = plt.subplots(figsize=plot.big_wide_figsize)\n", "plot.model_output(m, ax=ax, xlabel='$x$', ylabel='$y$', fontsize=20, portion=0.2,xlim=xlim, ylim=ylim)\n", "mlai.write_figure(figure=fig,\n", " filename='../slides/diagrams/gp/sparse-demo-unconstrained-inducing-6-gp.svg', \n", " transparent=True, frameon=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "
\n", "Gaussian process fitted with location of inducing variables and\n", "parameters both optimized\n", "
\n", "Now we will vary the number of inducing points used to form the\n", "approximation." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "m.num_inducing=8\n", "m.randomize()\n", "M = 8\n", "m.set_Z(np.random.rand(M,1)*12)\n", "\n", "_ = m.optimize(messages=True)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "fig, ax = plt.subplots(figsize=plot.big_wide_figsize)\n", "plot.model_output(m, ax=ax, xlabel='$x$', ylabel='$y$', fontsize=20, portion=0.2, xlim=xlim, ylim=ylim)\n", "mlai.write_figure(figure=fig,\n", " filename='../slides/diagrams/gp/sparse-demo-sparse-inducing-8-gp.svg', \n", " transparent=True, frameon=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "Comparison of the full Gaussian process fit with a sparse Gaussian\n", "process using eight inducing varibles. Both inducing variables and\n", "parameters are optimized.\n", "
\n", "And we can compare the probability of the result to the full model." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "print(m.log_likelihood(), m_full.log_likelihood())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Let’s be explicity about storing approximate posterior of\n", " $\\inducingVector$, $q(\\inducingVector)$.\n", "- Now we have\n", " $$p(\\dataVector^*|\\dataVector) = \\int p(\\dataVector^*| \\inducingVector) q(\\inducingVector | \\dataVector) \\text{d} \\inducingVector$$\n", "\n", "- Inducing variables look a lot like regular parameters.\n", "- *But*: their dimensionality does not need to be set at design time.\n", "- They can be modified arbitrarily at run time without effecting the\n", " model likelihood.\n", "- They only effect the quality of compression and the lower bound.\n", "\n", "- Exploit the resulting factorization ...\n", " $$p(\\dataVector^*|\\dataVector) = \\int p(\\dataVector^*| \\inducingVector) q(\\inducingVector | \\dataVector) \\text{d} \\inducingVector$$\n", " \\pause\n", "- The distribution now *factorizes*:\n", " $$p(\\dataVector^*|\\dataVector) = \\int \\prod_{i=1}^{\\numData^*}p(\\dataScalar^*_i| \\inducingVector) q(\\inducingVector | \\dataVector) \\text{d} \\inducingVector$$\n", "- This factorization can be exploited for stochastic variational\n", " inference [@Hoffman:stochastic12].\n", "\n", "
\n", "Modern data availability\n", "
\n", "
\n", "\n", "\n", "\n", "
\n", "\n", "
\n", "Proxy for index of deprivation?\n", "
\n", "
\n", "\n", "\n", "\n", "
\n", "\n", "
\n", "Actually index of deprivation is a proxy for this ...\n", "
\n", "
\n", "\n", "\n", "\n", "
\n", "\n", "\\catdoc\n", "\n", "\n", "\n", "\n", "\n", "\n", "
\n", "[[@Hensman:bigdata13]]{style=\"text-align:left\"}\n", "\n", "[]{style=\"text-align:right\"}\n", "
\n", "
\n", "\n", "\n", "\n", "
\n", "\n", "
\n", "\n", "
\n", "\n", "\n", "\n", "\n", "\n", "
\n", "[[@Hensman:bigdata13]]{style=\"text-align:left\"}\n", "\n", "[]{style=\"text-align:right\"}\n", "
\n", "
\n", "\n", "\n", "\n", "
\n", "\n", "
\n", "\n", "
\n", "- *A Unifying Framework for Gaussian Process Pseudo-Point\n", " Approximations using Power Expectation Propagation*\n", " @Thang:unifying17\n", "\n", "- *Deep Gaussian Processes and Variational Propagation of Uncertainty*\n", " @Damianou:thesis2015\n", "\n", "Even in the early days of Gaussian processes in machine learning, it was\n", "understood that we were throwing something fundamental away. This is\n", "perhaps captured best by David MacKay in his 1997 NeurIPS tutorial on\n", "Gaussian processes, where he asked \"Have we thrown out the baby with the\n", "bathwater?\". The quote below is from his summarization paper.\n", "\n", "> According to the hype of 1987, neural networks were meant to be\n", "> intelligent models which discovered features and patterns in data.\n", "> Gaussian processes in contrast are simply smoothing devices. How can\n", "> Gaussian processes possibly repalce neural networks? What is going on?\n", ">\n", "> @MacKay:gpintroduction98\n", "\n", "bathwater?” [Published as @MacKay:gpintroduction98]}" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import teaching_plots as plot" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "A deep neural network. Input nodes are shown at the bottom. Each\n", "hidden layer is the result of applying an affine transformation to the\n", "previous layer and placing through an activation function.\n", "
\n", "Mathematically, each layer of a neural network is given through\n", "computing the activation function, $\\basisFunction(\\cdot)$, contingent\n", "on the previous layer, or the inputs. In this way the activation\n", "functions, are composed to generate more complex interactions than would\n", "be possible with any single layer. $$\n", "\\begin{align}\n", " \\hiddenVector_{1} &= \\basisFunction\\left(\\mappingMatrix_1 \\inputVector\\right)\\\\\n", " \\hiddenVector_{2} &= \\basisFunction\\left(\\mappingMatrix_2\\hiddenVector_{1}\\right)\\\\\n", " \\hiddenVector_{3} &= \\basisFunction\\left(\\mappingMatrix_3 \\hiddenVector_{2}\\right)\\\\\n", " \\dataVector &= \\mappingVector_4 ^\\top\\hiddenVector_{3}\n", "\\end{align}\n", "$$\n", "\n", "### Overfitting\n", "\n", "One potential problem is that as the number of nodes in two adjacent\n", "layers increases, the number of parameters in the affine transformation\n", "between layers, $\\mappingMatrix$, increases. If there are $k_{i-1}$\n", "nodes in one layer, and $k_i$ nodes in the following, then that matrix\n", "contains $k_i k_{i-1}$ parameters, when we have layer widths in the\n", "1000s that leads to millions of parameters.\n", "\n", "One proposed solution is known as *dropout* where only a sub-set of the\n", "neural network is trained at each iteration. An alternative solution\n", "would be to reparameterize $\\mappingMatrix$ with its *singular value\n", "decomposition*. $$\n", " \\mappingMatrix = \\eigenvectorMatrix\\eigenvalueMatrix\\eigenvectwoMatrix^\\top\n", " $$ or $$\n", " \\mappingMatrix = \\eigenvectorMatrix\\eigenvectwoMatrix^\\top\n", " $$ where if $\\mappingMatrix \\in \\Re^{k_1\\times k_2}$ then\n", "$\\eigenvectorMatrix\\in \\Re^{k_1\\times q}$ and\n", "$\\eigenvectwoMatrix \\in \\Re^{k_2\\times q}$, i.e. we have a low rank\n", "matrix factorization for the weights." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import teaching_plots as plot" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "
\n", "Pictorial representation of the low rank form of the matrix\n", "$\\mappingMatrix$\n", "
" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import teaching_plots as plot" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Including the low rank decomposition of $\\mappingMatrix$ in the neural\n", "network, we obtain a new mathematical form. Effectively, we are adding\n", "additional *latent* layers, $\\latentVector$, in between each of the\n", "existing hidden layers. In a neural network these are sometimes known as\n", "*bottleneck* layers. The network can now be written mathematically as $$\n", "\\begin{align}\n", " \\latentVector_{1} &= \\eigenvectwoMatrix^\\top_1 \\inputVector\\\\\n", " \\hiddenVector_{1} &= \\basisFunction\\left(\\eigenvectorMatrix_1 \\latentVector_{1}\\right)\\\\\n", " \\latentVector_{2} &= \\eigenvectwoMatrix^\\top_2 \\hiddenVector_{1}\\\\\n", " \\hiddenVector_{2} &= \\basisFunction\\left(\\eigenvectorMatrix_2 \\latentVector_{2}\\right)\\\\\n", " \\latentVector_{3} &= \\eigenvectwoMatrix^\\top_3 \\hiddenVector_{2}\\\\\n", " \\hiddenVector_{3} &= \\basisFunction\\left(\\eigenvectorMatrix_3 \\latentVector_{3}\\right)\\\\\n", " \\dataVector &= \\mappingVector_4^\\top\\hiddenVector_{3}.\n", "\\end{align}\n", "$$\n", "\n", "$$\n", "\\begin{align}\n", " \\latentVector_{1} &= \\eigenvectwoMatrix^\\top_1 \\inputVector\\\\\n", " \\latentVector_{2} &= \\eigenvectwoMatrix^\\top_2 \\basisFunction\\left(\\eigenvectorMatrix_1 \\latentVector_{1}\\right)\\\\\n", " \\latentVector_{3} &= \\eigenvectwoMatrix^\\top_3 \\basisFunction\\left(\\eigenvectorMatrix_2 \\latentVector_{2}\\right)\\\\\n", " \\dataVector &= \\mappingVector_4 ^\\top \\latentVector_{3}\n", "\\end{align}\n", "$$\n", "\n", "Now if we replace each of these neural networks with a Gaussian process.\n", "This is equivalent to taking the limit as the width of each layer goes\n", "to infinity, while appropriately scaling down the outputs.\n", "\n", "$$\n", "\\begin{align}\n", " \\latentVector_{1} &= \\mappingFunctionVector_1\\left(\\inputVector\\right)\\\\\n", " \\latentVector_{2} &= \\mappingFunctionVector_2\\left(\\latentVector_{1}\\right)\\\\\n", " \\latentVector_{3} &= \\mappingFunctionVector_3\\left(\\latentVector_{2}\\right)\\\\\n", " \\dataVector &= \\mappingFunctionVector_4\\left(\\latentVector_{3}\\right)\n", "\\end{align}\n", "$$\n", "\n", "
\n", "\n", "\n", "\n", "
\n", "\n", "
\n", "The DeepFace architecture [@Taigman:deepface14], visualized through\n", "colors to represent the functional mappings at each layer. There are 120\n", "million parameters in the model.\n", "
\n", "The DeepFace architecture [@Taigman:deepface14] consists of layers that\n", "deal with *translation* and *rotational* invariances. These layers are\n", "followed by three locally-connected layers and two fully-connected\n", "layers. Color illustrates feature maps produced at each layer. The net\n", "includes more than 120 million parameters, where more than 95% come from\n", "the local and fully connected layers.\n", "\n", "
\n", "\n", "\n", "\n", "
\n", "\n", "
\n", "Deep learning models are composition of simple functions. We can\n", "think of a pinball machine as an analogy. Each layer of pins corresponds\n", "to one of the layers of functions in the model. Input data is\n", "represented by the location of the ball from left to right when it is\n", "dropped in from the top. Output class comes from the position of the\n", "ball as it leaves the pins at the bottom.\n", "
\n", "We can think of what these models are doing as being similar to early\n", "pin ball machines. In a neural network, we input a number (or numbers),\n", "whereas in pinball, we input a ball. The location of the ball on the\n", "left-right axis can be thought of as the number. As the ball falls\n", "through the machine, each layer of pins can be thought of as a different\n", "layer of neurons. Each layer acts to move the ball from left to right.\n", "\n", "In a pinball machine, when the ball gets to the bottom it might fall\n", "into a hole defining a score, in a neural network, that is equivalent to\n", "the decision: a classification of the input object.\n", "\n", "An image has more than one number associated with it, so it's like\n", "playing pinball in a *hyper-space*." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import pods\n", "from ipywidgets import IntSlider" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "pods.notebook.display_plots('pinball{sample:0>3}.svg', \n", " '../slides/diagrams', \n", " sample=IntSlider(1, 1, 2, 1))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "\n", "\n", "\n", "
\n", "\n", "
\n", "At initialization, the pins, which represent the parameters of the\n", "function, aren't in the right place to bring the balls to the correct\n", "decisions.\n", "
\n", "
\n", "\n", "\n", "\n", "
\n", "\n", "
\n", "After learning the pins are now in the right place to bring the balls\n", "to the correct decisions.\n", "
\n", "Learning involves moving all the pins to be in the right position, so\n", "that the ball falls in the right place. But moving all these pins in\n", "hyperspace can be difficult. In a hyper space you have to put a lot of\n", "data through the machine for to explore the positions of all the pins.\n", "Adversarial learning reflects the fact that a ball can be moved a small\n", "distance and lead to a very different result.\n", "\n", "Probabilistic methods explore more of the space by considering a range\n", "of possible paths for the ball through the machine.\n", "\n", "Mathematically, a deep Gaussian process can be seen as a composite\n", "*multivariate* function, $$\n", " \\mathbf{g}(\\inputVector)=\\mappingFunctionVector_5(\\mappingFunctionVector_4(\\mappingFunctionVector_3(\\mappingFunctionVector_2(\\mappingFunctionVector_1(\\inputVector))))).\n", " $$ Or if we view it from the probabilistic perspective we can see that\n", "a deep Gaussian process is specifying a factorization of the joint\n", "density, the standard deep model takes the form of a Markov chain." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from matplotlib import rc\n", "\n", "rc(\"font\", **{'family':'sans-serif','sans-serif':['Helvetica'],'size':30})\n", "rc(\"text\", usetex=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "$$\n", " p(\\dataVector|\\inputVector)= p(\\dataVector|\\mappingFunctionVector_5)p(\\mappingFunctionVector_5|\\mappingFunctionVector_4)p(\\mappingFunctionVector_4|\\mappingFunctionVector_3)p(\\mappingFunctionVector_3|\\mappingFunctionVector_2)p(\\mappingFunctionVector_2|\\mappingFunctionVector_1)p(\\mappingFunctionVector_1|\\inputVector)\n", " $$\n", "\n", "\n", "
\n", "Probabilistically the deep Gaussian process can be represented as a\n", "Markov chain.\n", "
" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from matplotlib import rc\n", "rc(\"font\", **{'family':'sans-serif','sans-serif':['Helvetica'], 'size':15})\n", "rc(\"text\", usetex=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "### Why Deep?\n", "\n", "If the result of composing many functions together is simply another\n", "function, then why do we bother? The key point is that we can change the\n", "class of functions we are modeling by composing in this manner. A\n", "Gaussian process is specifying a prior over functions, and one with a\n", "number of elegant properties. For example, the derivative process (if it\n", "exists) of a Gaussian process is also Gaussian distributed. That makes\n", "it easy to assimilate, for example, derivative observations. But that\n", "also might raise some alarm bells. That implies that the *marginal\n", "derivative distribution* is also Gaussian distributed. If that's the\n", "case, then it means that functions which occasionally exhibit very large\n", "derivatives are hard to model with a Gaussian process. For example, a\n", "function with jumps in.\n", "\n", "A one off discontinuity is easy to model with a Gaussian process, or\n", "even multiple discontinuities. They can be introduced in the mean\n", "function, or independence can be forced between two covariance functions\n", "that apply in different areas of the input space. But in these cases we\n", "will need to specify the number of discontinuities and where they occur.\n", "In otherwords we need to *parameterise* the discontinuities. If we do\n", "not know the number of discontinuities and don't wish to specify where\n", "they occur, i.e. if we want a non-parametric representation of\n", "discontinuities, then the standard Gaussian process doesn't help.\n", "\n", "### Stochastic Process Composition\n", "\n", "The deep Gaussian process leads to *non-Gaussian* models, and\n", "non-Gaussian characteristics in the covariance function. In effect, what\n", "we are proposing is that we change the properties of the functions we\n", "are considering by \\*composing stochastic processes\\$. This is an\n", "approach to creating new stochastic processes from well known processes.\n", "\n", "\n", "\n", "Additionally, we are not constrained to the formalism of the chain. For\n", "example, we can easily add single nodes emerging from some point in the\n", "depth of the chain. This allows us to combine the benefits of the\n", "graphical modelling formalism, but with a powerful framework for\n", "relating one set of variables to another, that of Gaussian processes\n", "\n", "\n", "### Difficulty for Probabilistic Approaches\n", "\n", "The challenge for composition of probabilistic models is that you need\n", "to propagate a probability densities through non linear mappings. This\n", "allows you to create broader classes of probability density.\n", "Unfortunately it renders the resulting densities *intractable*.\n", "\n", "\n", "\n", "\n", "\n", "\n", "The argument in the deep learning revolution is that deep architectures\n", "allow us to develop an abstraction of the feature set through model\n", "composition. Composing Gaussian processes is analytically intractable.\n", "To form deep Gaussian processes we use a variational approach to stack\n", "the models." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import pods" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "pods.notebook.display_plots('stack-gp-sample-Linear-{sample:0>1}.svg', \n", " directory='../../slides/diagrams/deepgp', sample=(0,4))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Stacked PCA\n", "\n", "
\n", "Composition of linear functions just leads to a new linear\n", "function.\n", "
\n", "Stacking a series of linear functions simply leads to a new linear\n", "function. The use of multiple linear function merely changes the\n", "covariance of the resulting Gaussian. If $$\n", "\\latentMatrix \\sim \\gaussianSamp{\\zerosVector}{\\eye}\n", "$$ and the $i$th hidden layer is a multivariate linear transformation\n", "defined by $\\weightMatrix_i$, $$\n", "\\dataMatrix = \\latentMatrix\\weightMatrix_1 \\weightMatrix_2 \\dots \\weightMatrix_\\numLayers\n", "$$ then the rules of multivariate Gaussians tell us that $$\n", "\\dataMatrix \\sim \\gaussianSamp{\\zerosVector}{\\weightMatrix_\\numLayers \\dots \\weightMatrix_1 \\weightMatrix^\\top_1 \\dots \\weightMatrix^\\top_\\numLayers}.\n", "$$ So the model can be replaced by one where we set\n", "$\\vMatrix = \\weightMatrix_\\numLayers \\dots \\weightMatrix_2 \\weightMatrix_1$.\n", "So is such a model trivial? The answer is that it depends. There are two\n", "cases in which such a model remaisn interesting. Firstly, if we make\n", "intermediate observations stemming from the chain. So, for example, if\n", "we decide that, $$\n", "\\latentMatrix_i = \\weightMatrix_i \\latentMatrix_{i-1}\n", "$$ and set\n", "$\\latentMatrix_{0} = \\inputMatrix \\sim \\gaussianSamp{\\zerosVector}{\\eye}$,\n", "then the matrices $\\weightMatrix$ inter-relate a series of jointly\n", "Gaussian observations in an interesting way, stacking the full data\n", "matrix to give $$\n", "\\latentMatrix = \\begin{bmatrix}\n", "\\latentMatrix_0 \\\\\n", "\\latentMatrix_1 \\\\\n", "\\vdots \\\\\n", "\\latentMatrix_\\numLayers\n", "\\end{bmatrix}\n", "$$ we can obtain\n", "$$\\latentMatrix \\sim \\gaussianSamp{\\zerosVector}{\\begin{bmatrix}\n", "\\eye & \\weightMatrix^\\top_1 & \\weightMatrix_1^\\top\\weightMatrix_2^\\top & \\dots & \\vMatrix^\\top \\\\\n", "\\weightMatrix_1 & \\weightMatrix_1 \\weightMatrix_1^\\top & \\weightMatrix_1 \\weightMatrix_1^\\top \\weightMatrix_2^\\top & \\dots & \\weightMatrix_1 \\vMatrix^\\top \\\\\n", "\\weightMatrix_2 \\weightMatrix_1 & \\weightMatrix_2 \\weightMatrix_1 \\weightMatrix_1^\\top & \\weightMatrix_2 \\weightMatrix_1 \\weightMatrix_1^\\top \\weightMatrix_2^\\top & \\dots & \\weightMatrix_2 \\weightMatrix_1 \\vMatrix^\\top \\\\\n", "\\vdots & \\vdots & \\vdots & \\ddots & \\vdots \\\\\n", "\\vMatrix & \\vMatrix \\weightMatrix_1^\\top & \\vMatrix \\weightMatrix_1^\\top \\weightMatrix_2^\\top& \\dots & \\vMatrix\\vMatrix^\\top\n", "\\end{bmatrix}}$$ which is a highly structured Gaussian covariance with\n", "hierarchical dependencies between the variables $\\latentMatrix_i$.\n", "\n", "### Stacked GP" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "pods.notebook.display_plots('stack-gp-sample-RBF-{sample:0>1}.svg', \n", " directory='../../slides/diagrams/deepgp', sample=(0,4))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "Stacking Gaussian process models leads to non linear mappings at each\n", "stage. Here we are mapping from two dimensions to two dimensions in each\n", "layer.\n", "
\n", "Note that once the box has folded over on itself, it cannot be unfolded.\n", "So a feature that is generated near the top of the model cannot be\n", "removed furthr down the model.\n", "\n", "This folding over effect happens in low dimensions. In higher dimensions\n", "it is less common.\n", "\n", "Observation of this effect at a talk in Cambridge was one of the things\n", "that caused David Duvenaud (and collaborators) to consider the behavior\n", "of deeper Gaussian process models [@Duvenaud:pathologies14].\n", "\n", "Such folding over in the latent spaces necessarily forces the density to\n", "be non-Gaussian. Indeed, since folding-over is avoided as we increase\n", "the dimensionality of the latent spaces, such processes become more\n", "Gaussian. If we take the limit of the latent space dimensionality as it\n", "tends to infinity, the entire deep Gaussian process returns to a\n", "standard Gaussian process, with a covariance function given as a deep\n", "kernel (such as those described by @Cho:deep09).\n", "\n", "Further analysis of these deep networks has been conducted by\n", "@Dunlop:deep2017, who use analysis of the deep network's stationary\n", "density (treating it as a Markov chain across layers), to explore the\n", "nature of the implied process prior for a deep GP.\n", "\n", "Both of these works, however, make constraining assumptions on the form\n", "of the Gaussian process prior at each layer (e.g. same covariance at\n", "each layer). In practice, the form of this covariance can be learnt and\n", "the densities described by the deep GP are more general than those\n", "mentioned in either of these papers." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from IPython.lib.display import YouTubeVideo\n", "YouTubeVideo('XhIvygQYFFQ')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "David Duvenaud also created a YouTube video to help visualize what\n", "happens as you drop through the layers of a deep GP.\n", "\n", "### GPy: A Gaussian Process Framework in Python\n", "\n", "
\n", "\n", "\n", "\n", "
\n", "\n", "GPy is a BSD licensed software code base for implementing Gaussian\n", "process models in python. This allows GPs to be combined with a wide\n", "variety of software libraries.\n", "\n", "The software itself is avaialble on\n", "[GitHub](https://github.com/SheffieldML/GPy) and the team welcomes\n", "contributions.\n", "\n", "The aim for GPy is to be a probabilistic-style programming language,\n", "i.e. you specify the model rather than the algorithm. As well as a large\n", "range of covariance functions the software allows for non-Gaussian\n", "likelihoods, multivariate outputs, dimensionality reduction and\n", "approximations for larger data sets.\n", "\n", "The GPy library can be installed via pip:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "pip install GPy" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This notebook depends on PyDeepGP. These libraries can be installed via\n", "pip:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "pip install git+https://github.com/SheffieldML/PyDeepGP.git" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Olympic Marathon Data\n", "\n", "\n", "\n", "\n", "\n", "\n", "
\n", "- Gold medal times for Olympic Marathon since 1896.\n", "- Marathons before 1924 didn’t have a standardised distance.\n", "- Present results using pace per km.\n", "- In 1904 Marathon was badly organised leading to very slow times.\n", "\n", "\n", "
\n", "\n", "\n", "\n", "
\n", "\n", "Image from Wikimedia Commons \n", "
\n", "The first thing we will do is load a standard data set for regression\n", "modelling. The data consists of the pace of Olympic Gold Medal Marathon\n", "winners for the Olympics from 1896 to present. First we load in the data\n", "and plot." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import pods" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "data = pods.datasets.olympic_marathon_men()\n", "x = data['X']\n", "y = data['Y']\n", "\n", "offset = y.mean()\n", "scale = np.sqrt(y.var())" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import matplotlib.pyplot as plt\n", "import teaching_plots as plot\n", "import mlai" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "\n", "xlim = (1875,2030)\n", "ylim = (2.5, 6.5)\n", "yhat = (y-offset)/scale\n", "\n", "fig, ax = plt.subplots(figsize=plot.big_wide_figsize)\n", "_ = ax.plot(x, y, 'r.',markersize=10)\n", "ax.set_xlabel('year', fontsize=20)\n", "ax.set_ylabel('pace min/km', fontsize=20)\n", "ax.set_xlim(xlim)\n", "ax.set_ylim(ylim)\n", "\n", "mlai.write_figure(figure=fig, \n", " filename='../slides/diagrams/datasets/olympic-marathon.svg', \n", " transparent=True, \n", " frameon=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "\n", "\n", "\n", "
\n", "\n", "Things to notice about the data include the outlier in 1904, in this\n", "year, the olympics was in St Louis, USA. Organizational problems and\n", "challenges with dust kicked up by the cars following the race meant that\n", "participants got lost, and only very few participants completed.\n", "\n", "More recent years see more consistently quick marathons.\n", "\n", "Data is fine for answering very specific questions, like \"Who won the\n", "Olympic Marathon in 2012?\", because we have that answer stored, however,\n", "we are not given the answer to many other questions. For example, Alan\n", "Turing was a formidable marathon runner, in 1946 he ran a time 2 hours\n", "46 minutes (just under four minutes per kilometer, faster than I and\n", "most of the other [Endcliffe Park\n", "Run](http://www.parkrun.org.uk/sheffieldhallam/) runners can do 5 km).\n", "What is the probability he would have won an Olympics if one had been\n", "held in 1946?\n", "\n", "\n", "\n", "\n", "\n", "\n", "
\n", "\n", "\n", "\n", "
\n", "
\n", "Alan Turing, in 1946 he was only 11 minutes slower than the winner of\n", "the 1948 games. Would he have won a hypothetical games held in 1946?\n", "Source: [Alan Turing Internet\n", "Scrapbook](http://www.turing.org.uk/scrapbook/run.html)\n", "
\n", "Our first objective will be to perform a Gaussian process fit to the\n", "data, we'll do this using the [GPy\n", "software](https://github.com/SheffieldML/GPy)." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import GPy" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "m_full = GPy.models.GPRegression(x,yhat)\n", "_ = m_full.optimize() # Optimize parameters of covariance function" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The first command sets up the model, then `m_full.optimize()` optimizes\n", "the parameters of the covariance function and the noise level of the\n", "model. Once the fit is complete, we'll try creating some test points,\n", "and computing the output of the GP model in terms of the mean and\n", "standard deviation of the posterior functions between 1870 and 2030. We\n", "plot the mean function and the standard deviation at 200 locations. We\n", "can obtain the predictions using `y_mean, y_var = m_full.predict(xt)`" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "xt = np.linspace(1870,2030,200)[:,np.newaxis]\n", "yt_mean, yt_var = m_full.predict(xt)\n", "yt_sd=np.sqrt(yt_var)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now we plot the results using the helper function in `teaching_plots`." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import teaching_plots as plot" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "fig, ax = plt.subplots(figsize=plot.big_wide_figsize)\n", "plot.model_output(m_full, scale=scale, offset=offset, ax=ax, xlabel='year', ylabel='pace min/km', fontsize=20, portion=0.2)\n", "ax.set_xlim(xlim)\n", "ax.set_ylim(ylim)\n", "mlai.write_figure(figure=fig,\n", " filename='../slides/diagrams/gp/olympic-marathon-gp.svg', \n", " transparent=True, frameon=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "### Fit Quality\n", "\n", "In the fit we see that the error bars (coming mainly from the noise\n", "variance) are quite large. This is likely due to the outlier point in\n", "1904, ignoring that point we can see that a tighter fit is obtained. To\n", "see this making a version of the model, `m_clean`, where that point is\n", "removed." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "x_clean=np.vstack((x[0:2, :], x[3:, :]))\n", "y_clean=np.vstack((y[0:2, :], y[3:, :]))\n", "\n", "m_clean = GPy.models.GPRegression(x_clean,y_clean)\n", "_ = m_clean.optimize()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Deep GP Fit\n", "\n", "Let's see if a deep Gaussian process can help here. We will construct a\n", "deep Gaussian process with one hidden layer (i.e. one Gaussian process\n", "feeding into another).\n", "\n", "Build a Deep GP with an additional hidden layer (one dimensional) to fit\n", "the model." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import GPy\n", "import deepgp" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "hidden = 1\n", "m = deepgp.DeepGP([y.shape[1],hidden,x.shape[1]],Y=yhat, X=x, inits=['PCA','PCA'], \n", " kernels=[GPy.kern.RBF(hidden,ARD=True),\n", " GPy.kern.RBF(x.shape[1],ARD=True)], # the kernels for each layer\n", " num_inducing=50, back_constraint=False)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Deep Gaussian process models also can require some thought in\n", "initialization. Here we choose to start by setting the noise variance to\n", "be one percent of the data variance.\n", "\n", "Optimization requires moving variational parameters in the hidden layer\n", "representing the mean and variance of the expected values in that layer.\n", "Since all those values can be scaled up, and this only results in a\n", "downscaling in the output of the first GP, and a downscaling of the\n", "input length scale to the second GP. It makes sense to first of all fix\n", "the scales of the covariance function in each of the GPs.\n", "\n", "Sometimes, deep Gaussian processes can find a local minima which\n", "involves increasing the noise level of one or more of the GPs. This\n", "often occurs because it allows a minimum in the KL divergence term in\n", "the lower bound on the likelihood. To avoid this minimum we habitually\n", "train with the likelihood variance (the noise on the output of the GP)\n", "fixed to some lower value for some iterations.\n", "\n", "Let's create a helper function to initialize the models we use in the\n", "notebook." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import deepgp" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%load -s initialize deepgp_tutorial.py" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Bind the new method to the Deep GP object.\n", "deepgp.DeepGP.initialize=initialize" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Call the initalization\n", "m.initialize()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now optimize the model. The first stage of optimization is working on\n", "variational parameters and lengthscales only." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "m.optimize(messages=False,max_iters=100)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now we remove the constraints on the scale of the covariance functions\n", "associated with each GP and optimize again." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "for layer in m.layers:\n", " pass #layer.kern.variance.constrain_positive(warning=False)\n", "m.obslayer.kern.variance.constrain_positive(warning=False)\n", "m.optimize(messages=False,max_iters=100)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Finally, we allow the noise variance to change and optimize for a large\n", "number of iterations." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "for layer in m.layers:\n", " layer.likelihood.variance.constrain_positive(warning=False)\n", "m.optimize(messages=True,max_iters=10000)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For our optimization process we define a new function." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%load -s staged_optimize deepgp_tutorial.py" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Bind the new method to the Deep GP object.\n", "deepgp.DeepGP.staged_optimize=staged_optimize" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "m.staged_optimize(messages=(True,True,True))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Plot the prediction\n", "\n", "The prediction of the deep GP can be extracted in a similar way to the\n", "normal GP. Although, in this case, it is an approximation to the true\n", "distribution, because the true distribution is not Gaussian." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import matplotlib.pyplot as plt" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "fig, ax = plt.subplots(figsize=plot.big_wide_figsize)\n", "plot.model_output(m, scale=scale, offset=offset, ax=ax, xlabel='year', ylabel='pace min/km', \n", " fontsize=20, portion=0.2)\n", "ax.set_xlim(xlim)\n", "\n", "ax.set_ylim(ylim)\n", "mlai.write_figure(figure=fig, filename='../slides/diagrams/deepgp/olympic-marathon-deep-gp.svg', \n", " transparent=True, frameon=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Olympic Marathon Data Deep GP\n", "\n", "" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%load -s posterior_sample deepgp_tutorial.py" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "deepgp.DeepGP.posterior_sample = posterior_sample" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "fig, ax = plt.subplots(figsize=plot.big_wide_figsize)\n", "plot.model_sample(m, scale=scale, offset=offset, samps=10, ax=ax, \n", " xlabel='year', ylabel='pace min/km', portion = 0.225)\n", "ax.set_xlim(xlim)\n", "ax.set_ylim(ylim)\n", "mlai.write_figure(figure=fig, filename='../slides/diagrams/deepgp/olympic-marathon-deep-gp-samples.svg', \n", " transparent=True, frameon=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Olympic Marathon Data Deep GP\n", "\n", "\n", "\n", "### Fitted GP for each layer\n", "\n", "Now we explore the GPs the model has used to fit each layer. First of\n", "all, we look at the hidden layer." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%load -s visualize deepgp_tutorial.py" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Bind the new method to the Deep GP object.\n", "deepgp.DeepGP.visualize=visualize" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "m.visualize(scale=scale, offset=offset, xlabel='year',\n", " ylabel='pace min/km',xlim=xlim, ylim=ylim,\n", " dataset='olympic-marathon',\n", " diagrams='../slides/diagrams/deepgp')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import pods" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "pods.notebook.display_plots('olympic-marathon-deep-gp-layer-{sample:0>1}.svg', \n", " '../slides/diagrams/deepgp', sample=(0,1))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "%load -s visualize_pinball deepgp_tutorial.py" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "# Bind the new method to the Deep GP object.\n", "deepgp.DeepGP.visualize_pinball=visualize_pinball" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "fig, ax = plt.subplots(figsize=plot.big_wide_figsize)\n", "m.visualize_pinball(ax=ax, scale=scale, offset=offset, points=30, portion=0.1,\n", " xlabel='year', ylabel='pace km/min', vertical=True)\n", "mlai.write_figure(figure=fig, filename='../slides/diagrams/deepgp/olympic-marathon-deep-gp-pinball.svg', \n", " transparent=True, frameon=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Olympic Marathon Pinball Plot\n", "\n", "\n", "\n", "The pinball plot shows the flow of any input ball through the deep\n", "Gaussian process. In a pinball plot a series of vertical parallel lines\n", "would indicate a purely linear function. For the olypmic marathon data\n", "we can see the first layer begins to shift from input towards the right.\n", "Note it also does so with some uncertainty (indicated by the shaded\n", "backgrounds). The second layer has less uncertainty, but bunches the\n", "inputs more strongly to the right. This input layer of uncertainty,\n", "followed by a layer that pushes inputs to the right is what gives the\n", "heteroschedastic noise.\n", "\n", "### Della Gatta Gene Data\n", "\n", "- Given given expression levels in the form of a time series from\n", " @DellaGatta:direct08." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import pods" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "data = pods.datasets.della_gatta_TRP63_gene_expression(data_set='della_gatta',gene_number=937)\n", "\n", "x = data['X']\n", "y = data['Y']\n", "\n", "offset = y.mean()\n", "scale = np.sqrt(y.var())" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import matplotlib.pyplot as plt\n", "import teaching_plots as plot\n", "import mlai" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "\n", "xlim = (-20,260)\n", "ylim = (5, 7.5)\n", "yhat = (y-offset)/scale\n", "\n", "fig, ax = plt.subplots(figsize=plot.big_wide_figsize)\n", "_ = ax.plot(x, y, 'r.',markersize=10)\n", "ax.set_xlabel('time/min', fontsize=20)\n", "ax.set_ylabel('expression', fontsize=20)\n", "ax.set_xlim(xlim)\n", "ax.set_ylim(ylim)\n", "\n", "mlai.write_figure(figure=fig, \n", " filename='../slides/diagrams/datasets/della-gatta-gene.svg', \n", " transparent=True, \n", " frameon=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "
\n", "\n", "\n", "\n", "
\n", "\n", "- Want to detect if a gene is expressed or not, fit a GP to each gene\n", " @Kalaitzis:simple11.\n", "\n", "
\n", "\n", "\n", "\n", "
\n", "\n", "
\n", "\n", "
\n", "Our first objective will be to perform a Gaussian process fit to the\n", "data, we'll do this using the [GPy\n", "software](https://github.com/SheffieldML/GPy)." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import GPy" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "m_full = GPy.models.GPRegression(x,yhat)\n", "m_full.kern.lengthscale=50\n", "_ = m_full.optimize() # Optimize parameters of covariance function" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Initialize the length scale parameter (which here actually represents a\n", "*time scale* of the covariance function to a reasonable value. Default\n", "would be 1, but here we set it to 50 minutes, given points are arriving\n", "across zero to 250 minutes." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "xt = np.linspace(-20,260,200)[:,np.newaxis]\n", "yt_mean, yt_var = m_full.predict(xt)\n", "yt_sd=np.sqrt(yt_var)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now we plot the results using the helper function in `teaching_plots`." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import teaching_plots as plot" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "fig, ax = plt.subplots(figsize=plot.big_wide_figsize)\n", "plot.model_output(m_full, scale=scale, offset=offset, ax=ax, xlabel='time/min', ylabel='expression', fontsize=20, portion=0.2)\n", "ax.set_xlim(xlim)\n", "ax.set_ylim(ylim)\n", "ax.set_title('log likelihood: {ll:.3}'.format(ll=m_full.log_likelihood()), fontsize=20)\n", "mlai.write_figure(figure=fig,\n", " filename='../slides/diagrams/gp/della-gatta-gene-gp.svg', \n", " transparent=True, frameon=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "Now we try a model initialized with a longer length scale." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "m_full2 = GPy.models.GPRegression(x,yhat)\n", "m_full2.kern.lengthscale=2000\n", "_ = m_full2.optimize() # Optimize parameters of covariance function" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import teaching_plots as plot" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "fig, ax = plt.subplots(figsize=plot.big_wide_figsize)\n", "plot.model_output(m_full2, scale=scale, offset=offset, ax=ax, xlabel='time/min', ylabel='expression', fontsize=20, portion=0.2)\n", "ax.set_xlim(xlim)\n", "ax.set_ylim(ylim)\n", "ax.set_title('log likelihood: {ll:.3}'.format(ll=m_full2.log_likelihood()), fontsize=20)\n", "mlai.write_figure(figure=fig,\n", " filename='../slides/diagrams/gp/della-gatta-gene-gp2.svg', \n", " transparent=True, frameon=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "Now we try a model initialized with a lower noise." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "m_full3 = GPy.models.GPRegression(x,yhat)\n", "m_full3.kern.lengthscale=20\n", "m_full3.likelihood.variance=0.001\n", "_ = m_full3.optimize() # Optimize parameters of covariance function" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import teaching_plots as plot" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "fig, ax = plt.subplots(figsize=plot.big_wide_figsize)\n", "plot.model_output(m_full3, scale=scale, offset=offset, ax=ax, xlabel='time/min', ylabel='expression', fontsize=20, portion=0.2)\n", "ax.set_xlim(xlim)\n", "ax.set_ylim(ylim)\n", "ax.set_title('log likelihood: {ll:.3}'.format(ll=m_full3.log_likelihood()), fontsize=20)\n", "mlai.write_figure(figure=fig,\n", " filename='../slides/diagrams/gp/della-gatta-gene-gp3.svg', \n", " transparent=True, frameon=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "\n", "\n", "" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "layers = [y.shape[1], 1,x.shape[1]]\n", "inits = ['PCA']*(len(layers)-1)\n", "kernels = []\n", "for i in layers[1:]:\n", " kernels += [GPy.kern.RBF(i)]\n", "m = deepgp.DeepGP(layers,Y=yhat, X=x, \n", " inits=inits, \n", " kernels=kernels, # the kernels for each layer\n", " num_inducing=20, back_constraint=False)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "m.initialize()\n", "m.staged_optimize()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "fig, ax=plt.subplots(figsize=plot.big_wide_figsize)\n", "plot.model_output(m, scale=scale, offset=offset, ax=ax, fontsize=20, portion=0.5)\n", "ax.set_ylim(ylim)\n", "ax.set_xlim(xlim)\n", "mlai.write_figure(filename='../slides/diagrams/deepgp/della-gatta-gene-deep-gp.svg', \n", " transparent=True, frameon=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### TP53 Gene Data Deep GP\n", "\n", "" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "fig, ax=plt.subplots(figsize=plot.big_wide_figsize)\n", "plot.model_sample(m, scale=scale, offset=offset, samps=10, ax=ax, portion = 0.5)\n", "ax.set_ylim(ylim)\n", "ax.set_xlim(xlim)\n", "mlai.write_figure(figure=fig, filename='../slides/diagrams/deepgp/della-gatta-gene-deep-gp-samples.svg', \n", " transparent=True, frameon=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### TP53 Gene Data Deep GP\n", "\n", "" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "m.visualize(offset=offset, scale=scale, xlim=xlim, ylim=ylim,\n", " dataset='della-gatta-gene',\n", " diagrams='../slides/diagrams/deepgp')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### TP53 Gene Data Latent 1\n", "\n", "\n", "\n", "### TP53 Gene Data Latent 2\n", "\n", "" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "fig, ax=plt.subplots(figsize=plot.big_wide_figsize)\n", "m.visualize_pinball(offset=offset, ax=ax, scale=scale, xlim=xlim, ylim=ylim, portion=0.1, points=50)\n", "mlai.write_figure(figure=fig, filename='../slides/diagrams/deepgp/della-gatta-gene-deep-gp-pinball.svg', \n", " transparent=True, frameon=True, ax=ax)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### TP53 Gene Pinball Plot\n", "\n", "\n", "\n", "### Step Function\n", "\n", "Next we consider a simple step function data set." ] }, { "cell_type": "code", "execution_count": 223, "metadata": {}, "outputs": [], "source": [ "num_low=25\n", "num_high=25\n", "gap = -.1\n", "noise=0.0001\n", "x = np.vstack((np.linspace(-1, -gap/2.0, num_low)[:, np.newaxis],\n", " np.linspace(gap/2.0, 1, num_high)[:, np.newaxis]))\n", "y = np.vstack((np.zeros((num_low, 1)), np.ones((num_high,1))))\n", "scale = np.sqrt(y.var())\n", "offset = y.mean()\n", "yhat = (y-offset)/scale" ] }, { "cell_type": "code", "execution_count": 229, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "fig, ax = plt.subplots(figsize=plot.big_wide_figsize)\n", "_ = ax.plot(x, y, 'r.',markersize=10)\n", "_ = ax.set_xlabel('$x$', fontsize=20)\n", "_ = ax.set_ylabel('$y$', fontsize=20)\n", "xlim = (-2, 2)\n", "ylim = (-0.6, 1.6)\n", "ax.set_ylim(ylim)\n", "ax.set_xlim(xlim)\n", "mlai.write_figure(figure=fig, filename='../slides/diagrams/datasets/step-function.svg', \n", " transparent=True, frameon=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Step Function Data\n", "\n", "" ] }, { "cell_type": "code", "execution_count": 227, "metadata": {}, "outputs": [], "source": [ "m_full = GPy.models.GPRegression(x,yhat)\n", "_ = m_full.optimize() # Optimize parameters of covariance function" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Step Function Data GP\n", "\n", "" ] }, { "cell_type": "code", "execution_count": 228, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "fig, ax=plt.subplots(figsize=plot.big_wide_figsize)\n", "plot.model_output(m_full, scale=scale, offset=offset, ax=ax, fontsize=20, portion=0.5)\n", "ax.set_ylim(ylim)\n", "ax.set_xlim(xlim)\n", "\n", "mlai.write_figure(figure=fig,filename='../slides/diagrams/gp/step-function-gp.svg', \n", " transparent=True, frameon=True)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "layers = [y.shape[1], 1, 1, 1,x.shape[1]]\n", "inits = ['PCA']*(len(layers)-1)\n", "kernels = []\n", "for i in layers[1:]:\n", " kernels += [GPy.kern.RBF(i)]\n", "m = deepgp.DeepGP(layers,Y=yhat, X=x, \n", " inits=inits, \n", " kernels=kernels, # the kernels for each layer\n", " num_inducing=20, back_constraint=False)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "m.initialize()\n", "m.staged_optimize()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "fig, ax=plt.subplots(figsize=plot.big_wide_figsize)\n", "plot.model_output(m, scale=scale, offset=offset, ax=ax, fontsize=20, portion=0.5)\n", "ax.set_ylim(ylim)\n", "ax.set_xlim(xlim)\n", "mlai.write_figure(filename='../slides/diagrams/deepgp/step-function-deep-gp.svg', \n", " transparent=True, frameon=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Step Function Data Deep GP\n", "\n", "" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "fig, ax=plt.subplots(figsize=plot.big_wide_figsize)\n", "\n", "plot.model_sample(m, scale=scale, offset=offset, samps=10, ax=ax, portion = 0.5)\n", "ax.set_ylim(ylim)\n", "ax.set_xlim(xlim)\n", "mlai.write_figure(figure=fig, filename='../slides/diagrams/deepgp/step-function-deep-gp-samples.svg', \n", " transparent=True, frameon=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Step Function Data Deep GP\n", "\n", "" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "m.visualize(offset=offset, scale=scale, xlim=xlim, ylim=ylim,\n", " dataset='step-function',\n", " diagrams='../slides/diagrams/deepgp')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Step Function Data Latent 1\n", "\n", "\n", "\n", "### Step Function Data Latent 2\n", "\n", "\n", "\n", "### Step Function Data Latent 3\n", "\n", "\n", "\n", "### Step Function Data Latent 4\n", "\n", "" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "fig, ax=plt.subplots(figsize=plot.big_wide_figsize)\n", "m.visualize_pinball(offset=offset, ax=ax, scale=scale, xlim=xlim, ylim=ylim, portion=0.1, points=50)\n", "mlai.write_figure(figure=fig, filename='../slides/diagrams/deepgp/step-function-deep-gp-pinball.svg', \n", " transparent=True, frameon=True, ax=ax)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Step Function Pinball Plot\n", "\n", "" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import pods" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "data = pods.datasets.mcycle()\n", "x = data['X']\n", "y = data['Y']\n", "scale=np.sqrt(y.var())\n", "offset=y.mean()\n", "yhat = (y - offset)/scale" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "fig, ax = plt.subplots(figsize=plot.big_wide_figsize)\n", "_ = ax.plot(x, y, 'r.',markersize=10)\n", "_ = ax.set_xlabel('time', fontsize=20)\n", "_ = ax.set_ylabel('acceleration', fontsize=20)\n", "xlim = (-20, 80)\n", "ylim = (-175, 125)\n", "ax.set_xlim(xlim)\n", "ax.set_ylim(ylim)\n", "mlai.write_figure(filename='../slides/diagrams/datasets/motorcycle-helmet.svg', \n", " transparent=True, frameon=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Motorcycle Helmet Data\n", "\n", "" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "m_full = GPy.models.GPRegression(x,yhat)\n", "_ = m_full.optimize() # Optimize parameters of covariance function" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Motorcycle Helmet Data GP\n", "\n", "" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import deepgp" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "layers = [y.shape[1], 1, x.shape[1]]\n", "inits = ['PCA']*(len(layers)-1)\n", "kernels = []\n", "for i in layers[1:]:\n", " kernels += [GPy.kern.RBF(i)]\n", "m = deepgp.DeepGP(layers,Y=yhat, X=x, \n", " inits=inits, \n", " kernels=kernels, # the kernels for each layer\n", " num_inducing=20, back_constraint=False)\n", "\n", "\n", "\n", "m.initialize()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "m.staged_optimize(iters=(1000,1000,10000), messages=(True, True, True))" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import teaching_plots as plot\n", "import mlai" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "fig, ax=plt.subplots(figsize=plot.big_wide_figsize)\n", "plot.model_output(m, scale=scale, offset=offset, ax=ax, xlabel='time', ylabel='acceleration/$g$', fontsize=20, portion=0.5)\n", "ax.set_ylim(ylim)\n", "ax.set_xlim(xlim)\n", "mlai.write_figure(filename='../slides/diagrams/deepgp/motorcycle-helmet-deep-gp.svg', \n", " transparent=True, frameon=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Motorcycle Helmet Data Deep GP\n", "\n", "" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import teaching_plots as plot\n", "import mlai" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "fig, ax=plt.subplots(figsize=plot.big_wide_figsize)\n", "plot.model_sample(m, scale=scale, offset=offset, samps=10, ax=ax, xlabel='time', ylabel='acceleration/$g$', portion = 0.5)\n", "ax.set_ylim(ylim)\n", "ax.set_xlim(xlim)\n", "\n", "mlai.write_figure(figure=fig, filename='../slides/diagrams/deepgp/motorcycle-helmet-deep-gp-samples.svg', \n", " transparent=True, frameon=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Motorcycle Helmet Data Deep GP\n", "\n", "" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "m.visualize(xlim=xlim, ylim=ylim, scale=scale,offset=offset, \n", " xlabel=\"time\", ylabel=\"acceleration/$g$\", portion=0.5,\n", " dataset='motorcycle-helmet',\n", " diagrams='../slides/diagrams/deepgp')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Motorcycle Helmet Data Latent 1\n", "\n", "\n", "\n", "### Motorcycle Helmet Data Latent 2\n", "\n", "" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "fig, ax=plt.subplots(figsize=plot.big_wide_figsize)\n", "m.visualize_pinball(ax=ax, xlabel='time', ylabel='acceleration/g', \n", " points=50, scale=scale, offset=offset, portion=0.1)\n", "mlai.write_figure(figure=fig, filename='../slides/diagrams/deepgp/motorcycle-helmet-deep-gp-pinball.svg', \n", " transparent=True, frameon=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Motorcycle Helmet Pinball Plot\n", "\n", "\n", "\n", "### Robot Wireless Data\n", "\n", "The robot wireless data is taken from an experiment run by Brian Ferris\n", "at University of Washington. It consists of the measurements of WiFi\n", "access point signal strengths as Brian walked in a loop." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "data=pods.datasets.robot_wireless()\n", "\n", "x = np.linspace(0,1,215)[:, np.newaxis]\n", "y = data['Y']\n", "offset = y.mean()\n", "scale = np.sqrt(y.var())\n", "yhat = (y-offset)/scale" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The ground truth is recorded in the data, the actual loop is given in\n", "the plot below." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "fig, ax = plt.subplots(figsize=plot.big_figsize)\n", "plt.plot(data['X'][:, 1], data['X'][:, 2], 'r.', markersize=5)\n", "ax.set_xlabel('x position', fontsize=20)\n", "ax.set_ylabel('y position', fontsize=20)\n", "mlai.write_figure(figure=fig, filename='../../slides/diagrams/datasets/robot-wireless-ground-truth.svg', transparent=True, frameon=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Robot Wireless Ground Truth\n", "\n", "\n", "\n", "We will ignore this ground truth in making our predictions, but see if\n", "the model can recover something similar in one of the latent layers." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "output_dim=1\n", "xlim = (-0.3, 1.3)\n", "fig, ax = plt.subplots(figsize=plot.big_wide_figsize)\n", "_ = ax.plot(x.flatten(), y[:, output_dim], \n", " 'r.', markersize=5)\n", "\n", "ax.set_xlabel('time', fontsize=20)\n", "ax.set_ylabel('signal strength', fontsize=20)\n", "xlim = (-0.2, 1.2)\n", "ylim = (-0.6, 2.0)\n", "ax.set_xlim(xlim)\n", "ax.set_ylim(ylim)\n", "\n", "mlai.write_figure(figure=fig, filename='../slides/diagrams/datasets/robot-wireless-dim-' + str(output_dim) + '.svg', \n", " transparent=True, frameon=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Robot WiFi Data\n", "\n", "\n", "\n", "Perform a Gaussian process fit on the data using GPy." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "m_full = GPy.models.GPRegression(x,yhat)\n", "_ = m_full.optimize() # Optimize parameters of covariance function" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "fig, ax=plt.subplots(figsize=plot.big_wide_figsize)\n", "plot.model_output(m_full, output_dim=output_dim, scale=scale, offset=offset, ax=ax, \n", " xlabel='time', ylabel='signal strength', fontsize=20, portion=0.5)\n", "ax.set_ylim(ylim)\n", "ax.set_xlim(xlim)\n", "mlai.write_figure(filename='../slides/diagrams/gp/robot-wireless-gp-dim-' + str(output_dim)+ '.svg', \n", " transparent=True, frameon=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Robot WiFi Data GP\n", "\n", "" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "layers = [y.shape[1], 10, 5, 2, 2, x.shape[1]]\n", "inits = ['PCA']*(len(layers)-1)\n", "kernels = []\n", "for i in layers[1:]:\n", " kernels += [GPy.kern.RBF(i, ARD=True)]" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "m = deepgp.DeepGP(layers,Y=y, X=x, inits=inits, \n", " kernels=kernels,\n", " num_inducing=50, back_constraint=False)\n", "m.initialize()" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "m.staged_optimize(messages=(True,True,True))" ] }, { "cell_type": "code", "execution_count": 217, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "fig, ax=plt.subplots(figsize=plot.big_wide_figsize)\n", "plot.model_output(m, output_dim=output_dim, scale=scale, offset=offset, ax=ax, \n", " xlabel='time', ylabel='signal strength', fontsize=20, portion=0.5)\n", "ax.set_ylim(ylim)\n", "ax.set_xlim(xlim)\n", "mlai.write_figure(figure=fig, filename='../slides/diagrams/deepgp/robot-wireless-deep-gp-dim-' + str(output_dim)+ '.svg', \n", " transparent=True, frameon=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Robot WiFi Data Deep GP\n", "\n", "" ] }, { "cell_type": "code", "execution_count": 219, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ " /Users/neil/anaconda3/lib/python3.6/site-packages/GPy/core/gp.py:557: RuntimeWarning:covariance is not positive-semidefinite.\n" ] }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "fig, ax=plt.subplots(figsize=plot.big_wide_figsize)\n", "plot.model_sample(m, output_dim=output_dim, scale=scale, offset=offset, samps=10, ax=ax,\n", " xlabel='time', ylabel='signal strength', fontsize=20, portion=0.5)\n", "ax.set_ylim(ylim)\n", "ax.set_xlim(xlim)\n", "mlai.write_figure(figure=fig, filename='../slides/diagrams/deepgp/robot-wireless-deep-gp-samples-dim-' + str(output_dim)+ '.svg', \n", " transparent=True, frameon=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Robot WiFi Data Deep GP\n", "\n", "\n", "\n", "### Robot WiFi Data Latent Space\n", "\n", "" ] }, { "cell_type": "code", "execution_count": 222, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "fig, ax = plt.subplots(figsize=plot.big_figsize)\n", "ax.plot(m.layers[-2].latent_space.mean[:, 0], \n", " m.layers[-2].latent_space.mean[:, 1], \n", " 'r.-', markersize=5)\n", "\n", "ax.set_xlabel('latent dimension 1', fontsize=20)\n", "ax.set_ylabel('latent dimension 2', fontsize=20)\n", "\n", "mlai.write_figure(figure=fig, filename='../slides/diagrams/deepgp/robot-wireless-latent-space.svg', \n", " transparent=True, frameon=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Robot WiFi Data Latent Space\n", "\n", "\n", "\n", "### Motion Capture\n", "\n", "- ‘High five’ data.\n", "- Model learns structure between two interacting subjects.\n", "\n", "### Shared LVM\n", "\n", "\n", "\n", "\n", "\n", "[Thanks to: Zhenwen Dai and Neil D.\n", "Lawrence]{style=\"text-align:right\"}\n", "\n", "We now look at the deep Gaussian processes' capacity to perform\n", "unsupervised learning.\n", "\n", "We will look at a sub-sample of the MNIST digit data set.\n", "\n", "First load in the MNIST data set from scikit learn. This can take a\n", "little while because it's large to download." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from sklearn.datasets import fetch_mldata" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "mnist = fetch_mldata('MNIST original')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Sub-sample the dataset to make the training faster." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import numpy as np" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "np.random.seed(0)\n", "digits = [0,1,2,3,4]\n", "N_per_digit = 100\n", "Y = []\n", "labels = []\n", "for d in digits:\n", " imgs = mnist['data'][mnist['target']==d]\n", " Y.append(imgs[np.random.permutation(imgs.shape[0])][:N_per_digit])\n", " labels.append(np.ones(N_per_digit)*d)\n", "Y = np.vstack(Y).astype(np.float64)\n", "labels = np.hstack(labels)\n", "Y /= 255." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Fit a Deep GP\n", "\n", "We're going to fit a Deep Gaussian process model to the MNIST data with\n", "two hidden layers. Each of the two Gaussian processes (one from the\n", "first hidden layer to the second, one from the second hidden layer to\n", "the data) has an exponentiated quadratic covariance." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import deepgp\n", "import GPy" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "num_latent = 2\n", "num_hidden_2 = 5\n", "m = deepgp.DeepGP([Y.shape[1],num_hidden_2,num_latent],\n", " Y,\n", " kernels=[GPy.kern.RBF(num_hidden_2,ARD=True), \n", " GPy.kern.RBF(num_latent,ARD=False)], \n", " num_inducing=50, back_constraint=False, \n", " encoder_dims=[[200],[200]])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Initialization\n", "\n", "Just like deep neural networks, there are some tricks to intitializing\n", "these models. The tricks we use here include some early training of the\n", "model with model parameters constrained. This gives the variational\n", "inducing parameters some scope to tighten the bound for the case where\n", "the noise variance is small and the variances of the Gaussian processes\n", "are around 1." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "m.obslayer.likelihood.variance[:] = Y.var()*0.01\n", "for layer in m.layers:\n", " layer.kern.variance.fix(warning=False)\n", " layer.likelihood.variance.fix(warning=False)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We now we optimize for a hundred iterations with the constrained model." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "m.optimize(messages=False,max_iters=100)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now we remove the fixed constraint on the kernel variance parameters,\n", "but keep the noise output constrained, and run for a further 100\n", "iterations." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "for layer in m.layers:\n", " layer.kern.variance.constrain_positive(warning=False)\n", "m.optimize(messages=False,max_iters=100)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Finally we unconstrain the layer likelihoods and allow the full model to\n", "be trained for 1000 iterations." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "for layer in m.layers:\n", " layer.likelihood.variance.constrain_positive(warning=False)\n", "m.optimize(messages=True,max_iters=10000)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Visualize the latent space of the top layer\n", "\n", "Now the model is trained, let's plot the mean of the posterior\n", "distributions in the top latent layer of the model." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import matplotlib.pyplot as plt\n", "from matplotlib import rc\n", "import teaching_plots as plot\n", "import mlai" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "rc(\"font\", **{'family':'sans-serif','sans-serif':['Helvetica'],'size':20})\n", "fig, ax = plt.subplots(figsize=plot.big_figsize)\n", "for d in digits:\n", " ax.plot(m.layer_1.X.mean[labels==d,0],m.layer_1.X.mean[labels==d,1],'.',label=str(d))\n", "_ = plt.legend()\n", "mlai.write_figure(figure=fig, filename=\"../slides/diagrams/deepgp/usps-digits-latent.svg\", transparent=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "### Visualize the latent space of the intermediate layer\n", "\n", "We can also visualize dimensions of the intermediate layer. First the\n", "lengthscale of those dimensions is given by" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "m.obslayer.kern.lengthscale" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import matplotlib.pyplot as plt\n", "import mlai" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "fig, ax = plt.subplots(figsize=plot.big_figsize)\n", "for i in range(5):\n", " for j in range(i):\n", " dims=[i, j]\n", " ax.cla()\n", " for d in digits:\n", " ax.plot(m.obslayer.X.mean[labels==d,dims[0]],\n", " m.obslayer.X.mean[labels==d,dims[1]],\n", " '.', label=str(d))\n", " plt.legend()\n", " plt.xlabel('dimension ' + str(dims[0]))\n", " plt.ylabel('dimension ' + str(dims[1]))\n", " mlai.write_figure(figure=fig, filename=\"../slides/diagrams/deepgp/usps-digits-hidden-\" + str(dims[0]) + '-' + str(dims[1]) + '.svg', transparent=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "### Generate From Model\n", "\n", "Now we can take a look at a sample from the model, by drawing a Gaussian\n", "random sample in the latent space and propagating it through the model." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "\n", "rows = 10\n", "cols = 20\n", "t=np.linspace(-1, 1, rows*cols)[:, None]\n", "kern = GPy.kern.RBF(1,lengthscale=0.05)\n", "cov = kern.K(t, t)\n", "x = np.random.multivariate_normal(np.zeros(rows*cols), cov, num_latent).T" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import matplotlib.pyplot as plt\n", "import mlai" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "yt = m.predict(x)\n", "fig, axs = plt.subplots(rows,cols,figsize=(10,6))\n", "for i in range(rows):\n", " for j in range(cols):\n", " #v = np.random.normal(loc=yt[0][i*cols+j, :], scale=np.sqrt(yt[1][i*cols+j, :]))\n", " v = yt[0][i*cols+j, :]\n", " axs[i,j].imshow(v.reshape(28,28), \n", " cmap='gray', interpolation='none',\n", " aspect='equal')\n", " axs[i,j].set_axis_off()\n", "mlai.write_figure(figure=fig, filename=\"../slides/diagrams/deepgp/digit-samples-deep-gp.svg\", transparent=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "\n", "\n", "- *Gaussian process based nonlinear latent structure discovery in\n", " multivariate spike train data* @Anqi:gpspike2017\n", "- *Doubly Stochastic Variational Inference for Deep Gaussian\n", " Processes* @Salimbeni:doubly2017\n", "- *Deep Multi-task Gaussian Processes for Survival Analysis with\n", " Competing Risks* @Alaa:deep2017\n", "- *Counterfactual Gaussian Processes for Reliable Decision-making and\n", " What-if Reasoning* @Schulam:counterfactual17\n", "\n", "- *Deep Survival Analysis* @Ranganath-survival16\n", "- *Recurrent Gaussian Processes* @Mattos:recurrent15\n", "- *Gaussian Process Based Approaches for Survival Analysis*\n", " @Saul:thesis2016\n", "\n", "
\n", "\n", "[](https://amzn.github.io/emukit-playground/)\n", "\n", "
\n", "\n", "
\n", "Emukit playground is a tutorial for understanding the\n", "simulation/emulation relationship.\n", "
\n", "
\n", "\n", "[](https://amzn.github.io/emukit-playground/#!/learn/bayesian_optimization)\n", "\n", "
\n", "\n", "
\n", "Tutorial on Bayesian optimization of the number of taxis deployed\n", "from Emukit playground.\n", "
\n", "### Uncertainty Quantification\n", "\n", "> Uncertainty quantification (UQ) is the science of quantitative\n", "> characterization and reduction of uncertainties in both computational\n", "> and real world applications. It tries to determine how likely certain\n", "> outcomes are if some aspects of the system are not exactly known.\n", "\n", "We will to illustrate different concepts of [Uncertainty\n", "Quantification](https://en.wikipedia.org/wiki/Uncertainty_quantification)\n", "(UQ) and the role that Gaussian processes play in this field. Based on a\n", "simple simulator of a car moving between a valley and a mountain, we are\n", "going to illustrate the following concepts:\n", "\n", "- **Systems emulation**. Many real world decisions are based on\n", " simulations that can be computationally very demanding. We will show\n", " how simulators can be replaced by *emulators*: Gaussian process\n", " models fitted on a few simulations that can be used to replace the\n", " *simulator*. Emulators are cheap to compute, fast to run, and always\n", " provide ways to quantify the uncertainty of how precise they are\n", " compared the original simulator.\n", "\n", "- **Emulators in optimization problems**. We will show how emulators\n", " can be used to optimize black-box functions that are expensive to\n", " evaluate. This field is also called Bayesian Optimization and has\n", " gained an increasing relevance in machine learning as emulators can\n", " be used to optimize computer simulations (and machine learning\n", " algorithms) quite efficiently.\n", "\n", "- **Multi-fidelity emulation methods**. In many scenarios we have\n", " simulators of different quality about the same measure of interest.\n", " In these cases the goal is to merge all sources of information under\n", " the same model so the final emulator is cheaper and more accurate\n", " than an emulator fitted only using data from the most accurate and\n", " expensive simulator.\n", "\n", "### Mountain Car Simulator\n", "\n", "To illustrate the above mentioned concepts we we use the [mountain car\n", "simulator](https://github.com/openai/gym/wiki/MountainCarContinuous-v0).\n", "This simulator is widely used in machine learning to test reinforcement\n", "learning algorithms. The goal is to define a control policy on a car\n", "whose objective is to climb a mountain. Graphically, the problem looks\n", "as follows:\n", "\n", "
\n", "\n", "\n", "\n", "
\n", "\n", "
\n", "The mountain car simulation from the Open AI gym.\n", "
\n", "The goal is to define a sequence of actions (push the car right or left\n", "with certain intensity) to make the car reach the flag after a number\n", "$T$ of time steps.\n", "\n", "At each time step $t$, the car is characterized by a vector\n", "$\\inputVector_{t} = (p_t,v_t)$ of states which are respectively the the\n", "position and velocity of the car at time $t$. For a sequence of states\n", "(an episode), the dynamics of the car is given by\n", "\n", "$$\\inputVector_{t+1} = \\mappingFunction(\\inputVector_{t},\\textbf{u}_{t})$$\n", "\n", "where $\\textbf{u}_{t}$ is the value of an action force, which in this\n", "example corresponds to push car to the left (negative value) or to the\n", "right (positive value). The actions across a full episode are\n", "represented in a policy $\\textbf{u}_{t} = \\pi(\\inputVector_{t},\\theta)$\n", "that acts according to the current state of the car and some parameters\n", "$\\theta$. In the following examples we will assume that the policy is\n", "linear which allows us to write $\\pi(\\inputVector_{t},\\theta)$ as\n", "\n", "$$\\pi(\\inputVector,\\theta)= \\theta_0 + \\theta_p p + \\theta_vv.$$\n", "\n", "For $t=1,\\dots,T$ now given some initial state $\\inputVector_{0}$ and\n", "some some values of each $\\textbf{u}_{t}$, we can **simulate** the full\n", "dynamics of the car for a full episode using\n", "[Gym](https://gym.openai.com/envs/). The values of $\\textbf{u}_{t}$ are\n", "fully determined by the parameters of the linear controller.\n", "\n", "After each episode of length $T$ is complete, a reward function\n", "$R_{T}(\\theta)$ is computed. In the mountain car example the reward is\n", "computed as 100 for reaching the target of the hill on the right hand\n", "side, minus the squared sum of actions (a real negative to push to the\n", "left and a real positive to push to the right) from start to goal. Note\n", "that our reward depend on $\\theta$ as we make it dependent on the\n", "parameters of the linear controller.\n", "\n", "### Emulate the Mountain Car" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import gym" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "env = gym.make('MountainCarContinuous-v0')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Our goal in this section is to find the parameters $\\theta$ of the\n", "linear controller such that\n", "\n", "$$\\theta^* = arg \\max_{\\theta} R_T(\\theta).$$\n", "\n", "In this section, we directly use Bayesian optimization to solve this\n", "problem. We will use [GPyOpt](https://sheffieldml.github.io/GPyOpt/) so\n", "we first define the objective function:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import mountain_car as mc\n", "import GPyOpt" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "obj_func = lambda x: mc.run_simulation(env, x)[0]\n", "objective = GPyOpt.core.task.SingleObjective(obj_func)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For each set of parameter values of the linear controller we can run an\n", "episode of the simulator (that we fix to have a horizon of $T=500$) to\n", "generate the reward. Using as input the parameters of the controller and\n", "as outputs the rewards we can build a Gaussian process emulator of the\n", "reward.\n", "\n", "We start defining the input space, which is three-dimensional:" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "## --- We define the input space of the emulator\n", "\n", "space= [{'name':'postion_parameter', 'type':'continuous', 'domain':(-1.2, +1)},\n", " {'name':'velocity_parameter', 'type':'continuous', 'domain':(-1/0.07, +1/0.07)},\n", " {'name':'constant', 'type':'continuous', 'domain':(-1, +1)}]\n", "\n", "design_space = GPyOpt.Design_space(space=space)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now we initizialize a Gaussian process emulator." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "model = GPyOpt.models.GPModel(optimize_restarts=5, verbose=False, exact_feval=True, ARD=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In Bayesian optimization an acquisition function is used to balance\n", "exploration and exploitation to evaluate new locations close to the\n", "optimum of the objective. In this notebook we select the expected\n", "improvement (EI). For further details have a look to the review paper of\n", "[Shahriari et al\n", "(2015)](http://www.cs.ox.ac.uk/people/nando.defreitas/publications/BayesOptLoop.pdf)." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "aquisition_optimizer = GPyOpt.optimization.AcquisitionOptimizer(design_space)\n", "acquisition = GPyOpt.acquisitions.AcquisitionEI(model, design_space, optimizer=aquisition_optimizer)\n", "evaluator = GPyOpt.core.evaluators.Sequential(acquisition) # Collect points sequentially, no parallelization." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "To initalize the model we start sampling some initial points (25) for\n", "the linear controler randomly." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from GPyOpt.experiment_design.random_design import RandomDesign" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "n_initial_points = 25\n", "random_design = RandomDesign(design_space)\n", "initial_design = random_design.get_samples(n_initial_points)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Before we start any optimization, lets have a look to the behavior of\n", "the car with the first of these initial points that we have selected\n", "randomly." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import numpy as np" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "random_controller = initial_design[0,:]\n", "_, _, _, frames = mc.run_simulation(env, np.atleast_2d(random_controller), render=True)\n", "anim=mc.animate_frames(frames, 'Random linear controller')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from IPython.core.display import HTML" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "HTML(anim.to_jshtml())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "As we can see the random linear controller does not manage to push the\n", "car to the top of the mountain. Now, let's optimize the regret using\n", "Bayesian optimization and the emulator for the reward. We try 50 new\n", "parameters chosen by the EI." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "max_iter = 50\n", "bo = GPyOpt.methods.ModularBayesianOptimization(model, design_space, objective, acquisition, evaluator, initial_design)\n", "bo.run_optimization(max_iter = max_iter )" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now we visualize the result for the best controller that we have found\n", "with Bayesian optimization." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "_, _, _, frames = mc.run_simulation(env, np.atleast_2d(bo.x_opt), render=True)\n", "anim=mc.animate_frames(frames, 'Best controller after 50 iterations of Bayesian optimization')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "HTML(anim.to_jshtml())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "he car can now make it to the top of the mountain! Emulating the reward\n", "function and using the EI helped as to find a linear controller that\n", "solves the problem.\n", "\n", "### Data Efficient Emulation\n", "\n", "In the previous section we solved the mountain car problem by directly\n", "emulating the reward but no considerations about the dynamics\n", "$\\inputVector_{t+1} = \\mappingFunction(\\inputVector_{t},\\textbf{u}_{t})$\n", "of the system were made. Note that we had to run 75 episodes of 500\n", "steps each to solve the problem, which required to call the simulator\n", "$500\\times 75 =37500$ times. In this section we will show how it is\n", "possible to reduce this number by building an emulator for $f$ that can\n", "later be used to directly optimize the control.\n", "\n", "The inputs of the model for the dynamics are the velocity, the position\n", "and the value of the control so create this space accordingly." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import gym" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "env = gym.make('MountainCarContinuous-v0')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import GPyOpt" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "space_dynamics = [{'name':'position', 'type':'continuous', 'domain':[-1.2, +0.6]},\n", " {'name':'velocity', 'type':'continuous', 'domain':[-0.07, +0.07]},\n", " {'name':'action', 'type':'continuous', 'domain':[-1, +1]}]\n", "design_space_dynamics = GPyOpt.Design_space(space=space_dynamics)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The outputs are the velocity and the position. Indeed our model will\n", "capture the change in position and velocity on time. That is, we will\n", "model\n", "\n", "$$\\Delta v_{t+1} = v_{t+1} - v_{t}$$\n", "\n", "$$\\Delta x_{t+1} = p_{t+1} - p_{t}$$\n", "\n", "with Gaussian processes with prior mean $v_{t}$ and $p_{t}$\n", "respectively. As a covariance function, we use a Matern52. We need\n", "therefore two models to capture the full dynamics of the system." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "position_model = GPyOpt.models.GPModel(optimize_restarts=5, verbose=False, exact_feval=True, ARD=True)\n", "velocity_model = GPyOpt.models.GPModel(optimize_restarts=5, verbose=False, exact_feval=True, ARD=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Next, we sample some input parameters and use the simulator to compute\n", "the outputs. Note that in this case we are not running the full\n", "episodes, we are just using the simulator to compute\n", "$\\inputVector_{t+1}$ given $\\inputVector_{t}$ and $\\textbf{u}_{t}$." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "from GPyOpt.experiment_design.random_design import RandomDesign\n", "import mountain_car as mc" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "### --- Random locations of the inputs\n", "n_initial_points = 500\n", "random_design_dynamics = RandomDesign(design_space_dynamics)\n", "initial_design_dynamics = random_design_dynamics.get_samples(n_initial_points)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "### --- Simulation of the (normalized) outputs\n", "y = np.zeros((initial_design_dynamics.shape[0], 2))\n", "for i in range(initial_design_dynamics.shape[0]):\n", " y[i, :] = mc.simulation(initial_design_dynamics[i, :])\n", "\n", "# Normalize the data from the simulation\n", "y_normalisation = np.std(y, axis=0)\n", "y_normalised = y/y_normalisation" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In general we might use much smarter strategies to design our emulation\n", "of the simulator. For example, we could use the variance of the\n", "predictive distributions of the models to collect points using\n", "uncertainty sampling, which will give us a better coverage of the space.\n", "For simplicity, we move ahead with the 500 randomly selected points.\n", "\n", "Now that we have a data set, we can update the emulators for the\n", "location and the velocity." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "position_model.updateModel(initial_design_dynamics, y[:, [0]], None, None)\n", "velocity_model.updateModel(initial_design_dynamics, y[:, [1]], None, None)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can now have a look to how the emulator and the simulator match.\n", "First, we show a contour plot of the car aceleration for each pair of\n", "can position and velocity. You can use the bar bellow to play with the\n", "values of the controler to compare the emulator and the simulator." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from IPython.html.widgets import interact" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can see how the emulator is doing a fairly good job approximating the\n", "simulator. On the edges, however, it struggles to captures the dynamics\n", "of the simulator.\n", "\n", "Given some input parameters of the linear controlling, how do the\n", "dynamics of the emulator and simulator match? In the following figure we\n", "show the position and velocity of the car for the 500 time steps of an\n", "episode in which the parameters of the linear controller have been fixed\n", "beforehand. The value of the input control is also shown." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "controller_gains = np.atleast_2d([0, .6, 1]) # change the valus of the linear controller to observe the trayectories." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "\n", "We now make explicit use of the emulator, using it to replace the\n", "simulator and optimize the linear controller. Note that in this\n", "optimization, we don't need to query the simulator anymore as we can\n", "reproduce the full dynamics of an episode using the emulator. For\n", "illustrative purposes, in this example we fix the initial location of\n", "the car.\n", "\n", "We define the objective reward function in terms of the simulator." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "### --- Optimize control parameters with emulator\n", "car_initial_location = np.asarray([-0.58912799, 0]) \n", "\n", "### --- Reward objective function using the emulator\n", "obj_func_emulator = lambda x: mc.run_emulation([position_model, velocity_model], x, car_initial_location)[0]\n", "objective_emulator = GPyOpt.core.task.SingleObjective(obj_func_emulator)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "And as before, we use Bayesian optimization to find the best possible\n", "linear controller." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "### --- Elements of the optimization that will use the multi-fidelity emulator\n", "model = GPyOpt.models.GPModel(optimize_restarts=5, verbose=False, exact_feval=True, ARD=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The design space is the three continuous variables that make up the\n", "linear controller." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "space= [{'name':'linear_1', 'type':'continuous', 'domain':(-1/1.2, +1)},\n", " {'name':'linear_2', 'type':'continuous', 'domain':(-1/0.07, +1/0.07)},\n", " {'name':'constant', 'type':'continuous', 'domain':(-1, +1)}]\n", "\n", "design_space = GPyOpt.Design_space(space=space)\n", "aquisition_optimizer = GPyOpt.optimization.AcquisitionOptimizer(design_space)\n", "\n", "random_design = RandomDesign(design_space)\n", "initial_design = random_design.get_samples(25)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We set the acquisition function to be expected improvement using\n", "`GPyOpt`." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "acquisition = GPyOpt.acquisitions.AcquisitionEI(model, design_space, optimizer=aquisition_optimizer)\n", "evaluator = GPyOpt.core.evaluators.Sequential(acquisition)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "bo_emulator = GPyOpt.methods.ModularBayesianOptimization(model, design_space, objective_emulator, acquisition, evaluator, initial_design)\n", "bo_emulator.run_optimization(max_iter=50)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "_, _, _, frames = mc.run_simulation(env, np.atleast_2d(bo_emulator.x_opt), render=True)\n", "anim=mc.animate_frames(frames, 'Best controller using the emulator of the dynamics')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from IPython.core.display import HTML" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "HTML(anim.to_jshtml())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "And the problem is again solved, but in this case we have replaced the\n", "simulator of the car dynamics by a Gaussian process emulator that we\n", "learned by calling the simulator only 500 times. Compared to the 37500\n", "calls that we needed when applying Bayesian optimization directly on the\n", "simulator this is a great gain.\n", "\n", "In some scenarios we have simulators of the same environment that have\n", "different fidelities, that is that reflect with different level of\n", "accuracy the dynamics of the real world. Running simulations of the\n", "different fidelities also have a different cost: hight fidelity\n", "simulations are more expensive the cheaper ones. If we have access to\n", "these simulators we can combine high and low fidelity simulations under\n", "the same model.\n", "\n", "So let's assume that we have two simulators of the mountain car\n", "dynamics, one of high fidelity (the one we have used) and another one of\n", "low fidelity. The traditional approach to this form of multi-fidelity\n", "emulation is to assume that\n", "\n", "$$\\mappingFunction_i\\left(\\inputVector\\right) = \\rho\\mappingFunction_{i-1}\\left(\\inputVector\\right) + \\delta_i\\left(\\inputVector \\right)$$\n", "\n", "where $\\mappingFunction_{i-1}\\left(\\inputVector\\right)$ is a low\n", "fidelity simulation of the problem of interest and\n", "$\\mappingFunction_i\\left(\\inputVector\\right)$ is a higher fidelity\n", "simulation. The function $\\delta_i\\left(\\inputVector \\right)$ represents\n", "the difference between the lower and higher fidelity simulation, which\n", "is considered additive. The additive form of this covariance means that\n", "if $\\mappingFunction_{0}\\left(\\inputVector\\right)$ and\n", "$\\left\\{\\delta_i\\left(\\inputVector \\right)\\right\\}_{i=1}^m$ are all\n", "Gaussian processes, then the process over all fidelities of simuation\n", "will be a joint Gaussian process.\n", "\n", "But with Deep Gaussian processes we can consider the form\n", "\n", "$$\\mappingFunction_i\\left(\\inputVector\\right) = \\mappingFunctionTwo_{i}\\left(\\mappingFunction_{i-1}\\left(\\inputVector\\right)\\right) + \\delta_i\\left(\\inputVector \\right),$$\n", "\n", "where the low fidelity representation is non linearly transformed by\n", "$\\mappingFunctionTwo(\\cdot)$ before use in the process. This is the\n", "approach taken in @Perdikaris:multifidelity17. But once we accept that\n", "these models can be composed, a highly flexible framework can emerge. A\n", "key point is that the data enters the model at different levels, and\n", "represents different aspects. For example these correspond to the two\n", "fidelities of the mountain car simulator.\n", "\n", "We start by sampling both of them at 250 random input locations." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import gym" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "env = gym.make('MountainCarContinuous-v0')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import GPyOpt" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "### --- Collect points from low and high fidelity simulator --- ###\n", "\n", "space = GPyOpt.Design_space([\n", " {'name':'position', 'type':'continuous', 'domain':(-1.2, +1)},\n", " {'name':'velocity', 'type':'continuous', 'domain':(-0.07, +0.07)},\n", " {'name':'action', 'type':'continuous', 'domain':(-1, +1)}])\n", "\n", "n_points = 250\n", "random_design = GPyOpt.experiment_design.RandomDesign(space)\n", "x_random = random_design.get_samples(n_points)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Next, we evaluate the high and low fidelity simualtors at those\n", "locations." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import mountain_car as mc" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "d_position_hf = np.zeros((n_points, 1))\n", "d_velocity_hf = np.zeros((n_points, 1))\n", "d_position_lf = np.zeros((n_points, 1))\n", "d_velocity_lf = np.zeros((n_points, 1))\n", "\n", "# --- Collect high fidelity points\n", "for i in range(0, n_points):\n", " d_position_hf[i], d_velocity_hf[i] = mc.simulation(x_random[i, :])\n", "\n", "# --- Collect low fidelity points \n", "for i in range(0, n_points):\n", " d_position_lf[i], d_velocity_lf[i] = mc.low_cost_simulation(x_random[i, :])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "It is time to build the multi-fidelity model for both the position and\n", "the velocity.\n", "\n", "As we did in the previous section we use the emulator to optimize the\n", "simulator. In this case we use the high fidelity output of the emulator." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "### --- Optimize controller parameters \n", "obj_func = lambda x: mc.run_simulation(env, x)[0]\n", "obj_func_emulator = lambda x: mc.run_emulation([position_model, velocity_model], x, car_initial_location)[0]\n", "objective_multifidelity = GPyOpt.core.task.SingleObjective(obj_func)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "And we optimize using Bayesian optimzation." ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from GPyOpt.experiment_design.random_design import RandomDesign" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "model = GPyOpt.models.GPModel(optimize_restarts=5, verbose=False, exact_feval=True, ARD=True)\n", "space= [{'name':'linear_1', 'type':'continuous', 'domain':(-1/1.2, +1)},\n", " {'name':'linear_2', 'type':'continuous', 'domain':(-1/0.07, +1/0.07)},\n", " {'name':'constant', 'type':'continuous', 'domain':(-1, +1)}]\n", "\n", "design_space = GPyOpt.Design_space(space=space)\n", "aquisition_optimizer = GPyOpt.optimization.AcquisitionOptimizer(design_space)\n", "\n", "n_initial_points = 25\n", "random_design = RandomDesign(design_space)\n", "initial_design = random_design.get_samples(n_initial_points)\n", "acquisition = GPyOpt.acquisitions.AcquisitionEI(model, design_space, optimizer=aquisition_optimizer)\n", "evaluator = GPyOpt.core.evaluators.Sequential(acquisition)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "bo_multifidelity = GPyOpt.methods.ModularBayesianOptimization(model, design_space, objective_multifidelity, acquisition, evaluator, initial_design)\n", "bo_multifidelity.run_optimization(max_iter=50)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "_, _, _, frames = mc.run_simulation(env, np.atleast_2d(bo_multifidelity.x_opt), render=True)\n", "anim=mc.animate_frames(frames, 'Best controller with multi-fidelity emulator')" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "from IPython.core.display import HTML" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "HTML(anim.to_jshtml())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "\n", "And problem solved! We see how the problem is also solved with 250\n", "observations of the high fidelity simulator and 250 of the low fidelity\n", "simulator.\n", "\n", "- *Multi-fidelity emulation*: build surrogate models when data is\n", " obtained from multiple information sources that have different\n", " fidelity and/or cost;\n", "- *Bayesian optimisation*: optimise physical experiments and tune\n", " parameters of machine learning algorithms;\n", "- *Experimental design/Active learning*: design the most informative\n", " experiments and perform active learning with machine learning\n", " models;\n", "- *Sensitivity analysis*: analyse the influence of inputs on the\n", " outputs of a given system;\n", "- *Bayesian quadrature*: efficiently compute the integrals of\n", " functions that are expensive to evaluate.\n", "\n", "
\n", "\n", "\n", "\n", "
\n", "\n", "
\n", "\n", "
\n", "### MxFusion\n", "\n", "\n", "\n", "\n", " \n", " \n", "
\n", "- Work by Eric Meissner and Zhenwen Dai.\n", "- Probabilistic programming.\n", "- Available on [Github](https://github.com/amzn/mxfusion)\n", " \n", " \n", "
\n", "\n", "### MxFusion\n", "\n", "### Why another framework?\n", "\n", "### Key Requirements\n", "\n", "Specialized inference methods + models, without requiring users to\n", "reimplement nor understand them every time. Leverage expert knowledge.\n", "Efficient inference, flexible framework. Existing frameworks either did\n", "one or the other: flexible, or efficient.\n", "\n", "### What does it look like?\n", "\n", "**Modelling**\n", "\n", "**Inference**" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "m = Model()\n", "m.mu = Variable()\n", "m.s = Variable(transformation=PositiveTransformation())\n", "m.Y = Normal.define_variable(mean=m.mu, variance=m.s)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Variable\n", "- Distribution\n", "- Function\n", "\n", "- `log_pdf`\n", "- `draw_samples`\n", "\n", "- Variational Inference\n", "- MCMC Sampling (*soon*) Built on MXNet Gluon (imperative code, not\n", " static graph)" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "infr = GradBasedInference(inference_algorithm=MAP(model=m, observed=[m.Y]))\n", "infr.run(Y=data)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "- Model + Inference together form building blocks.\n", " - Just doing modular modeling with universal inference doesn't\n", " really scale, need specialized inference methods for specialized\n", " modelling objects like non-parametrics.\n", "\n", "### Long term Aim\n", "\n", "- Simulate/Emulate the components of the system.\n", " - Validate with real world using multifidelity.\n", " - Interpret system using e.g. sensitivity analysis.\n", "- Perform end to end learning to optimize.\n", " - Maintain interpretability.\n", "\n", "Stefanos Eleftheriadis, John Bronskill, Hugh Salimbeni, Rich Turner,\n", "Zhenwen Dai, Javier Gonzalez, Andreas Damianou, Mark Pullin, Eric\n", "Meissner.\n", "\n", "- twitter: @lawrennd\n", "- blog:\n", " [http://inverseprobability.com](http://inverseprobability.com/blog.html)\n", "\n", "### References {#references .unnumbered}" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.6.3" } }, "nbformat": 4, "nbformat_minor": 2 }