{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "## Implementing a custom kernel in QPyTorch\n", "\n", "In this notebook we are looking at how to implement a custom kernel in QPyTorch. As an example, we consider the [sinc](https://en.wikipedia.org/wiki/Sinc_function) kernel." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import math\n", "import torch\n", "import qpytorch\n", "from matplotlib import pyplot as plt" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Before we start, let's set up some training data and convenience functions" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "import os\n", "smoke_test = ('CI' in os.environ)\n", "training_iter = 2 if smoke_test else 50\n", "\n", "# Training data is 100 points in [0,1] inclusive regularly spaced\n", "train_x = torch.linspace(0, 1, 100)\n", "# True function is sin(2*pi*x) with Gaussian noise\n", "train_y = torch.sin(train_x * (2 * math.pi)) + torch.randn(train_x.size()) * math.sqrt(0.04)\n", "\n", "# Wrap training, prediction and plotting from the ExactQEP-Tutorial into a function, \n", "# so that we do not have to repeat the code later on\n", "def train(model, likelihood, training_iter=training_iter):\n", " # Use the adam optimizer\n", " optimizer = torch.optim.Adam(model.parameters(), lr=0.1) # Includes QExponentialLikelihood parameters\n", "\n", " # \"Loss\" for QEPs - the marginal log likelihood\n", " mll = qpytorch.mlls.ExactMarginalLogLikelihood(likelihood, model)\n", "\n", " for i in range(training_iter):\n", " # Zero gradients from previous iteration\n", " optimizer.zero_grad()\n", " # Output from model\n", " output = model(train_x)\n", " # Calc loss and backprop gradients\n", " loss = -mll(output, train_y)\n", " loss.backward()\n", " optimizer.step()\n", " \n", "\n", "def predict(model, likelihood, test_x = torch.linspace(0, 1, 51)):\n", " model.eval()\n", " likelihood.eval()\n", " # Make predictions by feeding model through likelihood\n", " with torch.no_grad(), qpytorch.settings.fast_pred_var():\n", " # Test points are regularly spaced along [0,1]\n", " return likelihood(model(test_x))\n", "\n", "def plot(observed_pred, test_x=torch.linspace(0, 1, 51)):\n", " with torch.no_grad():\n", " # Initialize plot\n", " f, ax = plt.subplots(1, 1, figsize=(4, 3))\n", "\n", " # Get upper and lower confidence bounds\n", " lower, upper = observed_pred.confidence_region(rescale=True)\n", " # Plot training data as black stars\n", " ax.plot(train_x.numpy(), train_y.numpy(), 'k*')\n", " # Plot predictive means as blue line\n", " ax.plot(test_x.numpy(), observed_pred.mean.numpy(), 'b')\n", " # Shade between the lower and upper confidence bounds\n", " ax.fill_between(test_x.numpy(), lower.numpy(), upper.numpy(), alpha=0.5)\n", " ax.set_ylim([-3, 3])\n", " ax.legend(['Observed Data', 'Mean', 'Confidence'])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### A first kernel\n", "\n", "To implement a custom kernel, we derive one from QPyTorch's [kernel class](https://qepytorch.readthedocs.io/en/stable/kernels.html) and implement the `forward()` method. The base class provides many useful routines. For example, `__call__()` is implemented, so that the kernel may be called directly, without resorting to the `forward()` routine. Among other things, the `Kernel` class provides a method `covar_dist()`, which may be used to calculate the Euclidian distance between point pairs conveniently.\n", "\n", "The `forward()` method represents the kernel function and should return a `torch.tensor` or a `linear_operator.operators.LinearOperator`, when called on two `torch.tensor`s:" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "class FirstSincKernel(qpytorch.kernels.Kernel):\n", " # the sinc kernel is stationary\n", " is_stationary = True\n", "\n", " # this is the kernel function\n", " def forward(self, x1, x2, **params):\n", " # calculate the distance between inputs\n", " diff = self.covar_dist(x1, x2, **params)\n", " # prevent divide by 0 errors\n", " diff.where(diff == 0, torch.as_tensor(1e-20))\n", " # return sinc(diff) = sin(diff) / diff\n", " return torch.sin(diff).div(diff)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can now already use this kernel. We therefore define a QEP-model, similar to the tutorial on exact QEP inference:" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "# Use the simplest form of QEP model, exact inference\n", "POWER = 1.0\n", "class FirstQEPModel(qpytorch.models.ExactQEP):\n", " def __init__(self, train_x, train_y, likelihood):\n", " super().__init__(train_x, train_y, likelihood)\n", " self.power = torch.tensor(POWER)\n", " self.mean_module = qpytorch.means.ConstantMean()\n", " self.covar_module = FirstSincKernel()\n", "\n", " def forward(self, x):\n", " mean_x = self.mean_module(x)\n", " covar_x = self.covar_module(x)\n", " return qpytorch.distributions.MultivariateQExponential(mean_x, covar_x, power=self.power)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "By using the convenience routines from above, the model can be trained and evaluated:" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAWgAAAEYCAYAAABxx2wUAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAAPYQAAD2EBqD+naQAAUbpJREFUeJztnXd4VGXaxu8zM5mWNklIzyQhCR0CEgQpCooKrovifnYWwe4CFlgVXVexsaC4duyFFWFREFYFRGkBQakSCBBCeoH0ZNKmZWbe74+TGTLJ9GSSSfL8rmsumNPe9ySZe57zvE/hGGMMBEEQhM8h6OkJEARBELYhgSYIgvBRSKAJgiB8FBJogiAIH4UEmiAIwkchgSYIgvBRSKAJgiB8FBJogiAIH4UEmiAIwkchgSYIgvBRvCrQH374IVJTUxEUFISgoCBMnDgRP/30kzeHJAiC6DNw3qzF8eOPP0IoFGLQoEFgjOE///kPVq1ahRMnTmDEiBHeGpYgCKJP4FWBtkVoaChWrVqF+++/vzuHJQiC6HWIumsgo9GIjRs3orm5GRMnTrR5jE6ng06ns7w3mUyora1FWFgYOI7rrqkSBEF4DcYYGhsbERMTA4HAiZeZeZlTp04xf39/JhQKWXBwMNu2bZvdY5ctW8YA0Ite9KJXn3+VlJQ41U+vuzj0ej2Ki4tRX1+PTZs24bPPPsO+ffswfPjwDse2t6Dr6+sRHx+PkpISBAUFeXOaBEEQ3UJDQwOUSiVUKhWCg4MdHtvtPuhrr70WycnJ+Pjjj50e29DQgODgYNTX15NAEwTRJ3BH17o9DtpkMllZyQRBEIRtvLpI+Oyzz+KGG25AfHw8GhsbsX79eqSnp+Pnn3/25rAEQRB9Aq8KdGVlJe655x6UlZUhODgYqamp+Pnnn3Hdddd5c1iCIIg+gVcF+vPPP/fm5QnCY0wmE/R6fU9Pg+iD+Pn5QSgUdsm1ui0OmiB8Bb1ej4KCAphMpp6eCtFHUSgUiIqK6nT+Bgk00a9gjKGsrAxCoRBKpdJ5ogBBuAFjDGq1GpWVlQCA6OjoTl2PBJroVxgMBqjVasTExEAul/f0dIg+iEwmA8CvwUVERHTK3UHmA9GvMBqNAACxWNzDMyH6MuYv/5aWlk5dhwSa6JdQbRfCm3TV3xcJNEEQhI9CAk0QfYzExES8/fbbPT2NLqOv3Y87kEATRC+hpKQE9913H2JiYiAWi5GQkIDHH38cNTU1PT21HuXFF18Ex3HgOA4ikQgDBgzAVVddhbffftvtshLp6engOA4qlco7k3UTEmiC8JBjx47hmmuuwbFjx7w+Vn5+PsaNG4ecnBz897//RW5uLj766CPs3r0bEydORG1trdfnYA+j0djjMeUjRoxAWVkZiouLsXfvXtx2221YsWIFJk2ahMbGxh6dW2cggSYID/nqq6+wd+9erF271utjLVy4EGKxGL/88gumTp2K+Ph43HDDDdi1axcuXLiA5557zur4xsZG3HXXXfD390dsbCxWr15t2ccYw4svvoj4+HhIJBLExMTgscces+zX6XR48sknERsbC39/f0yYMAHp6emW/WvWrIFCocAPP/yA4cOHQyKR4LPPPoNUKu1geT7++OO45pprLO8PHDiAK6+8EjKZDEqlEo899hiam5st+ysrKzFr1izIZDIMHDgQ69atc+nnIxKJEBUVhZiYGIwaNQqPPvoo9u3bh9OnT+O1116zHLd27VqMGzcOgYGBiIqKwt13322JWS4sLMTVV18NAAgJCQHHcZg/fz4AYMeOHZgyZQoUCgXCwsLw5z//GXl5eS7NrVN0SVV+L1FfX88AsPr6+p6eCtFH0Gg07OzZs0yj0Xh0fmFhITt27Bg7fvw4i4iIYABYREQEO378ODt27BgrLCzs4hkzVlNTwziOY//6179s7n/wwQdZSEgIM5lMjDHGEhISWGBgIFuxYgXLzs5m7777LhMKheyXX35hjDG2ceNGFhQUxLZv386KiorY4cOH2SeffGK53gMPPMAmTZrE9u/fz3Jzc9mqVauYRCJh58+fZ4wx9uWXXzI/Pz82adIkdvDgQXbu3DnW1NTEIiMj2WeffWa5jsFgsNqWm5vL/P392VtvvcXOnz/PDh48yC677DI2f/58yzk33HADGz16NPv999/ZsWPH2KRJk5hMJmNvvfWW3Z/PsmXL2OjRo23uu/nmm9mwYcMs7z///HO2fft2lpeXx37//Xc2ceJEdsMNN1jm+9133zEALDs7m5WVlTGVSsUYY2zTpk3su+++Yzk5OezEiRNs1qxZbNSoUcxoNNoc19HfmTu6RgJN9Cs6K9Bo0xGD4zirf82vrubQoUMMANuyZYvN/W+++SYDwCoqKhhjvEDPnDnT6pg77rjD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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# initialize likelihood and model\n", "likelihood = qpytorch.likelihoods.QExponentialLikelihood(power=torch.tensor(POWER))\n", "model = FirstQEPModel(train_x, train_y, likelihood)\n", "\n", "# set to training mode and train\n", "model.train()\n", "likelihood.train()\n", "train(model, likelihood)\n", "\n", "# Get into evaluation (predictive posterior) mode and predict\n", "model.eval()\n", "likelihood.eval()\n", "observed_pred = predict(model, likelihood)\n", "# plot results\n", "plot(observed_pred)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Clearly, the kernel doesn't perform well. This is due to the lack of a lengthscale parameter, which we will add next." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Adding hyperparameters\n", "\n", "Although the `FirstSincKernel` can be used for defining a model, it lacks a parameter that controls the correlation length. This lengthscale will be implemented as a hyperparameter. See also the [tutorial on hyperparamaters](https://qepytorch.readthedocs.io/en/stable/examples/00_Basic_Usage/Hyperparameters.html), for information on raw vs. actual parameters.\n", "\n", "The parameter has to be registered, using the method `register_parameter()`, which `Kernel` inherits from `Module`. Similarly, we register constraints and priors." ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "# import positivity constraint\n", "from qpytorch.constraints import Positive\n", "\n", "class SincKernel(qpytorch.kernels.Kernel):\n", " # the sinc kernel is stationary\n", " is_stationary = True\n", " \n", " # We will register the parameter when initializing the kernel\n", " def __init__(self, length_prior=None, length_constraint=None, **kwargs):\n", " super().__init__(**kwargs)\n", " \n", " # register the raw parameter\n", " self.register_parameter(\n", " name='raw_length', parameter=torch.nn.Parameter(torch.zeros(*self.batch_shape, 1, 1))\n", " )\n", " \n", " # set the parameter constraint to be positive, when nothing is specified\n", " if length_constraint is None:\n", " length_constraint = Positive()\n", "\n", " # register the constraint\n", " self.register_constraint(\"raw_length\", length_constraint)\n", " \n", " # set the parameter prior, see\n", " # https://qepytorch.readthedocs.io/en/stable/module.html#qpytorch.Module.register_prior\n", " if length_prior is not None:\n", " self.register_prior(\n", " \"length_prior\",\n", " length_prior,\n", " lambda m: m.length,\n", " lambda m, v : m._set_length(v),\n", " )\n", "\n", " # now set up the 'actual' paramter\n", " @property\n", " def length(self):\n", " # when accessing the parameter, apply the constraint transform\n", " return self.raw_length_constraint.transform(self.raw_length)\n", "\n", " @length.setter\n", " def length(self, value):\n", " return self._set_length(value)\n", "\n", " def _set_length(self, value):\n", " if not torch.is_tensor(value):\n", " value = torch.as_tensor(value).to(self.raw_length)\n", " # when setting the paramater, transform the actual value to a raw one by applying the inverse transform\n", " self.initialize(raw_length=self.raw_length_constraint.inverse_transform(value))\n", "\n", " # this is the kernel function\n", " def forward(self, x1, x2, **params):\n", " # apply lengthscale\n", " x1_ = x1.div(self.length)\n", " x2_ = x2.div(self.length)\n", " # calculate the distance between inputs\n", " diff = self.covar_dist(x1_, x2_, **params)\n", " # prevent divide by 0 errors\n", " diff.where(diff == 0, torch.as_tensor(1e-20))\n", " # return sinc(diff) = sin(diff) / diff\n", " return torch.sin(diff).div(diff)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We can now define a new QEPModel, train it and make predictions:" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# Use the simplest form of QEP model, exact inference\n", "class SincQEPModel(qpytorch.models.ExactQEP):\n", " def __init__(self, train_x, train_y, likelihood):\n", " super().__init__(train_x, train_y, likelihood)\n", " self.power = torch.tensor(POWER)\n", " self.mean_module = qpytorch.means.ConstantMean()\n", " self.covar_module = SincKernel()\n", "\n", " def forward(self, x):\n", " mean_x = self.mean_module(x)\n", " covar_x = self.covar_module(x)\n", " return qpytorch.distributions.MultivariateQExponential(mean_x, covar_x, power=self.power)\n", "\n", "# initialize the new model\n", "model = SincQEPModel(train_x, train_y, likelihood)\n", "\n", "# set to training mode and train\n", "model.train()\n", "likelihood.train()\n", "train(model, likelihood)\n", "\n", "# Get into evaluation (predictive posterior) mode and predict\n", "model.eval()\n", "likelihood.eval()\n", "observed_pred = predict(model, likelihood)\n", "# plot results\n", "plot(observed_pred)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Because many kernels use a lengthscale, there is actually a simpler way to implement it, by using the `has_lengthscale` attribute from `Kernel`." ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAWgAAAEYCAYAAABxx2wUAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAAPYQAAD2EBqD+naQAAWw5JREFUeJzt3Xd4k1X7wPFvmjTp3pu2lL1nGTIUFBCVF8EJ2hdBEfwpLlBRX1/FhSD4KiqIC0WWIAiCbEQKAjLKklFGgQ5KSxddtE1Hzu+PkNC0aZuUpoRyPteVqzbPkzznofXuyRn3rRBCCCRJkiS743CjGyBJkiSZJwO0JEmSnZIBWpIkyU7JAC1JkmSnZICWJEmyUzJAS5Ik2SkZoCVJkuyUDNCSJEl2SgZoSZIkOyUDtCRJkp2yaYCeO3cuHTt2xMPDAw8PD3r16sWGDRtseUlJkqQGQ2HLXBy///47SqWSFi1aIITgp59+YubMmRw6dIh27drZ6rKSJEkNgk0DtDk+Pj7MnDmTsWPH1udlJUmSbjqq+rpQWVkZy5cv58qVK/Tq1cvsOVqtFq1Wa/xep9ORlZWFr68vCoWivpoqSZJkM0II8vLyCAkJwcGhhlFmYWP//POPcHV1FUqlUnh6eop169ZVee6UKVMEIB/yIR/y0eAfSUlJNcZPmw9xFBcXk5iYSE5ODitWrOD7779n+/bttG3bttK5FXvQOTk5hIeHk5SUhIeHhy2bKUmSVC9yc3MJCwsjOzsbT0/Pas+t9zHogQMH0qxZM7755psaz83NzcXT05OcnBwZoCVJahCsiWv1vg5ap9OZ9JIlSZIk82w6Sfjmm29y7733Eh4eTl5eHkuWLCE6OppNmzbZ8rKSJEkNgk0DdFpaGk888QQpKSl4enrSsWNHNm3axKBBg2x5WUmSpAbBpgF63rx5tnx7Sao1nU5HcXHxjW6G1AA5OjqiVCrr5L3qbR20JNmL4uJizp8/j06nu9FNkRooLy8vgoKCrnv/hgzQ0i1FCEFKSgpKpZKwsLCaNwpIkhWEEBQUFJCWlgZAcHDwdb2fDNDSLaW0tJSCggJCQkJwcXG50c2RGiBnZ2dAPwcXEBBwXcMdsvsg3VLKysoAUKvVN7glUkNm+ONfUlJyXe8jA7R0S5K5XSRbqqvfLxmgJUmS7JQM0JLUwERERDBr1qwb3Yw609DuxxoyQEvSTSIpKYmnnnqKkJAQ1Go1jRs35qWXXiIzM/NGN+2Gevfdd1EoFCgUClQqFX5+ftxxxx3MmjXL6rQS0dHRKBQKsrOzbdNYK8kALUm1FBMTw1133UVMTIzNr3Xu3Dm6devGmTNn+Pnnn4mLi+Prr79m69at9OrVi6ysLJu3oSplZWU3fE15u3btSElJITExkW3btvHII48wbdo0evfuTV5e3g1t2/WQAVqSamnBggVs27aNhQsX2vxaEyZMQK1Ws3nzZvr160d4eDj33nsvf/zxB8nJybz11lsm5+fl5fHYY4/h6upKo0aNmDNnjvGYEIJ3332X8PBwNBoNISEhvPjii8bjWq2WV199lUaNGuHq6krPnj2Jjo42Hp8/fz5eXl6sWbOGtm3botFo+P7773FycqrU83zppZe46667jN/v3LmT22+/HWdnZ8LCwnjxxRe5cuWK8XhaWhpDhw7F2dmZJk2asHjxYov+fVQqFUFBQYSEhNChQwdeeOEFtm/fzrFjx/j444+N5y1cuJBu3brh7u5OUFAQjz/+uHHNcnx8PHfeeScA3t7eKBQKxowZA8DGjRvp27cvXl5e+Pr68q9//YuzZ89a1LbrUidZ+W0kJydHACInJ+dGN0VqIAoLC8WJEydEYWFhrV4fHx8vYmJixIEDB0RAQIAAREBAgDhw4ICIiYkR8fHxddxiITIzM4VCoRAfffSR2ePjxo0T3t7eQqfTCSGEaNy4sXB3dxfTpk0Tp06dEl988YVQKpVi8+bNQgghli9fLjw8PMT69etFQkKC2Lt3r/j222+N7/f000+L3r17ix07doi4uDgxc+ZModFoxOnTp4UQQvz444/C0dFR9O7dW+zatUucPHlS5Ofni8DAQPH9998b36e0tNTkubi4OOHq6io+++wzcfr0abFr1y7RpUsXMWbMGONr7r33XtGpUyfx999/i5iYGNG7d2/h7OwsPvvssyr/faZMmSI6depk9tiwYcNEmzZtjN/PmzdPrF+/Xpw9e1b8/fffolevXuLee+81tvfXX38VgDh16pRISUkR2dnZQgghVqxYIX799Vdx5swZcejQITF06FDRoUMHUVZWZva61f2eWRPXZICWbinXG6ApVxFDoVCYfDU86tqePXsEIFatWmX2+KeffioAcenSJSGEPkDfc889JueMGDHCGIj+97//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\n", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "class SimpleSincKernel(qpytorch.kernels.Kernel):\n", " has_lengthscale = True\n", " \n", " # this is the kernel function\n", " def forward(self, x1, x2, **params):\n", " # apply lengthscale\n", " x1_ = x1.div(self.lengthscale)\n", " x2_ = x2.div(self.lengthscale)\n", " # calculate the distance between inputs\n", " diff = self.covar_dist(x1_, x2_, **params)\n", " # prevent divide by 0 errors\n", " diff.where(diff == 0, torch.as_tensor(1e-20))\n", " # return sinc(diff) = sin(diff) / diff\n", " return torch.sin(diff).div(diff)\n", "\n", "# Use the simplest form of QEP model, exact inference\n", "class SimpleSincQEPModel(qpytorch.models.ExactQEP):\n", " def __init__(self, train_x, train_y, likelihood):\n", " super().__init__(train_x, train_y, likelihood)\n", " self.power = torch.tensor(POWER)\n", " self.mean_module = qpytorch.means.ConstantMean()\n", " self.covar_module = SimpleSincKernel()\n", "\n", " def forward(self, x):\n", " mean_x = self.mean_module(x)\n", " covar_x = self.covar_module(x)\n", " return qpytorch.distributions.MultivariateQExponential(mean_x, covar_x, power=self.power)\n", "\n", "# initialize the new model\n", "model = SimpleSincQEPModel(train_x, train_y, likelihood)\n", "\n", "# set to training mode and train\n", "model.train()\n", "likelihood.train()\n", "train(model, likelihood)\n", "\n", "# Get into evaluation (predictive posterior) mode and predict\n", "model.eval()\n", "likelihood.eval()\n", "observed_pred = predict(model, likelihood)\n", "# plot results\n", "plot(observed_pred)" ] } ], "metadata": { "kernelspec": { "display_name": "Python 3 (ipykernel)", "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.12.12" } }, "nbformat": 4, "nbformat_minor": 4 }