From 36fdea9e0d2ec1e207713931725ec0d111934168 Mon Sep 17 00:00:00 2001 From: Ankush Aggarwal Date: Tue, 8 Jun 2021 23:48:19 +0100 Subject: [PATCH 1/4] Added an indexed version of the VariationalStrategy class that allows functional values and derivative values at different locations to be used in model training (and prediction) --- .../08_Advanced_Usage/variationalGP-derivs.py | 124 +++++++++++++++ gpytorch/variational/__init__.py | 3 +- gpytorch/variational/variational_strategy.py | 147 +++++++++++++++++- 3 files changed, 272 insertions(+), 2 deletions(-) create mode 100644 examples/08_Advanced_Usage/variationalGP-derivs.py diff --git a/examples/08_Advanced_Usage/variationalGP-derivs.py b/examples/08_Advanced_Usage/variationalGP-derivs.py new file mode 100644 index 000000000..ddccfc3af --- /dev/null +++ b/examples/08_Advanced_Usage/variationalGP-derivs.py @@ -0,0 +1,124 @@ +import torch +import sys +from os.path import dirname, abspath +sys.path.insert(0,dirname(dirname(dirname(abspath(__file__))))) +import gpytorch +import math +from matplotlib import pyplot as plt +import numpy as np + +lb, ub = 0.0, 1. #5*math.pi +n1 = 40 #function values +freq = 0.4 #frequency of the size function +train_x1 = torch.linspace(lb, ub, n1)#.unsqueeze(-1) +train_y1 = torch.sin(freq*train_x1) + 0.005 * torch.randn(train_x1.size()) + +n2=50 #derivative values at different x locations +train_x2 = torch.linspace(lb, ub, n2)#.unsqueeze(-1) +train_y2 = freq*torch.cos(freq*train_x2) + 0.005 * torch.randn(train_x2.size()) + +train_x = torch.cat([train_x1 , train_x2]) +train_y = torch.cat([train_y1,train_y2]) + +ndata,ndim = train_x.shape.numel(),1 +train_index = torch.empty(ndata,ndim+1,dtype=bool) +train_index[:n1,0]=True +train_index[:n1,1]=False +train_index[n1:,0]=False +train_index[n1:,1]=True + +from gpytorch.models import ApproximateGP +from gpytorch.variational import CholeskyVariationalDistribution +from gpytorch.variational import VariationalStrategyIndexed + +class GPModel(ApproximateGP): + def __init__(self): + inducing_points = torch.rand(15)*ub + inducing_index = torch.ones(15,ndim+1,dtype=bool) + variational_distribution = CholeskyVariationalDistribution(torch.sum(inducing_index).item()) + variational_strategy = VariationalStrategyIndexed( + self, inducing_points, variational_distribution, inducing_index, learn_inducing_locations=True + ) + super(GPModel, self).__init__(variational_strategy) + self.mean_module = gpytorch.means.ConstantMeanGrad() + self.covar_module = gpytorch.kernels.ScaleKernel(gpytorch.kernels.RBFKernelGrad()) + + def forward(self, x, index): + index = index.reshape(-1) + mean_x = self.mean_module(x).reshape(-1)[index] + full_kernel = self.covar_module(x) + covar_x = full_kernel[..., index,:][...,:,index] + return gpytorch.distributions.MultivariateNormal(mean_x, covar_x) + +gpytorch.linear_operator.settings.debug._default = False + +likelihood = gpytorch.likelihoods.GaussianLikelihood() +model = GPModel() +# this is for running the notebook in our testing framework +import os +smoke_test = ('CI' in os.environ) +training_iter = 2 if smoke_test else 50 + +# Find optimal model hyperparameters +model.train() +likelihood.train() + +# Use the adam optimizer +optimizer = torch.optim.Adam([ + {'params': model.parameters()}, + {'params': likelihood.parameters()}, +], lr=0.1) + +# "Loss" for GPs - the marginal log likelihood +mll = gpytorch.mlls.ExactMarginalLogLikelihood(likelihood, model) +mll = gpytorch.mlls.VariationalELBO(likelihood, model, num_data=train_y.size(0)) +#print(train_y) +#output = model(train_x1,train_x2) +#loss = -mll(output, train_y) +#loss.backward() + +for i in range(training_iter): + optimizer.zero_grad() + output = model(train_x,x_index=train_index) + loss = -mll(output, train_y) + loss.backward() + print('Iter %d/%d - Loss: %.3f' % (i + 1, training_iter, loss.item())) + optimizer.step() + + +# Set into eval mode +model.eval() +likelihood.eval() + +# Initialize plots +f, (y1_ax, y2_ax) = plt.subplots(1, 2, figsize=(12, 6)) + +n11=200 +test_x = torch.linspace(lb, ub, n11) +test_index = torch.ones(test_x.shape[0],ndim+1,dtype=bool) + +# Make predictions +with torch.no_grad(), gpytorch.settings.max_cg_iterations(50): + predictions = likelihood(model(test_x,x_index=test_index)) + mean = predictions.mean + lower, upper = predictions.confidence_region() + +# Plot training data as black stars +y1_ax.plot(train_x[:n1].detach().numpy(), train_y[:n1].detach().numpy(), 'k*') +# Predictive mean as blue line +y1_ax.plot(test_x.detach().numpy(), mean[::2].detach().numpy(), 'b') +# Shade in confidence +y1_ax.fill_between(test_x.detach().numpy(), lower[::2].detach().numpy(), upper[::2].detach().numpy(), alpha=0.5) +y1_ax.legend(['Observed Values', 'Mean', 'Confidence']) +y1_ax.set_title('Function values') + +# Plot training data as black stars +y2_ax.plot(train_x[n1:].detach().numpy(), train_y[n1:].detach().numpy(), 'k*') +# Predictive mean as blue line +y2_ax.plot(test_x.detach().numpy(), mean[1::2].detach().numpy(), 'b') +# Shade in confidence +y2_ax.fill_between(test_x.detach().numpy(), lower[1::2].detach().numpy(), upper[1::2].detach().numpy(), alpha=0.5) +y2_ax.legend(['Observed Derivatives', 'Mean', 'Confidence']) +y2_ax.set_title('Derivatives') + +plt.show() diff --git a/gpytorch/variational/__init__.py b/gpytorch/variational/__init__.py index 69e10d2e0..25741f9eb 100644 --- a/gpytorch/variational/__init__.py +++ b/gpytorch/variational/__init__.py @@ -19,10 +19,11 @@ from .orthogonally_decoupled_variational_strategy import OrthogonallyDecoupledVariationalStrategy from .tril_natural_variational_distribution import TrilNaturalVariationalDistribution from .unwhitened_variational_strategy import UnwhitenedVariationalStrategy -from .variational_strategy import VariationalStrategy +from .variational_strategy import VariationalStrategy, VariationalStrategyIndexed __all__ = [ "_VariationalStrategy", + "_VariationalStrategyIndexed", "AdditiveGridInterpolationVariationalStrategy", "BatchDecoupledVariationalStrategy", "CiqVariationalStrategy", diff --git a/gpytorch/variational/variational_strategy.py b/gpytorch/variational/variational_strategy.py index 6701f7643..8ba036b23 100644 --- a/gpytorch/variational/variational_strategy.py +++ b/gpytorch/variational/variational_strategy.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 - +import inspect import warnings import torch @@ -244,3 +244,148 @@ def __call__(self, x, prior=False, **kwargs): self.updated_strategy.fill_(True) return super().__call__(x, prior=prior, **kwargs) + + +class VariationalStrategyIndexed(_VariationalStrategy): + r""" + This is an Indexed version of the VariationalStrategy that can be + used with function and derivative values at different locations + + :param ~gpytorch.models.ApproximateGP model: Model this strategy is applied to. + Typically passed in when the VariationalStrategy is created in the + __init__ method of the user defined model. + :param torch.Tensor inducing_points: Tensor containing a set of inducing + points to use for variational inference. + :param ~gpytorch.variational.VariationalDistribution variational_distribution: A + VariationalDistribution object that represents the form of the variational distribution :math:`q(\mathbf u)` + :param torch.Tensor inducing_index: Boolean Tensor containing True/False flags at inducing + points for functiona/derivatives to be used for slicing the full covariance matrix. + :param learn_inducing_locations: (Default True): Whether or not + the inducing point locations :math:`\mathbf Z` should be learned (i.e. are they + parameters of the model). + :type learn_inducing_locations: `bool`, optional + + .. _Hensman et al. (2015): + http://proceedings.mlr.press/v38/hensman15.pdf + .. _Matthews (2017): + https://www.repository.cam.ac.uk/handle/1810/278022 + """ + + def __init__( + self, + model, + inducing_points, + variational_distribution, + inducing_index, + learn_inducing_locations=True, + jitter_val=None, + ): + super().__init__( + model, inducing_points, variational_distribution, learn_inducing_locations, jitter_val=jitter_val + ) + self.inducing_index = inducing_index + self.register_buffer("updated_strategy", torch.tensor(True)) + self._register_load_state_dict_pre_hook(_ensure_updated_strategy_flag_set) + self.has_fantasy_strategy = True + + @cached(name="cholesky_factor", ignore_args=True) + def _cholesky_factor(self, induc_induc_covar): + L = psd_safe_cholesky(to_dense(induc_induc_covar).type(_linalg_dtype_cholesky.value())) + return TriangularLinearOperator(L) + + @property + @cached(name="prior_distribution_memo") + def prior_distribution(self): + zeros = torch.zeros( + self._variational_distribution.shape(), + dtype=self._variational_distribution.dtype, + device=self._variational_distribution.device, + ) + ones = torch.ones_like(zeros) + res = MultivariateNormal(zeros, DiagLinearOperator(ones)) + return res + + def forward(self, x, inducing_points, inducing_values, variational_inducing_covar=None, x_index=None, **kwargs): + # Compute full prior distribution + full_inputs = torch.cat([inducing_points, x], dim=-2) + full_indices = torch.cat([self.inducing_index, x_index], dim=-2) + full_output = self.model.forward(full_inputs, full_indices, **kwargs) + full_covar = full_output.lazy_covariance_matrix + + # Covariance terms + num_induc = torch.sum(self.inducing_index).item() + test_mean = full_output.mean[..., num_induc:] + induc_induc_covar = full_covar[..., :num_induc, :num_induc].add_jitter(self.jitter_val) + induc_data_covar = full_covar[..., :num_induc, num_induc:].to_dense() + data_data_covar = full_covar[..., num_induc:, num_induc:] + + # Compute interpolation terms + # K_ZZ^{-1/2} K_ZX + # K_ZZ^{-1/2} \mu_Z + L = self._cholesky_factor(induc_induc_covar) + if L.shape != induc_induc_covar.shape: + # Aggressive caching can cause nasty shape incompatibilies when evaluating with different batch shapes + # TODO: Use a hook fo this + try: + pop_from_cache_ignore_args(self, "cholesky_factor") + except CachingError: + pass + L = self._cholesky_factor(induc_induc_covar) + interp_term = L.solve(induc_data_covar.type(_linalg_dtype_cholesky.value())).to(full_inputs.dtype) + + # Compute the mean of q(f) + # k_XZ K_ZZ^{-1/2} (m - K_ZZ^{-1/2} \mu_Z) + \mu_X + predictive_mean = (interp_term.transpose(-1, -2) @ inducing_values.unsqueeze(-1)).squeeze(-1) + test_mean + + # Compute the covariance of q(f) + # K_XX + k_XZ K_ZZ^{-1/2} (S - I) K_ZZ^{-1/2} k_ZX + middle_term = self.prior_distribution.lazy_covariance_matrix.mul(-1) + if variational_inducing_covar is not None: + middle_term = SumLinearOperator(variational_inducing_covar, middle_term) + + if trace_mode.on(): + predictive_covar = ( + data_data_covar.add_jitter(self.jitter_val).to_dense() + + interp_term.transpose(-1, -2) @ middle_term.to_dense() @ interp_term + ) + else: + predictive_covar = SumLinearOperator( + data_data_covar.add_jitter(self.jitter_val), + MatmulLinearOperator(interp_term.transpose(-1, -2), middle_term @ interp_term), + ) + + # Return the distribution + return MultivariateNormal(predictive_mean, predictive_covar) + + def __call__(self, x, prior=False, **kwargs): + if not self.updated_strategy.item() and not prior: + with torch.no_grad(): + # Get unwhitened p(u) + prior_function_dist = self(self.inducing_points, prior=True) + prior_mean = prior_function_dist.loc + L = self._cholesky_factor(prior_function_dist.lazy_covariance_matrix.add_jitter(self.jitter_val)) + + # Temporarily turn off noise that's added to the mean + orig_mean_init_std = self._variational_distribution.mean_init_std + self._variational_distribution.mean_init_std = 0.0 + + # Change the variational parameters to be whitened + variational_dist = self.variational_distribution + mean_diff = (variational_dist.loc - prior_mean).unsqueeze(-1).type(_linalg_dtype_cholesky.value()) + whitened_mean = L.solve(mean_diff).squeeze(-1).to(variational_dist.loc.dtype) + covar_root = variational_dist.lazy_covariance_matrix.root_decomposition().root.to_dense() + covar_root = covar_root.type(_linalg_dtype_cholesky.value()) + whitened_covar = RootLinearOperator(L.solve(covar_root).to(variational_dist.loc.dtype)) + whitened_variational_distribution = variational_dist.__class__(whitened_mean, whitened_covar) + self._variational_distribution.initialize_variational_distribution(whitened_variational_distribution) + + # Reset the random noise parameter of the model + self._variational_distribution.mean_init_std = orig_mean_init_std + + # Reset the cache + clear_cache_hook(self) + + # Mark that we have updated the variational strategy + self.updated_strategy.fill_(True) + + return super().__call__(x, prior=prior, **kwargs) From 4cf5b1918c6b653dbcd1bd8fb89081b4b5aac299 Mon Sep 17 00:00:00 2001 From: Ankush Aggarwal Date: Thu, 5 Aug 2021 14:34:12 +0100 Subject: [PATCH 2/4] Added an example --- ...P_Derivative_Information_MonotonicGP.ipynb | 1621 +++++++++++++++++ 1 file changed, 1621 insertions(+) create mode 100644 examples/08_Advanced_Usage/ApproxGP_Derivative_Information_MonotonicGP.ipynb diff --git a/examples/08_Advanced_Usage/ApproxGP_Derivative_Information_MonotonicGP.ipynb b/examples/08_Advanced_Usage/ApproxGP_Derivative_Information_MonotonicGP.ipynb new file mode 100644 index 000000000..82ec674f9 --- /dev/null +++ b/examples/08_Advanced_Usage/ApproxGP_Derivative_Information_MonotonicGP.ipynb @@ -0,0 +1,1621 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "9f2efb2d", + "metadata": {}, + "source": [ + "# Training an approximate GP with derivatives\n", + "\n", + "In this notebook, we will train an approximate GP with function values and derivatives, although at different locations. " + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "573fa727", + "metadata": {}, + "outputs": [], + "source": [ + "import torch\n", + "import gpytorch\n", + "import math\n", + "from matplotlib import pyplot as plt\n", + "import numpy as np" + ] + }, + { + "cell_type": "markdown", + "id": "7f78e5b0", + "metadata": {}, + "source": [ + "First we create the training data from a sine function with some added noise. Importantly, the function observations and the derivative observations are at different locations." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "a5efdfeb", + "metadata": {}, + "outputs": [], + "source": [ + "lb, ub = 0., 1. \n", + "freq = 0.4 #frequency of the size function\n", + "\n", + "n1 = 40 #function values\n", + "train_x1 = torch.linspace(lb, ub, n1)#.unsqueeze(-1)\n", + "train_y1 = torch.sin(freq*train_x1) + 0.005 * torch.randn(train_x1.size())\n", + "\n", + "n2=50 #derivative values at different x locations\n", + "train_x2 = torch.linspace(lb, ub, n2)#.unsqueeze(-1)\n", + "train_y2 = freq*torch.cos(freq*train_x2) + 0.005 * torch.randn(train_x2.size())\n", + "\n", + "train_x = torch.cat([train_x1 , train_x2])\n", + "train_y = torch.cat([train_y1,train_y2])\n", + "\n", + "ndata,ndim = train_x.shape.numel(),1" + ] + }, + { + "cell_type": "markdown", + "id": "3bc0bab7", + "metadata": {}, + "source": [ + "Since the model needs to differentiate between the two types of locations, we crate an array of boolean indices of shape `ndata,ndim+1` that indicate what observations are at each element of `train_x` (i.e., we allow one location to have both function and derivative observations)" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "5c8ee43b", + "metadata": {}, + "outputs": [], + "source": [ + "train_index = torch.empty(ndata,ndim+1,dtype=bool)\n", + "train_index[:n1,0]=True\n", + "train_index[:n1,1]=False\n", + "train_index[n1:,0]=False\n", + "train_index[n1:,1]=True" + ] + }, + { + "cell_type": "markdown", + "id": "d39acc9f", + "metadata": {}, + "source": [ + "Next, we define an Approximate GP with Cholesky Variational distribution and the indexed version of the `VariationalStrategy`, called `VariationalStrategyIndexed`" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "5599ceba", + "metadata": { + "lines_to_next_cell": 1 + }, + "outputs": [], + "source": [ + "from gpytorch.models import ApproximateGP\n", + "from gpytorch.variational import CholeskyVariationalDistribution\n", + "from gpytorch.variational import VariationalStrategyIndexed\n", + "\n", + "class GPModel(ApproximateGP):\n", + " def __init__(self):\n", + " inducing_points = torch.rand(40)*ub\n", + " inducing_index = torch.ones(40,ndim+1,dtype=bool)\n", + " variational_distribution = CholeskyVariationalDistribution(torch.sum(inducing_index).item())\n", + " variational_strategy = VariationalStrategyIndexed(\n", + " self, inducing_points, variational_distribution, inducing_index, learn_inducing_locations=True\n", + " )\n", + " super(GPModel, self).__init__(variational_strategy)\n", + " self.mean_module = gpytorch.means.ConstantMeanGrad()\n", + " self.covar_module = gpytorch.kernels.ScaleKernel(gpytorch.kernels.RBFKernelGrad())\n", + "\n", + " def forward(self, x, index):\n", + " index = index.reshape(-1)\n", + " mean_x = self.mean_module(x).reshape(-1)[index]\n", + " full_kernel = self.covar_module(x)\n", + " covar_x = full_kernel[..., index,:][...,:,index]\n", + " return gpytorch.distributions.MultivariateNormal(mean_x, covar_x)" + ] + }, + { + "cell_type": "markdown", + "id": "62bf6193", + "metadata": {}, + "source": [ + "[Because of a bug in the `linear_operator` ](https://github.com/cornellius-gp/gpytorch/issues/1554), we have to unset its debug option. Otherwise, it raises an error while slicing the covariance matrix." + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "f5687837", + "metadata": {}, + "outputs": [], + "source": [ + "gpytorch.linear_operator.settings.debug._default = False" + ] + }, + { + "cell_type": "markdown", + "id": "1fef475d", + "metadata": {}, + "source": [ + "We crate instances of the model and a Gaussian likelihood. " + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "1e826ef6", + "metadata": {}, + "outputs": [], + "source": [ + "model = GPModel()\n", + "likelihood = gpytorch.likelihoods.GaussianLikelihood()\n", + "\n", + "# \"Loss\" for approximate GPs - the ELBO\n", + "mll = gpytorch.mlls.VariationalELBO(likelihood, model, num_data=train_y.size(0))" + ] + }, + { + "cell_type": "markdown", + "id": "2348bb4e", + "metadata": {}, + "source": [ + "Next, we train the GP using Adam optimizer. The main difference from the default ApproximateGP is that we have to pass named argument `x_index` when calling the model." + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "b85c9be2", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Iter 1/50 - Loss: 1.614\n", + "Iter 2/50 - Loss: 1.410\n", + "Iter 3/50 - Loss: 1.076\n", + "Iter 4/50 - Loss: 1.013\n", + "Iter 5/50 - Loss: 1.011\n", + "Iter 6/50 - Loss: 0.946\n", + "Iter 7/50 - Loss: 0.863\n", + "Iter 8/50 - Loss: 0.815\n", + "Iter 9/50 - Loss: 0.801\n", + "Iter 10/50 - Loss: 0.786\n", + "Iter 11/50 - Loss: 0.746\n", + "Iter 12/50 - Loss: 0.691\n", + "Iter 13/50 - Loss: 0.640\n", + "Iter 14/50 - Loss: 0.603\n", + "Iter 15/50 - Loss: 0.573\n", + "Iter 16/50 - Loss: 0.534\n", + "Iter 17/50 - Loss: 0.481\n", + "Iter 18/50 - Loss: 0.421\n", + "Iter 19/50 - Loss: 0.365\n", + "Iter 20/50 - Loss: 0.320\n", + "Iter 21/50 - Loss: 0.278\n", + "Iter 22/50 - Loss: 0.233\n", + "Iter 23/50 - Loss: 0.183\n", + "Iter 24/50 - Loss: 0.134\n", + "Iter 25/50 - Loss: 0.086\n", + "Iter 26/50 - Loss: 0.037\n", + "Iter 27/50 - Loss: -0.010\n", + "Iter 28/50 - Loss: -0.060\n", + "Iter 29/50 - Loss: -0.115\n", + "Iter 30/50 - Loss: -0.167\n", + "Iter 31/50 - Loss: -0.219\n", + "Iter 32/50 - Loss: -0.270\n", + "Iter 33/50 - Loss: -0.321\n", + "Iter 34/50 - Loss: -0.375\n", + "Iter 35/50 - Loss: -0.428\n", + "Iter 36/50 - Loss: -0.481\n", + "Iter 37/50 - Loss: -0.532\n", + "Iter 38/50 - Loss: -0.583\n", + "Iter 39/50 - Loss: -0.637\n", + "Iter 40/50 - Loss: -0.690\n", + "Iter 41/50 - Loss: -0.742\n", + "Iter 42/50 - Loss: -0.796\n", + "Iter 43/50 - Loss: -0.850\n", + "Iter 44/50 - Loss: -0.903\n", + "Iter 45/50 - Loss: -0.955\n", + "Iter 46/50 - Loss: -1.007\n", + "Iter 47/50 - Loss: -1.045\n", + "Iter 48/50 - Loss: -1.072\n", + "Iter 49/50 - Loss: -1.159\n", + "Iter 50/50 - Loss: -1.191\n" + ] + } + ], + "source": [ + "# this is for running the notebook in our testing framework\n", + "import os\n", + "smoke_test = ('CI' in os.environ)\n", + "training_iter = 2 if smoke_test else 50\n", + "\n", + "# Find optimal model hyperparameters\n", + "model.train()\n", + "likelihood.train()\n", + "\n", + "# Use the adam optimizer\n", + "optimizer = torch.optim.Adam([\n", + " {'params': model.parameters()},\n", + " {'params': likelihood.parameters()},\n", + "], lr=0.1)\n", + "\n", + "for i in range(training_iter):\n", + " optimizer.zero_grad()\n", + " output = model(train_x,x_index=train_index)\n", + " loss = -mll(output, train_y)\n", + " loss.backward()\n", + " print('Iter %d/%d - Loss: %.3f' % (i + 1, training_iter, loss.item()))\n", + " optimizer.step()" + ] + }, + { + "cell_type": "markdown", + "id": "ce43d623", + "metadata": {}, + "source": [ + "The trained model and its derivatives are plotted next" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "ec4554d7", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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Afh8Pnbs2MF5553HpEmTmDlzJp999hkAu3btYtq0aYwZM4Z77rmn3nO5/PLLefXVV2tHcHbv3s2BAweYOXMm3/zmN8nLy2P06NH89Kc/rff1dUdWFi1axA033ADA0aNHueyyy5g8eTKTJ09m5cqVALz77ruMHz+e8ePHM2HCBMrLy1v3nyAiUaU+tf4+9Xg9e/bk4Ycf5s9//jPWWgKBAHfeeSeTJ09m7Nix/O1vfwNg+fLlzJw5k3nz5jFq1Cjgy/51/vz5vPrqq7X7vOGGG1i0aBG7d+9m5syZTJw4kYkTJ9aG67vuuosVK1Ywfvx4fv/737N8+XIuuugigsEggwcPpqSkpHZfI0aM4PDhwx3bZ1trO+XXpEmTrEis2Lp1a7O3TUxMtMAJX4mJia0+/gMPPGC/+93vnvD4+PHj7aZNm+xjjz1me/fubQsKCmxVVZUdPXq0Xbt2rV20aJG95ZZbarcvKSmxXq/XTps2zR45csRaa+3ChQvtjTfeaK21dtasWfab3/xm7fbz5s2zb7/9du12N998s7XW2jlz5tht27ZZa61ds2aNPfPMM6211l588cX2iSeesNZa++c//9mmpKTUez4XXnihffnll6211v73f/+3/cEPfmCttbawsNBaa63f77ezZs2ymzZtqm3X2rVrrbX2mH2+8MIL9vrrr7fWWrtgwQK7YsUKa621e/bssSNHjrTWWnvRRRfZ999/31prbXl5ufX5fCe0p77/X2Cd7QR9aUd+qd+WjqI+NbJ9an2PZ2Rk2EOHDtm//e1v9v7777fWWut2u+2kSZPszp077TvvvGOTk5Ptzp07T9jPiy++aK+77jprrbUej8f279/fVlVV2crKSltdXW2ttXbbtm22ps9455137IUXXli7n7r377jjDvvoo4/WnttZZ51lre3YPlsjyyKdzM6dO7nqqqtITk4GIDk5mauvvppdu3a163Hnzp1LTk4OSUlJfPWrX+X9999nzJgxvPHGG/znf/4nK1asICMjg88//5xPPvmEuXPnMn78eH7xi1+Qn59fu58rr7zymNs1IycLFy7kyiuvpKKiglWrVnHFFVcwfvx4vvGNb9SOoqxcubJ2OsW1117bYFvrTsWoOwXj+eefZ+LEiUyYMIEtW7awdevWZp//m2++ye2338748eOZN28eZWVlVFRUMH36dL7//e/z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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "# Set into eval mode\n", + "model.eval()\n", + "likelihood.eval()\n", + "\n", + "# Initialize plots\n", + "f, (y1_ax, y2_ax) = plt.subplots(1, 2, figsize=(12, 6))\n", + "\n", + "n11=200\n", + "test_x = torch.linspace(lb, ub, n11)\n", + "test_index = torch.ones(test_x.shape[0],ndim+1,dtype=bool)\n", + "\n", + "# Make predictions\n", + "with torch.no_grad(), gpytorch.settings.max_cg_iterations(50):\n", + " predictions = likelihood(model(test_x,x_index=test_index))\n", + " mean = predictions.mean\n", + " lower, upper = predictions.confidence_region()\n", + "\n", + "# Plot training data as black stars\n", + "y1_ax.plot(train_x[:n1].detach().numpy(), train_y[:n1].detach().numpy(), 'k*')\n", + "# Predictive mean as blue line\n", + "y1_ax.plot(test_x.detach().numpy(), mean[::2].detach().numpy(), 'b')\n", + "# Shade in confidence\n", + "y1_ax.fill_between(test_x.detach().numpy(), lower[::2].detach().numpy(), upper[::2].detach().numpy(), alpha=0.5)\n", + "y1_ax.legend(['Observed Values', 'Mean', 'Confidence'])\n", + "y1_ax.set_title('Function values')\n", + "\n", + "# Plot training data as black stars\n", + "y2_ax.plot(train_x[n1:].detach().numpy(), train_y[n1:].detach().numpy(), 'k*')\n", + "# Predictive mean as blue line\n", + "y2_ax.plot(test_x.detach().numpy(), mean[1::2].detach().numpy(), 'b')\n", + "# Shade in confidence\n", + "y2_ax.fill_between(test_x.detach().numpy(), lower[1::2].detach().numpy(), upper[1::2].detach().numpy(), alpha=0.5)\n", + "y2_ax.legend(['Observed Derivatives', 'Mean', 'Confidence'])\n", + "y2_ax.set_title('Derivatives')\n", + "\n", + "plt.show()" + ] + }, + { + "cell_type": "markdown", + "id": "c34b1bea", + "metadata": {}, + "source": [ + "# Monotonic GP\n", + "In general, they do not have to be the same. This can be achieved implementing a `CompositeLikelihood` demonstrated in this section. We use the `CompositeLikelihood` to create a monotonic GP following the approach by [Riihimaki and Vehtari](http://proceedings.mlr.press/v9/riihimaki10a/riihimaki10a.pdf). A Gaussian likelihood is used for the function values, but a probit likelihood, called `BernoulliLikelihood` in `gpytorch`, is used to constrain derivatives to be positive. Here a parameter `nu` defines a scaling factor, and increasing this factor increases the accuracy of the constraint." + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "id": "b3eae655", + "metadata": {}, + "outputs": [], + "source": [ + "class CompositeLikelihood(gpytorch.likelihoods._OneDimensionalLikelihood):\n", + " def __init__(self,likelihoods_list,indices):\n", + " super().__init__()\n", + " self.likelihoods_list = likelihoods_list\n", + " self.indices = indices\n", + " self.nu = 1.\n", + "\n", + " def set_indices(indices):\n", + " self.indices = indices\n", + "\n", + " def forward(self,function_samples,**kwargs):\n", + " #This method is not called for ELBO, so it does not need to be implemented\n", + " raise NotImplementedError\n", + "\n", + " def split(self, full_y):\n", + " y = []\n", + " temp = torch.zeros_like(self.indices)\n", + " #print(full_y)\n", + " for i in range(self.indices.shape[-1]):\n", + " temp[:,i] = self.indices[:,i]\n", + " y.append(full_y[...,temp[self.indices]])\n", + " temp[:,i] = False\n", + " return y\n", + "\n", + " def expected_log_prob(self,observations, function_dist, *params,**kwargs):\n", + " #split observations into a list of different parts observ[i]\n", + " observ = self.split(observations)\n", + "\n", + " def log_prob_lambda(function_samples):\n", + " #for the log_prob_lambda function, which takes function_samples as input\n", + " #split the function_samples into a list of different parts f_samples[i]\n", + " f_samples = self.split(function_samples)\n", + " log_prob = []\n", + " for i,l in enumerate(self.likelihoods_list):\n", + " if isinstance(l,gpytorch.likelihoods.GaussianLikelihood):\n", + " log_prob.append(l(f_samples[i]).log_prob(observ[i]))\n", + " elif isinstance(l,gpytorch.likelihoods.BernoulliLikelihood):\n", + " log_prob.append(gpytorch.functions.log_normal_cdf(\n", + " f_samples[i].mul(observ[i].mul(2).sub(1)).mul(self.nu))) \n", + " #.mul(2).sub(1) changes the Bernoulli observations to -1 and 1, \n", + " #so that p(Y=y|f)=\\Phi(yf), see the BernoulliLikelihood) for details on this\n", + "\n", + " #combine the log_prob back into the correct ordered full vector\n", + " return torch.cat(log_prob,-1)\n", + "\n", + " log_prob = self.quadrature(log_prob_lambda, function_dist)\n", + " return log_prob" + ] + }, + { + "cell_type": "markdown", + "id": "e711adc9", + "metadata": {}, + "source": [ + "Having this likelihood function, we set a similar problem to above. However, in this case, there are no actual observations at the derivative locations. Instead, the `train_y2` is 1 at the derivative locations, which indicates that the derivatives must be positive." + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "bff544de", + "metadata": {}, + "outputs": [], + "source": [ + "lb, ub = 0.0, 1. \n", + "n1 = 40 #function values\n", + "freq = 2 #frequency of the size function\n", + "train_x1 = torch.linspace(lb, ub, n1)\n", + "train_y1 = torch.sin(freq*train_x1) + 0.005 * torch.randn(train_x1.size())\n", + "\n", + "n2=50 #derivative values at different x locations\n", + "train_x2 = torch.linspace(lb, ub, n2)\n", + "train_y2 = torch.ones_like(train_x2) \n", + "\n", + "train_x = torch.cat([train_x1 , train_x2])\n", + "train_y = torch.cat([train_y1,train_y2])\n", + "\n", + "ndata,ndim = train_x.shape.numel(),1\n", + "train_index = torch.empty(ndata,ndim+1,dtype=bool)\n", + "train_index[:n1,0]=True\n", + "train_index[:n1,1]=False\n", + "train_index[n1:,0]=False\n", + "train_index[n1:,1]=True" + ] + }, + { + "cell_type": "markdown", + "id": "d6f3c798", + "metadata": {}, + "source": [ + "We create an instance of the `GPModel` and create two likelihood functions -- one for function values and one for derivatives -- and pass these onto the `CompositeLikelihood` along with the indices at the training points `train_index`. ELBO is used for the loss function. " + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "adb9821c", + "metadata": {}, + "outputs": [], + "source": [ + "gpytorch.linear_operator.settings.debug._default = False\n", + "model = GPModel()\n", + "likelihood = gpytorch.likelihoods.GaussianLikelihood()\n", + "likelihood2 = gpytorch.likelihoods.BernoulliLikelihood()\n", + "test_likelihood = CompositeLikelihood((likelihood,likelihood2),train_index)\n", + "mll = gpytorch.mlls.VariationalELBO(test_likelihood, model, num_data=train_y.size(0))" + ] + }, + { + "cell_type": "markdown", + "id": "ed506ac0", + "metadata": {}, + "source": [ + "Next we train the model, first with default `nu` of 1 and then increase `nu` to 10 and train for another 500 iterations. " + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "5d3d3686", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Iter 1/500 - Loss: -0.350\n", + "Iter 2/500 - Loss: 5.153\n", + "Iter 3/500 - Loss: -0.105\n", + "Iter 4/500 - Loss: 1.501\n", + "Iter 5/500 - Loss: 2.501\n", + "Iter 6/500 - Loss: 1.507\n", + "Iter 7/500 - Loss: 0.269\n", + "Iter 8/500 - Loss: -0.196\n", + "Iter 9/500 - Loss: 0.071\n", + "Iter 10/500 - Loss: 0.480\n", + "Iter 11/500 - Loss: 0.591\n", + "Iter 12/500 - Loss: 0.387\n", + "Iter 13/500 - Loss: 0.083\n", + "Iter 14/500 - Loss: -0.138\n", + "Iter 15/500 - Loss: -0.212\n", + "Iter 16/500 - Loss: -0.167\n", + "Iter 17/500 - Loss: -0.076\n", + "Iter 18/500 - Loss: -0.004\n", + "Iter 19/500 - Loss: 0.019\n", + "Iter 20/500 - Loss: -0.008\n", + "Iter 21/500 - Loss: -0.068\n", + "Iter 22/500 - Loss: -0.138\n", + "Iter 23/500 - Loss: -0.197\n", + "Iter 24/500 - Loss: -0.229\n", + "Iter 25/500 - Loss: -0.231\n", + "Iter 26/500 - Loss: -0.210\n", + "Iter 27/500 - Loss: -0.185\n", + "Iter 28/500 - Loss: -0.171\n", + "Iter 29/500 - Loss: -0.175\n", + "Iter 30/500 - Loss: -0.193\n", + "Iter 31/500 - Loss: -0.217\n", + "Iter 32/500 - Loss: -0.237\n", + "Iter 33/500 - Loss: -0.250\n", + "Iter 34/500 - Loss: -0.255\n", + "Iter 35/500 - Loss: -0.254\n", + "Iter 36/500 - Loss: -0.250\n", + "Iter 37/500 - Loss: -0.245\n", + "Iter 38/500 - Loss: -0.242\n", + "Iter 39/500 - Loss: -0.246\n", + "Iter 40/500 - Loss: -0.254\n", + "Iter 41/500 - Loss: -0.265\n", + "Iter 42/500 - Loss: -0.273\n", + "Iter 43/500 - Loss: -0.277\n", + "Iter 44/500 - Loss: -0.277\n", + "Iter 45/500 - Loss: -0.276\n", + "Iter 46/500 - Loss: -0.276\n", + "Iter 47/500 - Loss: -0.278\n", + "Iter 48/500 - Loss: -0.281\n", + "Iter 49/500 - Loss: -0.287\n", + "Iter 50/500 - Loss: -0.292\n", + "Iter 51/500 - Loss: -0.296\n", + "Iter 52/500 - Loss: -0.299\n", + "Iter 53/500 - Loss: -0.299\n", + "Iter 54/500 - Loss: -0.300\n", + "Iter 55/500 - Loss: -0.301\n", + "Iter 56/500 - Loss: -0.305\n", + "Iter 57/500 - Loss: -0.309\n", + "Iter 58/500 - Loss: -0.313\n", + "Iter 59/500 - Loss: -0.317\n", + "Iter 60/500 - Loss: -0.319\n", + "Iter 61/500 - Loss: -0.321\n", + "Iter 62/500 - Loss: -0.323\n", + "Iter 63/500 - Loss: -0.326\n", + "Iter 64/500 - Loss: -0.329\n", + "Iter 65/500 - Loss: -0.333\n", + "Iter 66/500 - Loss: -0.336\n", + "Iter 67/500 - Loss: -0.338\n", + "Iter 68/500 - Loss: -0.340\n", + "Iter 69/500 - Loss: -0.343\n", + "Iter 70/500 - Loss: -0.346\n", + "Iter 71/500 - Loss: -0.349\n", + "Iter 72/500 - Loss: -0.352\n", + "Iter 73/500 - Loss: -0.354\n", + "Iter 74/500 - Loss: -0.357\n", + "Iter 75/500 - Loss: -0.359\n", + "Iter 76/500 - Loss: -0.362\n", + "Iter 77/500 - Loss: -0.365\n", + "Iter 78/500 - Loss: -0.368\n", + "Iter 79/500 - Loss: -0.371\n", + "Iter 80/500 - Loss: -0.373\n", + "Iter 81/500 - Loss: -0.376\n", + "Iter 82/500 - Loss: -0.378\n", + "Iter 83/500 - Loss: -0.381\n", + "Iter 84/500 - Loss: -0.384\n", + "Iter 85/500 - Loss: -0.386\n", + "Iter 86/500 - Loss: -0.389\n", + "Iter 87/500 - Loss: -0.392\n", + "Iter 88/500 - Loss: -0.394\n", + "Iter 89/500 - Loss: -0.397\n", + "Iter 90/500 - Loss: -0.400\n", + "Iter 91/500 - Loss: -0.402\n", + "Iter 92/500 - Loss: -0.405\n", + "Iter 93/500 - Loss: -0.408\n", + "Iter 94/500 - Loss: -0.410\n", + "Iter 95/500 - Loss: -0.413\n", + "Iter 96/500 - Loss: -0.416\n", + "Iter 97/500 - Loss: -0.419\n", + "Iter 98/500 - Loss: -0.421\n", + "Iter 99/500 - Loss: -0.424\n", + "Iter 100/500 - Loss: -0.427\n", + "Iter 101/500 - Loss: -0.430\n", + "Iter 102/500 - Loss: -0.432\n", + "Iter 103/500 - Loss: -0.435\n", + "Iter 104/500 - Loss: -0.438\n", + "Iter 105/500 - Loss: -0.441\n", + "Iter 106/500 - Loss: -0.444\n", + "Iter 107/500 - Loss: -0.446\n", + "Iter 108/500 - Loss: -0.449\n", + "Iter 109/500 - Loss: -0.452\n", + "Iter 110/500 - Loss: -0.455\n", + "Iter 111/500 - Loss: -0.458\n", + "Iter 112/500 - Loss: -0.461\n", + "Iter 113/500 - Loss: -0.464\n", + "Iter 114/500 - Loss: -0.467\n", + "Iter 115/500 - Loss: -0.470\n", + "Iter 116/500 - Loss: -0.473\n", + "Iter 117/500 - Loss: -0.477\n", + "Iter 118/500 - Loss: -0.480\n", + "Iter 119/500 - Loss: -0.483\n", + "Iter 120/500 - Loss: -0.487\n", + "Iter 121/500 - Loss: -0.490\n", + "Iter 122/500 - Loss: -0.494\n", + "Iter 123/500 - Loss: -0.497\n", + "Iter 124/500 - Loss: -0.501\n", + "Iter 125/500 - Loss: -0.504\n", + "Iter 126/500 - Loss: -0.508\n", + "Iter 127/500 - Loss: -0.511\n", + "Iter 128/500 - Loss: -0.514\n", + "Iter 129/500 - Loss: -0.520\n", + "Iter 130/500 - Loss: -0.524\n", + "Iter 131/500 - Loss: -0.527\n", + "Iter 132/500 - Loss: -0.532\n", + "Iter 133/500 - Loss: -0.537\n", + "Iter 134/500 - Loss: -0.541\n", + "Iter 135/500 - Loss: -0.544\n", + "Iter 136/500 - Loss: -0.549\n", + "Iter 137/500 - Loss: -0.552\n", + "Iter 138/500 - Loss: -0.554\n", + "Iter 139/500 - Loss: -0.559\n", + "Iter 140/500 - Loss: -0.565\n", + "Iter 141/500 - Loss: -0.567\n", + "Iter 142/500 - Loss: -0.569\n", + "Iter 143/500 - Loss: -0.567\n", + "Iter 144/500 - Loss: -0.535\n", + "Iter 145/500 - Loss: -0.379\n", + "Iter 146/500 - Loss: -0.346\n", + "Iter 147/500 - Loss: -0.532\n", + "Iter 148/500 - Loss: -0.437\n", + "Iter 149/500 - Loss: -0.533\n", + "Iter 150/500 - Loss: -0.367\n", + "Iter 151/500 - Loss: -0.450\n", + "Iter 152/500 - Loss: -0.287\n", + "Iter 153/500 - Loss: -0.297\n", + "Iter 154/500 - Loss: -0.474\n", + "Iter 155/500 - Loss: -0.246\n", + "Iter 156/500 - Loss: -0.390\n", + "Iter 157/500 - Loss: -0.454\n", + "Iter 158/500 - Loss: -0.371\n", + "Iter 159/500 - Loss: -0.481\n", + "Iter 160/500 - Loss: -0.442\n", + "Iter 161/500 - Loss: -0.473\n", + "Iter 162/500 - Loss: -0.442\n", + "Iter 163/500 - Loss: -0.500\n", + "Iter 164/500 - Loss: -0.485\n", + "Iter 165/500 - Loss: -0.503\n", + "Iter 166/500 - Loss: -0.500\n", + "Iter 167/500 - Loss: -0.525\n", + "Iter 168/500 - Loss: -0.520\n", + "Iter 169/500 - Loss: -0.527\n", + "Iter 170/500 - Loss: -0.548\n", + "Iter 171/500 - Loss: -0.536\n", + "Iter 172/500 - Loss: -0.556\n", + "Iter 173/500 - Loss: -0.556\n", + "Iter 174/500 - Loss: -0.572\n", + "Iter 175/500 - Loss: -0.563\n", + "Iter 176/500 - Loss: -0.585\n", + "Iter 177/500 - Loss: -0.584\n", + "Iter 178/500 - Loss: -0.587\n", + "Iter 179/500 - Loss: -0.602\n", + "Iter 180/500 - Loss: -0.599\n", + "Iter 181/500 - Loss: -0.608\n", + "Iter 182/500 - Loss: -0.618\n", + "Iter 183/500 - Loss: -0.615\n", + "Iter 184/500 - Loss: -0.627\n", + "Iter 185/500 - Loss: -0.633\n", + "Iter 186/500 - Loss: -0.634\n", + "Iter 187/500 - Loss: -0.637\n", + "Iter 188/500 - Loss: -0.647\n", + "Iter 189/500 - Loss: -0.654\n", + "Iter 190/500 - Loss: -0.655\n", + "Iter 191/500 - Loss: -0.658\n", + "Iter 192/500 - Loss: -0.650\n", + "Iter 193/500 - Loss: -0.635\n", + "Iter 194/500 - Loss: -0.566\n", + "Iter 195/500 - Loss: -0.371\n", + "Iter 196/500 - Loss: 0.258\n", + "Iter 197/500 - Loss: 0.505\n", + "Iter 198/500 - Loss: -0.224\n", + "Iter 199/500 - Loss: -0.546\n", + "Iter 200/500 - Loss: -0.071\n", + "Iter 201/500 - Loss: -0.595\n", + "Iter 202/500 - Loss: -0.287\n", + "Iter 203/500 - Loss: -0.511\n", + "Iter 204/500 - Loss: -0.408\n", + "Iter 205/500 - Loss: -0.551\n", + "Iter 206/500 - Loss: -0.435\n", + "Iter 207/500 - Loss: -0.581\n", + "Iter 208/500 - Loss: -0.473\n", + "Iter 209/500 - Loss: -0.575\n", + "Iter 210/500 - Loss: -0.516\n", + "Iter 211/500 - Loss: -0.555\n", + "Iter 212/500 - Loss: -0.568\n", + "Iter 213/500 - Loss: -0.534\n", + "Iter 214/500 - Loss: -0.594\n", + "Iter 215/500 - Loss: -0.551\n", + "Iter 216/500 - Loss: -0.582\n", + "Iter 217/500 - Loss: -0.583\n", + "Iter 218/500 - Loss: -0.580\n", + "Iter 219/500 - Loss: -0.594\n", + "Iter 220/500 - Loss: -0.592\n", + "Iter 221/500 - Loss: -0.604\n", + "Iter 222/500 - Loss: -0.598\n", + "Iter 223/500 - Loss: -0.618\n", + "Iter 224/500 - Loss: -0.607\n", + "Iter 225/500 - Loss: -0.627\n", + "Iter 226/500 - Loss: -0.618\n", + "Iter 227/500 - Loss: -0.635\n", + "Iter 228/500 - Loss: -0.633\n", + "Iter 229/500 - Loss: -0.638\n", + "Iter 230/500 - Loss: -0.646\n", + "Iter 231/500 - Loss: -0.649\n", + "Iter 232/500 - Loss: -0.651\n", + "Iter 233/500 - Loss: -0.662\n", + "Iter 234/500 - Loss: -0.657\n", + "Iter 235/500 - Loss: -0.671\n", + "Iter 236/500 - Loss: -0.667\n", + "Iter 237/500 - Loss: -0.676\n", + "Iter 238/500 - Loss: -0.678\n", + "Iter 239/500 - Loss: -0.681\n", + "Iter 240/500 - Loss: -0.687\n", + "Iter 241/500 - Loss: -0.689\n", + "Iter 242/500 - Loss: -0.691\n", + "Iter 243/500 - Loss: -0.698\n", + "Iter 244/500 - Loss: -0.698\n", + "Iter 245/500 - Loss: -0.700\n", + "Iter 246/500 - Loss: -0.706\n", + "Iter 247/500 - Loss: -0.710\n", + "Iter 248/500 - Loss: -0.711\n", + "Iter 249/500 - Loss: -0.712\n", + "Iter 250/500 - Loss: -0.715\n", + "Iter 251/500 - Loss: -0.720\n", + "Iter 252/500 - Loss: -0.724\n", + "Iter 253/500 - Loss: -0.726\n", + "Iter 254/500 - Loss: -0.729\n", + "Iter 255/500 - Loss: -0.731\n", + "Iter 256/500 - Loss: -0.730\n", + "Iter 257/500 - Loss: -0.725\n", + "Iter 258/500 - Loss: -0.700\n", + "Iter 259/500 - Loss: -0.591\n", + "Iter 260/500 - Loss: -0.242\n", + "Iter 261/500 - Loss: 0.894\n", + "Iter 262/500 - Loss: 0.758\n", + "Iter 263/500 - Loss: -0.328\n", + "Iter 264/500 - Loss: -0.318\n", + "Iter 265/500 - Loss: -0.100\n", + "Iter 266/500 - Loss: -0.546\n", + "Iter 267/500 - Loss: -0.221\n", + "Iter 268/500 - Loss: -0.580\n", + "Iter 269/500 - Loss: -0.359\n", + "Iter 270/500 - Loss: -0.505\n", + "Iter 271/500 - Loss: -0.521\n", + "Iter 272/500 - Loss: -0.452\n", + "Iter 273/500 - Loss: -0.578\n", + "Iter 274/500 - Loss: -0.473\n", + "Iter 275/500 - Loss: -0.559\n", + "Iter 276/500 - Loss: -0.563\n", + "Iter 277/500 - Loss: -0.516\n", + "Iter 278/500 - Loss: -0.584\n", + "Iter 279/500 - Loss: -0.564\n", + "Iter 280/500 - Loss: -0.554\n", + "Iter 281/500 - Loss: -0.605\n", + "Iter 282/500 - Loss: -0.574\n", + "Iter 283/500 - Loss: -0.584\n", + "Iter 284/500 - Loss: -0.617\n", + "Iter 285/500 - Loss: -0.590\n", + "Iter 286/500 - Loss: -0.612\n", + "Iter 287/500 - Loss: -0.624\n", + "Iter 288/500 - Loss: -0.611\n", + "Iter 289/500 - Loss: -0.632\n", + "Iter 290/500 - Loss: -0.635\n", + "Iter 291/500 - Loss: -0.630\n", + "Iter 292/500 - Loss: -0.651\n", + "Iter 293/500 - Loss: -0.643\n", + "Iter 294/500 - Loss: -0.653\n", + "Iter 295/500 - Loss: -0.660\n", + "Iter 296/500 - Loss: -0.658\n", + "Iter 297/500 - Loss: -0.670\n", + "Iter 298/500 - Loss: -0.668\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Iter 299/500 - Loss: -0.675\n", + "Iter 300/500 - Loss: -0.678\n", + "Iter 301/500 - Loss: -0.682\n", + "Iter 302/500 - Loss: -0.686\n", + "Iter 303/500 - Loss: -0.689\n", + "Iter 304/500 - Loss: -0.694\n", + "Iter 305/500 - Loss: -0.696\n", + "Iter 306/500 - Loss: -0.702\n", + "Iter 307/500 - Loss: -0.703\n", + "Iter 308/500 - Loss: -0.709\n", + "Iter 309/500 - Loss: -0.710\n", + "Iter 310/500 - Loss: -0.715\n", + "Iter 311/500 - Loss: -0.717\n", + "Iter 312/500 - Loss: -0.721\n", + "Iter 313/500 - Loss: -0.724\n", + "Iter 314/500 - Loss: -0.727\n", + "Iter 315/500 - Loss: -0.730\n", + "Iter 316/500 - Loss: -0.733\n", + "Iter 317/500 - Loss: -0.736\n", + "Iter 318/500 - Loss: -0.739\n", + "Iter 319/500 - Loss: -0.742\n", + "Iter 320/500 - Loss: -0.744\n", + "Iter 321/500 - Loss: -0.747\n", + "Iter 322/500 - Loss: -0.749\n", + "Iter 323/500 - Loss: -0.752\n", + "Iter 324/500 - Loss: -0.754\n", + "Iter 325/500 - Loss: -0.756\n", + "Iter 326/500 - Loss: -0.759\n", + "Iter 327/500 - Loss: -0.760\n", + "Iter 328/500 - Loss: -0.762\n", + "Iter 329/500 - Loss: -0.765\n", + "Iter 330/500 - Loss: -0.766\n", + "Iter 331/500 - Loss: -0.768\n", + "Iter 332/500 - Loss: -0.770\n", + "Iter 333/500 - Loss: -0.771\n", + "Iter 334/500 - Loss: -0.773\n", + "Iter 335/500 - Loss: -0.774\n", + "Iter 336/500 - Loss: -0.775\n", + "Iter 337/500 - Loss: -0.776\n", + "Iter 338/500 - Loss: -0.775\n", + "Iter 339/500 - Loss: -0.768\n", + "Iter 340/500 - Loss: -0.740\n", + "Iter 341/500 - Loss: -0.627\n", + "Iter 342/500 - Loss: -0.241\n", + "Iter 343/500 - Loss: 1.019\n", + "Iter 344/500 - Loss: 1.497\n", + "Iter 345/500 - Loss: 0.235\n", + "Iter 346/500 - Loss: -0.433\n", + "Iter 347/500 - Loss: 0.178\n", + "Iter 348/500 - Loss: -0.553\n", + "Iter 349/500 - Loss: -0.159\n", + "Iter 350/500 - Loss: -0.473\n", + "Iter 351/500 - Loss: -0.378\n", + "Iter 352/500 - Loss: -0.313\n", + "Iter 353/500 - Loss: -0.507\n", + "Iter 354/500 - Loss: -0.456\n", + "Iter 355/500 - Loss: -0.471\n", + "Iter 356/500 - Loss: -0.487\n", + "Iter 357/500 - Loss: -0.471\n", + "Iter 358/500 - Loss: -0.516\n", + "Iter 359/500 - Loss: -0.542\n", + "Iter 360/500 - Loss: -0.503\n", + "Iter 361/500 - Loss: -0.505\n", + "Iter 362/500 - Loss: -0.557\n", + "Iter 363/500 - Loss: -0.564\n", + "Iter 364/500 - Loss: -0.546\n", + "Iter 365/500 - Loss: -0.558\n", + "Iter 366/500 - Loss: -0.578\n", + "Iter 367/500 - Loss: -0.577\n", + "Iter 368/500 - Loss: -0.580\n", + "Iter 369/500 - Loss: -0.593\n", + "Iter 370/500 - Loss: -0.594\n", + "Iter 371/500 - Loss: -0.601\n", + "Iter 372/500 - Loss: -0.607\n", + "Iter 373/500 - Loss: -0.615\n", + "Iter 374/500 - Loss: -0.621\n", + "Iter 375/500 - Loss: -0.624\n", + "Iter 376/500 - Loss: -0.629\n", + "Iter 377/500 - Loss: -0.636\n", + "Iter 378/500 - Loss: -0.641\n", + "Iter 379/500 - Loss: -0.644\n", + "Iter 380/500 - Loss: -0.652\n", + "Iter 381/500 - Loss: -0.656\n", + "Iter 382/500 - Loss: -0.659\n", + "Iter 383/500 - Loss: -0.668\n", + "Iter 384/500 - Loss: -0.671\n", + "Iter 385/500 - Loss: -0.673\n", + "Iter 386/500 - Loss: -0.682\n", + "Iter 387/500 - Loss: -0.685\n", + "Iter 388/500 - Loss: -0.688\n", + "Iter 389/500 - Loss: -0.695\n", + "Iter 390/500 - Loss: -0.697\n", + "Iter 391/500 - Loss: -0.702\n", + "Iter 392/500 - Loss: -0.706\n", + "Iter 393/500 - Loss: -0.710\n", + "Iter 394/500 - Loss: -0.715\n", + "Iter 395/500 - Loss: -0.718\n", + "Iter 396/500 - Loss: -0.722\n", + "Iter 397/500 - Loss: -0.726\n", + "Iter 398/500 - Loss: -0.729\n", + "Iter 399/500 - Loss: -0.733\n", + "Iter 400/500 - Loss: -0.736\n", + "Iter 401/500 - Loss: -0.739\n", + "Iter 402/500 - Loss: -0.743\n", + "Iter 403/500 - Loss: -0.745\n", + "Iter 404/500 - Loss: -0.749\n", + "Iter 405/500 - Loss: -0.751\n", + "Iter 406/500 - Loss: -0.754\n", + "Iter 407/500 - Loss: -0.757\n", + "Iter 408/500 - Loss: -0.759\n", + "Iter 409/500 - Loss: -0.762\n", + "Iter 410/500 - Loss: -0.764\n", + "Iter 411/500 - Loss: -0.767\n", + "Iter 412/500 - Loss: -0.769\n", + "Iter 413/500 - Loss: -0.771\n", + "Iter 414/500 - Loss: -0.773\n", + "Iter 415/500 - Loss: -0.775\n", + "Iter 416/500 - Loss: -0.776\n", + "Iter 417/500 - Loss: -0.778\n", + "Iter 418/500 - Loss: -0.780\n", + "Iter 419/500 - Loss: -0.781\n", + "Iter 420/500 - Loss: -0.783\n", + "Iter 421/500 - Loss: -0.784\n", + "Iter 422/500 - Loss: -0.785\n", + "Iter 423/500 - Loss: -0.785\n", + "Iter 424/500 - Loss: -0.780\n", + "Iter 425/500 - Loss: -0.765\n", + "Iter 426/500 - Loss: -0.719\n", + "Iter 427/500 - Loss: -0.768\n", + "Iter 428/500 - Loss: -0.743\n", + "Iter 429/500 - Loss: -0.762\n", + "Iter 430/500 - Loss: -0.783\n", + "Iter 431/500 - Loss: -0.786\n", + "Iter 432/500 - Loss: -0.779\n", + "Iter 433/500 - Loss: -0.775\n", + "Iter 434/500 - Loss: -0.768\n", + "Iter 435/500 - Loss: -0.768\n", + "Iter 436/500 - Loss: -0.764\n", + "Iter 437/500 - Loss: -0.764\n", + "Iter 438/500 - Loss: -0.760\n", + "Iter 439/500 - Loss: -0.756\n", + "Iter 440/500 - Loss: -0.746\n", + "Iter 441/500 - Loss: -0.725\n", + "Iter 442/500 - Loss: -0.703\n", + "Iter 443/500 - Loss: -0.665\n", + "Iter 444/500 - Loss: -0.642\n", + "Iter 445/500 - Loss: -0.635\n", + "Iter 446/500 - Loss: -0.688\n", + "Iter 447/500 - Loss: -0.757\n", + "Iter 448/500 - Loss: -0.795\n", + "Iter 449/500 - Loss: -0.773\n", + "Iter 450/500 - Loss: -0.738\n", + "Iter 451/500 - Loss: -0.746\n", + "Iter 452/500 - Loss: -0.784\n", + "Iter 453/500 - Loss: -0.795\n", + "Iter 454/500 - Loss: -0.773\n", + "Iter 455/500 - Loss: -0.761\n", + "Iter 456/500 - Loss: -0.781\n", + "Iter 457/500 - Loss: -0.797\n", + "Iter 458/500 - Loss: -0.789\n", + "Iter 459/500 - Loss: -0.776\n", + "Iter 460/500 - Loss: -0.781\n", + "Iter 461/500 - Loss: -0.795\n", + "Iter 462/500 - Loss: -0.799\n", + "Iter 463/500 - Loss: -0.791\n", + "Iter 464/500 - Loss: -0.785\n", + "Iter 465/500 - Loss: -0.790\n", + "Iter 466/500 - Loss: -0.799\n", + "Iter 467/500 - Loss: -0.802\n", + "Iter 468/500 - Loss: -0.798\n", + "Iter 469/500 - Loss: -0.793\n", + "Iter 470/500 - Loss: -0.791\n", + "Iter 471/500 - Loss: -0.794\n", + "Iter 472/500 - Loss: -0.798\n", + "Iter 473/500 - Loss: -0.803\n", + "Iter 474/500 - Loss: -0.805\n", + "Iter 475/500 - Loss: -0.806\n", + "Iter 476/500 - Loss: -0.806\n", + "Iter 477/500 - Loss: -0.804\n", + "Iter 478/500 - Loss: -0.801\n", + "Iter 479/500 - Loss: -0.793\n", + "Iter 480/500 - Loss: -0.777\n", + "Iter 481/500 - Loss: -0.735\n", + "Iter 482/500 - Loss: -0.634\n", + "Iter 483/500 - Loss: -0.383\n", + "Iter 484/500 - Loss: 0.015\n", + "Iter 485/500 - Loss: 0.361\n", + "Iter 486/500 - Loss: -0.238\n", + "Iter 487/500 - Loss: -0.743\n", + "Iter 488/500 - Loss: -0.297\n", + "Iter 489/500 - Loss: -0.509\n", + "Iter 490/500 - Loss: -0.634\n", + "Iter 491/500 - Loss: -0.509\n", + "Iter 492/500 - Loss: -0.680\n", + "Iter 493/500 - Loss: -0.539\n", + "Iter 494/500 - Loss: -0.726\n", + "Iter 495/500 - Loss: -0.609\n", + "Iter 496/500 - Loss: -0.708\n", + "Iter 497/500 - Loss: -0.640\n", + "Iter 498/500 - Loss: -0.702\n", + "Iter 499/500 - Loss: -0.683\n", + "Iter 500/500 - Loss: -0.690\n", + "Iter 1/500 - Loss: -0.694\n", + "Iter 2/500 - Loss: -0.701\n", + "Iter 3/500 - Loss: -0.710\n", + "Iter 4/500 - Loss: -0.718\n", + "Iter 5/500 - Loss: -0.708\n", + "Iter 6/500 - Loss: -0.727\n", + "Iter 7/500 - Loss: -0.727\n", + "Iter 8/500 - Loss: -0.724\n", + "Iter 9/500 - Loss: -0.733\n", + "Iter 10/500 - Loss: -0.733\n", + "Iter 11/500 - Loss: -0.741\n", + "Iter 12/500 - Loss: -0.738\n", + "Iter 13/500 - Loss: -0.746\n", + "Iter 14/500 - Loss: -0.749\n", + "Iter 15/500 - Loss: -0.753\n", + "Iter 16/500 - Loss: -0.750\n", + "Iter 17/500 - Loss: -0.760\n", + "Iter 18/500 - Loss: -0.758\n", + "Iter 19/500 - Loss: -0.761\n", + "Iter 20/500 - Loss: -0.766\n", + "Iter 21/500 - Loss: -0.767\n", + "Iter 22/500 - Loss: -0.769\n", + "Iter 23/500 - Loss: -0.773\n", + "Iter 24/500 - Loss: -0.775\n", + "Iter 25/500 - Loss: -0.776\n", + "Iter 26/500 - Loss: -0.779\n", + "Iter 27/500 - Loss: -0.781\n", + "Iter 28/500 - Loss: -0.783\n", + "Iter 29/500 - Loss: -0.785\n", + "Iter 30/500 - Loss: -0.787\n", + "Iter 31/500 - Loss: -0.788\n", + "Iter 32/500 - Loss: -0.790\n", + "Iter 33/500 - Loss: -0.792\n", + "Iter 34/500 - Loss: -0.793\n", + "Iter 35/500 - Loss: -0.795\n", + "Iter 36/500 - Loss: -0.795\n", + "Iter 37/500 - Loss: -0.797\n", + "Iter 38/500 - Loss: -0.798\n", + "Iter 39/500 - Loss: -0.799\n", + "Iter 40/500 - Loss: -0.800\n", + "Iter 41/500 - Loss: -0.801\n", + "Iter 42/500 - Loss: -0.803\n", + "Iter 43/500 - Loss: -0.803\n", + "Iter 44/500 - Loss: -0.804\n", + "Iter 45/500 - Loss: -0.805\n", + "Iter 46/500 - Loss: -0.806\n", + "Iter 47/500 - Loss: -0.806\n", + "Iter 48/500 - Loss: -0.807\n", + "Iter 49/500 - Loss: -0.808\n", + "Iter 50/500 - Loss: -0.809\n", + "Iter 51/500 - Loss: -0.809\n", + "Iter 52/500 - Loss: -0.809\n", + "Iter 53/500 - Loss: -0.810\n", + "Iter 54/500 - Loss: -0.810\n", + "Iter 55/500 - Loss: -0.811\n", + "Iter 56/500 - Loss: -0.811\n", + "Iter 57/500 - Loss: -0.812\n", + "Iter 58/500 - Loss: -0.812\n", + "Iter 59/500 - Loss: -0.812\n", + "Iter 60/500 - Loss: -0.812\n", + "Iter 61/500 - Loss: -0.812\n", + "Iter 62/500 - Loss: -0.810\n", + "Iter 63/500 - Loss: -0.805\n", + "Iter 64/500 - Loss: -0.789\n", + "Iter 65/500 - Loss: -0.742\n", + "Iter 66/500 - Loss: -0.615\n", + "Iter 67/500 - Loss: -0.314\n", + "Iter 68/500 - Loss: 0.142\n", + "Iter 69/500 - Loss: 0.207\n", + "Iter 70/500 - Loss: -0.475\n", + "Iter 71/500 - Loss: -0.697\n", + "Iter 72/500 - Loss: -0.325\n", + "Iter 73/500 - Loss: -0.682\n", + "Iter 74/500 - Loss: -0.603\n", + "Iter 75/500 - Loss: -0.588\n", + "Iter 76/500 - Loss: -0.716\n", + "Iter 77/500 - Loss: -0.601\n", + "Iter 78/500 - Loss: -0.741\n", + "Iter 79/500 - Loss: -0.634\n", + "Iter 80/500 - Loss: -0.743\n", + "Iter 81/500 - Loss: -0.662\n", + "Iter 82/500 - Loss: -0.741\n", + "Iter 83/500 - Loss: -0.684\n", + "Iter 84/500 - Loss: -0.743\n", + "Iter 85/500 - Loss: -0.703\n", + "Iter 86/500 - Loss: -0.744\n", + "Iter 87/500 - Loss: -0.720\n", + "Iter 88/500 - Loss: -0.738\n", + "Iter 89/500 - Loss: -0.741\n", + "Iter 90/500 - Loss: -0.732\n", + "Iter 91/500 - Loss: -0.756\n", + "Iter 92/500 - Loss: -0.733\n", + "Iter 93/500 - Loss: -0.763\n", + "Iter 94/500 - Loss: -0.742\n", + "Iter 95/500 - Loss: -0.764\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Iter 96/500 - Loss: -0.753\n", + "Iter 97/500 - Loss: -0.764\n", + "Iter 98/500 - Loss: -0.763\n", + "Iter 99/500 - Loss: -0.765\n", + "Iter 100/500 - Loss: -0.770\n", + "Iter 101/500 - Loss: -0.768\n", + "Iter 102/500 - Loss: -0.775\n", + "Iter 103/500 - Loss: -0.773\n", + "Iter 104/500 - Loss: -0.778\n", + "Iter 105/500 - Loss: -0.778\n", + "Iter 106/500 - Loss: -0.782\n", + "Iter 107/500 - Loss: -0.782\n", + "Iter 108/500 - Loss: -0.785\n", + "Iter 109/500 - Loss: -0.786\n", + "Iter 110/500 - Loss: -0.788\n", + "Iter 111/500 - Loss: -0.791\n", + "Iter 112/500 - Loss: -0.790\n", + "Iter 113/500 - Loss: -0.795\n", + "Iter 114/500 - Loss: -0.792\n", + "Iter 115/500 - Loss: -0.798\n", + "Iter 116/500 - Loss: -0.795\n", + "Iter 117/500 - Loss: -0.799\n", + "Iter 118/500 - Loss: -0.799\n", + "Iter 119/500 - Loss: -0.800\n", + "Iter 120/500 - Loss: -0.802\n", + "Iter 121/500 - Loss: -0.802\n", + "Iter 122/500 - Loss: -0.804\n", + "Iter 123/500 - Loss: -0.805\n", + "Iter 124/500 - Loss: -0.805\n", + "Iter 125/500 - Loss: -0.807\n", + "Iter 126/500 - Loss: -0.807\n", + "Iter 127/500 - Loss: -0.807\n", + "Iter 128/500 - Loss: -0.809\n", + "Iter 129/500 - Loss: -0.808\n", + "Iter 130/500 - Loss: -0.809\n", + "Iter 131/500 - Loss: -0.810\n", + "Iter 132/500 - Loss: -0.810\n", + "Iter 133/500 - Loss: -0.811\n", + "Iter 134/500 - Loss: -0.812\n", + "Iter 135/500 - Loss: -0.812\n", + "Iter 136/500 - Loss: -0.812\n", + "Iter 137/500 - Loss: -0.813\n", + "Iter 138/500 - Loss: -0.813\n", + "Iter 139/500 - Loss: -0.813\n", + "Iter 140/500 - Loss: -0.813\n", + "Iter 141/500 - Loss: -0.814\n", + "Iter 142/500 - Loss: -0.814\n", + "Iter 143/500 - Loss: -0.814\n", + "Iter 144/500 - Loss: -0.814\n", + "Iter 145/500 - Loss: -0.815\n", + "Iter 146/500 - Loss: -0.815\n", + "Iter 147/500 - Loss: -0.815\n", + "Iter 148/500 - Loss: -0.815\n", + "Iter 149/500 - Loss: -0.815\n", + "Iter 150/500 - Loss: -0.815\n", + "Iter 151/500 - Loss: -0.816\n", + "Iter 152/500 - Loss: -0.816\n", + "Iter 153/500 - Loss: -0.816\n", + "Iter 154/500 - Loss: -0.816\n", + "Iter 155/500 - Loss: -0.816\n", + "Iter 156/500 - Loss: -0.816\n", + "Iter 157/500 - Loss: -0.816\n", + "Iter 158/500 - Loss: -0.816\n", + "Iter 159/500 - Loss: -0.816\n", + "Iter 160/500 - Loss: -0.817\n", + "Iter 161/500 - Loss: -0.817\n", + "Iter 162/500 - Loss: -0.817\n", + "Iter 163/500 - Loss: -0.817\n", + "Iter 164/500 - Loss: -0.817\n", + "Iter 165/500 - Loss: -0.817\n", + "Iter 166/500 - Loss: -0.817\n", + "Iter 167/500 - Loss: -0.817\n", + "Iter 168/500 - Loss: -0.817\n", + "Iter 169/500 - Loss: -0.816\n", + "Iter 170/500 - Loss: -0.816\n", + "Iter 171/500 - Loss: -0.816\n", + "Iter 172/500 - Loss: -0.815\n", + "Iter 173/500 - Loss: -0.813\n", + "Iter 174/500 - Loss: -0.809\n", + "Iter 175/500 - Loss: -0.802\n", + "Iter 176/500 - Loss: -0.787\n", + "Iter 177/500 - Loss: -0.757\n", + "Iter 178/500 - Loss: -0.697\n", + "Iter 179/500 - Loss: -0.579\n", + "Iter 180/500 - Loss: -0.389\n", + "Iter 181/500 - Loss: -0.166\n", + "Iter 182/500 - Loss: -0.163\n", + "Iter 183/500 - Loss: -0.528\n", + "Iter 184/500 - Loss: -0.809\n", + "Iter 185/500 - Loss: -0.605\n", + "Iter 186/500 - Loss: -0.594\n", + "Iter 187/500 - Loss: -0.806\n", + "Iter 188/500 - Loss: -0.658\n", + "Iter 189/500 - Loss: -0.729\n", + "Iter 190/500 - Loss: -0.771\n", + "Iter 191/500 - Loss: -0.695\n", + "Iter 192/500 - Loss: -0.798\n", + "Iter 193/500 - Loss: -0.714\n", + "Iter 194/500 - Loss: -0.790\n", + "Iter 195/500 - Loss: -0.739\n", + "Iter 196/500 - Loss: -0.781\n", + "Iter 197/500 - Loss: -0.758\n", + "Iter 198/500 - Loss: -0.776\n", + "Iter 199/500 - Loss: -0.770\n", + "Iter 200/500 - Loss: -0.775\n", + "Iter 201/500 - Loss: -0.777\n", + "Iter 202/500 - Loss: -0.775\n", + "Iter 203/500 - Loss: -0.783\n", + "Iter 204/500 - Loss: -0.777\n", + "Iter 205/500 - Loss: -0.787\n", + "Iter 206/500 - Loss: -0.779\n", + "Iter 207/500 - Loss: -0.791\n", + "Iter 208/500 - Loss: -0.781\n", + "Iter 209/500 - Loss: -0.794\n", + "Iter 210/500 - Loss: -0.784\n", + "Iter 211/500 - Loss: -0.797\n", + "Iter 212/500 - Loss: -0.787\n", + "Iter 213/500 - Loss: -0.798\n", + "Iter 214/500 - Loss: -0.791\n", + "Iter 215/500 - Loss: -0.798\n", + "Iter 216/500 - Loss: -0.796\n", + "Iter 217/500 - Loss: -0.798\n", + "Iter 218/500 - Loss: -0.801\n", + "Iter 219/500 - Loss: -0.798\n", + "Iter 220/500 - Loss: -0.804\n", + "Iter 221/500 - Loss: -0.800\n", + "Iter 222/500 - Loss: -0.805\n", + "Iter 223/500 - Loss: -0.804\n", + "Iter 224/500 - Loss: -0.804\n", + "Iter 225/500 - Loss: -0.808\n", + "Iter 226/500 - Loss: -0.805\n", + "Iter 227/500 - Loss: -0.808\n", + "Iter 228/500 - Loss: -0.809\n", + "Iter 229/500 - Loss: -0.808\n", + "Iter 230/500 - Loss: -0.810\n", + "Iter 231/500 - Loss: -0.810\n", + "Iter 232/500 - Loss: -0.810\n", + "Iter 233/500 - Loss: -0.812\n", + "Iter 234/500 - Loss: -0.811\n", + "Iter 235/500 - Loss: -0.811\n", + "Iter 236/500 - Loss: -0.813\n", + "Iter 237/500 - Loss: -0.813\n", + "Iter 238/500 - Loss: -0.813\n", + "Iter 239/500 - Loss: -0.814\n", + "Iter 240/500 - Loss: -0.814\n", + "Iter 241/500 - Loss: -0.814\n", + "Iter 242/500 - Loss: -0.814\n", + "Iter 243/500 - Loss: -0.815\n", + "Iter 244/500 - Loss: -0.815\n", + "Iter 245/500 - Loss: -0.815\n", + "Iter 246/500 - Loss: -0.815\n", + "Iter 247/500 - Loss: -0.816\n", + "Iter 248/500 - Loss: -0.816\n", + "Iter 249/500 - Loss: -0.816\n", + "Iter 250/500 - Loss: -0.816\n", + "Iter 251/500 - Loss: -0.816\n", + "Iter 252/500 - Loss: -0.816\n", + "Iter 253/500 - Loss: -0.816\n", + "Iter 254/500 - Loss: -0.816\n", + "Iter 255/500 - Loss: -0.816\n", + "Iter 256/500 - Loss: -0.817\n", + "Iter 257/500 - Loss: -0.817\n", + "Iter 258/500 - Loss: -0.817\n", + "Iter 259/500 - Loss: -0.817\n", + "Iter 260/500 - Loss: -0.817\n", + "Iter 261/500 - Loss: -0.817\n", + "Iter 262/500 - Loss: -0.817\n", + "Iter 263/500 - Loss: -0.817\n", + "Iter 264/500 - Loss: -0.817\n", + "Iter 265/500 - Loss: -0.817\n", + "Iter 266/500 - Loss: -0.817\n", + "Iter 267/500 - Loss: -0.817\n", + "Iter 268/500 - Loss: -0.817\n", + "Iter 269/500 - Loss: -0.817\n", + "Iter 270/500 - Loss: -0.817\n", + "Iter 271/500 - Loss: -0.817\n", + "Iter 272/500 - Loss: -0.817\n", + "Iter 273/500 - Loss: -0.817\n", + "Iter 274/500 - Loss: -0.817\n", + "Iter 275/500 - Loss: -0.817\n", + "Iter 276/500 - Loss: -0.818\n", + "Iter 277/500 - Loss: -0.818\n", + "Iter 278/500 - Loss: -0.818\n", + "Iter 279/500 - Loss: -0.817\n", + "Iter 280/500 - Loss: -0.817\n", + "Iter 281/500 - Loss: -0.817\n", + "Iter 282/500 - Loss: -0.817\n", + "Iter 283/500 - Loss: -0.817\n", + "Iter 284/500 - Loss: -0.817\n", + "Iter 285/500 - Loss: -0.816\n", + "Iter 286/500 - Loss: -0.815\n", + "Iter 287/500 - Loss: -0.814\n", + "Iter 288/500 - Loss: -0.811\n", + "Iter 289/500 - Loss: -0.805\n", + "Iter 290/500 - Loss: -0.794\n", + "Iter 291/500 - Loss: -0.773\n", + "Iter 292/500 - Loss: -0.733\n", + "Iter 293/500 - Loss: -0.662\n", + "Iter 294/500 - Loss: -0.543\n", + "Iter 295/500 - Loss: -0.391\n", + "Iter 296/500 - Loss: -0.291\n", + "Iter 297/500 - Loss: -0.411\n", + "Iter 298/500 - Loss: -0.709\n", + "Iter 299/500 - Loss: -0.800\n", + "Iter 300/500 - Loss: -0.635\n", + "Iter 301/500 - Loss: -0.682\n", + "Iter 302/500 - Loss: -0.810\n", + "Iter 303/500 - Loss: -0.703\n", + "Iter 304/500 - Loss: -0.747\n", + "Iter 305/500 - Loss: -0.795\n", + "Iter 306/500 - Loss: -0.724\n", + "Iter 307/500 - Loss: -0.800\n", + "Iter 308/500 - Loss: -0.757\n", + "Iter 309/500 - Loss: -0.776\n", + "Iter 310/500 - Loss: -0.788\n", + "Iter 311/500 - Loss: -0.764\n", + "Iter 312/500 - Loss: -0.800\n", + "Iter 313/500 - Loss: -0.766\n", + "Iter 314/500 - Loss: -0.799\n", + "Iter 315/500 - Loss: -0.777\n", + "Iter 316/500 - Loss: -0.794\n", + "Iter 317/500 - Loss: -0.788\n", + "Iter 318/500 - Loss: -0.788\n", + "Iter 319/500 - Loss: -0.797\n", + "Iter 320/500 - Loss: -0.786\n", + "Iter 321/500 - Loss: -0.802\n", + "Iter 322/500 - Loss: -0.789\n", + "Iter 323/500 - Loss: -0.801\n", + "Iter 324/500 - Loss: -0.795\n", + "Iter 325/500 - Loss: -0.798\n", + "Iter 326/500 - Loss: -0.802\n", + "Iter 327/500 - Loss: -0.797\n", + "Iter 328/500 - Loss: -0.805\n", + "Iter 329/500 - Loss: -0.800\n", + "Iter 330/500 - Loss: -0.804\n", + "Iter 331/500 - Loss: -0.805\n", + "Iter 332/500 - Loss: -0.803\n", + "Iter 333/500 - Loss: -0.808\n", + "Iter 334/500 - Loss: -0.805\n", + "Iter 335/500 - Loss: -0.807\n", + "Iter 336/500 - Loss: -0.810\n", + "Iter 337/500 - Loss: -0.807\n", + "Iter 338/500 - Loss: -0.810\n", + "Iter 339/500 - Loss: -0.811\n", + "Iter 340/500 - Loss: -0.809\n", + "Iter 341/500 - Loss: -0.811\n", + "Iter 342/500 - Loss: -0.813\n", + "Iter 343/500 - Loss: -0.811\n", + "Iter 344/500 - Loss: -0.812\n", + "Iter 345/500 - Loss: -0.814\n", + "Iter 346/500 - Loss: -0.813\n", + "Iter 347/500 - Loss: -0.813\n", + "Iter 348/500 - Loss: -0.815\n", + "Iter 349/500 - Loss: -0.815\n", + "Iter 350/500 - Loss: -0.814\n", + "Iter 351/500 - Loss: -0.815\n", + "Iter 352/500 - Loss: -0.816\n", + "Iter 353/500 - Loss: -0.816\n", + "Iter 354/500 - Loss: -0.815\n", + "Iter 355/500 - Loss: -0.816\n", + "Iter 356/500 - Loss: -0.816\n", + "Iter 357/500 - Loss: -0.817\n", + "Iter 358/500 - Loss: -0.816\n", + "Iter 359/500 - Loss: -0.816\n", + "Iter 360/500 - Loss: -0.816\n", + "Iter 361/500 - Loss: -0.817\n", + "Iter 362/500 - Loss: -0.817\n", + "Iter 363/500 - Loss: -0.817\n", + "Iter 364/500 - Loss: -0.817\n", + "Iter 365/500 - Loss: -0.817\n", + "Iter 366/500 - Loss: -0.817\n", + "Iter 367/500 - Loss: -0.817\n", + "Iter 368/500 - Loss: -0.817\n", + "Iter 369/500 - Loss: -0.818\n", + "Iter 370/500 - Loss: -0.818\n", + "Iter 371/500 - Loss: -0.818\n", + "Iter 372/500 - Loss: -0.817\n", + "Iter 373/500 - Loss: -0.817\n", + "Iter 374/500 - Loss: -0.817\n", + "Iter 375/500 - Loss: -0.817\n", + "Iter 376/500 - Loss: -0.817\n", + "Iter 377/500 - Loss: -0.817\n", + "Iter 378/500 - Loss: -0.817\n", + "Iter 379/500 - Loss: -0.817\n", + "Iter 380/500 - Loss: -0.817\n", + "Iter 381/500 - Loss: -0.817\n", + "Iter 382/500 - Loss: -0.816\n", + "Iter 383/500 - Loss: -0.815\n", + "Iter 384/500 - Loss: -0.813\n", + "Iter 385/500 - Loss: -0.810\n", + "Iter 386/500 - Loss: -0.805\n", + "Iter 387/500 - Loss: -0.794\n", + "Iter 388/500 - Loss: -0.775\n", + "Iter 389/500 - Loss: -0.739\n", + "Iter 390/500 - Loss: -0.674\n", + "Iter 391/500 - Loss: -0.569\n", + "Iter 392/500 - Loss: -0.429\n", + "Iter 393/500 - Loss: -0.331\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Iter 394/500 - Loss: -0.414\n", + "Iter 395/500 - Loss: -0.686\n", + "Iter 396/500 - Loss: -0.808\n", + "Iter 397/500 - Loss: -0.666\n", + "Iter 398/500 - Loss: -0.674\n", + "Iter 399/500 - Loss: -0.807\n", + "Iter 400/500 - Loss: -0.727\n", + "Iter 401/500 - Loss: -0.737\n", + "Iter 402/500 - Loss: -0.803\n", + "Iter 403/500 - Loss: -0.733\n", + "Iter 404/500 - Loss: -0.791\n", + "Iter 405/500 - Loss: -0.772\n", + "Iter 406/500 - Loss: -0.768\n", + "Iter 407/500 - Loss: -0.797\n", + "Iter 408/500 - Loss: -0.763\n", + "Iter 409/500 - Loss: -0.800\n", + "Iter 410/500 - Loss: -0.773\n", + "Iter 411/500 - Loss: -0.794\n", + "Iter 412/500 - Loss: -0.786\n", + "Iter 413/500 - Loss: -0.787\n", + "Iter 414/500 - Loss: -0.796\n", + "Iter 415/500 - Loss: -0.784\n", + "Iter 416/500 - Loss: -0.801\n", + "Iter 417/500 - Loss: -0.787\n", + "Iter 418/500 - Loss: -0.801\n", + "Iter 419/500 - Loss: -0.794\n", + "Iter 420/500 - Loss: -0.797\n", + "Iter 421/500 - Loss: -0.802\n", + "Iter 422/500 - Loss: -0.795\n", + "Iter 423/500 - Loss: -0.805\n", + "Iter 424/500 - Loss: -0.799\n", + "Iter 425/500 - Loss: -0.804\n", + "Iter 426/500 - Loss: -0.805\n", + "Iter 427/500 - Loss: -0.802\n", + "Iter 428/500 - Loss: -0.808\n", + "Iter 429/500 - Loss: -0.805\n", + "Iter 430/500 - Loss: -0.806\n", + "Iter 431/500 - Loss: -0.810\n", + "Iter 432/500 - Loss: -0.807\n", + "Iter 433/500 - Loss: -0.809\n", + "Iter 434/500 - Loss: -0.811\n", + "Iter 435/500 - Loss: -0.809\n", + "Iter 436/500 - Loss: -0.811\n", + "Iter 437/500 - Loss: -0.813\n", + "Iter 438/500 - Loss: -0.811\n", + "Iter 439/500 - Loss: -0.812\n", + "Iter 440/500 - Loss: -0.814\n", + "Iter 441/500 - Loss: -0.814\n", + "Iter 442/500 - Loss: -0.813\n", + "Iter 443/500 - Loss: -0.815\n", + "Iter 444/500 - Loss: -0.815\n", + "Iter 445/500 - Loss: -0.815\n", + "Iter 446/500 - Loss: -0.815\n", + "Iter 447/500 - Loss: -0.816\n", + "Iter 448/500 - Loss: -0.816\n", + "Iter 449/500 - Loss: -0.816\n", + "Iter 450/500 - Loss: -0.816\n", + "Iter 451/500 - Loss: -0.816\n", + "Iter 452/500 - Loss: -0.817\n", + "Iter 453/500 - Loss: -0.817\n", + "Iter 454/500 - Loss: -0.817\n", + "Iter 455/500 - Loss: -0.817\n", + "Iter 456/500 - Loss: -0.817\n", + "Iter 457/500 - Loss: -0.817\n", + "Iter 458/500 - Loss: -0.817\n", + "Iter 459/500 - Loss: -0.818\n", + "Iter 460/500 - Loss: -0.818\n", + "Iter 461/500 - Loss: -0.817\n", + "Iter 462/500 - Loss: -0.817\n", + "Iter 463/500 - Loss: -0.817\n", + "Iter 464/500 - Loss: -0.817\n", + "Iter 465/500 - Loss: -0.817\n", + "Iter 466/500 - Loss: -0.817\n", + "Iter 467/500 - Loss: -0.817\n", + "Iter 468/500 - Loss: -0.817\n", + "Iter 469/500 - Loss: -0.818\n", + "Iter 470/500 - Loss: -0.818\n", + "Iter 471/500 - Loss: -0.817\n", + "Iter 472/500 - Loss: -0.817\n", + "Iter 473/500 - Loss: -0.817\n", + "Iter 474/500 - Loss: -0.816\n", + "Iter 475/500 - Loss: -0.815\n", + "Iter 476/500 - Loss: -0.813\n", + "Iter 477/500 - Loss: -0.810\n", + "Iter 478/500 - Loss: -0.802\n", + "Iter 479/500 - Loss: -0.788\n", + "Iter 480/500 - Loss: -0.759\n", + "Iter 481/500 - Loss: -0.704\n", + "Iter 482/500 - Loss: -0.601\n", + "Iter 483/500 - Loss: -0.436\n", + "Iter 484/500 - Loss: -0.244\n", + "Iter 485/500 - Loss: -0.214\n", + "Iter 486/500 - Loss: -0.508\n", + "Iter 487/500 - Loss: -0.807\n", + "Iter 488/500 - Loss: -0.661\n", + "Iter 489/500 - Loss: -0.605\n", + "Iter 490/500 - Loss: -0.804\n", + "Iter 491/500 - Loss: -0.686\n", + "Iter 492/500 - Loss: -0.733\n", + "Iter 493/500 - Loss: -0.775\n", + "Iter 494/500 - Loss: -0.710\n", + "Iter 495/500 - Loss: -0.796\n", + "Iter 496/500 - Loss: -0.723\n", + "Iter 497/500 - Loss: -0.793\n", + "Iter 498/500 - Loss: -0.739\n", + "Iter 499/500 - Loss: -0.789\n", + "Iter 500/500 - Loss: -0.751\n" + ] + } + ], + "source": [ + "# Find optimal model hyperparameters\n", + "model.train()\n", + "test_likelihood.train()\n", + "\n", + "# Use the adam optimizer\n", + "optimizer = torch.optim.Adam([\n", + " {'params': model.parameters()},\n", + " {'params': likelihood.parameters()},\n", + "], lr=0.1)\n", + "\n", + "training_iter = 2 if smoke_test else 500\n", + "\n", + "for i in range(training_iter):\n", + " optimizer.zero_grad()\n", + " output = model(train_x,x_index=train_index)\n", + " loss = -mll(output, train_y)\n", + " loss.backward()\n", + " print('Iter %d/%d - Loss: %.3f' % (i + 1, training_iter, loss.item()))\n", + " optimizer.step()\n", + " \n", + "#increase the nu and train again\n", + "test_likelihood.nu = 10.\n", + "for i in range(training_iter):\n", + " optimizer.zero_grad()\n", + " output = model(train_x,x_index=train_index)\n", + " loss = -mll(output, train_y)\n", + " loss.backward()\n", + " print('Iter %d/%d - Loss: %.3f' % (i + 1, training_iter, loss.item()))\n", + " optimizer.step()" + ] + }, + { + "cell_type": "markdown", + "id": "078aa8d1", + "metadata": {}, + "source": [ + "Lastly, we plot the resulting trained GP and its derivatives. Due to the constraints, the posterior mean does not decrease, and instead becomes flat." + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "f037ab8a", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "
" + ] + }, + "metadata": { + "needs_background": "light" + }, + "output_type": "display_data" + } + ], + "source": [ + "model.eval()\n", + "\n", + "# Initialize plots\n", + "f, (y1_ax, y2_ax) = plt.subplots(1, 2, figsize=(12, 6))\n", + "\n", + "n11=200\n", + "test_x = torch.linspace(lb, ub, n11)\n", + "test_index = torch.ones(test_x.shape[0],ndim+1,dtype=bool)\n", + "\n", + "# Make predictions\n", + "with torch.no_grad(), gpytorch.settings.max_cg_iterations(50):\n", + " predictions = model(test_x,x_index=test_index)\n", + " mean = predictions.mean\n", + " lower, upper = predictions.confidence_region()\n", + "\n", + "# Plot training data as black stars\n", + "y1_ax.plot(train_x[:n1].detach().numpy(), train_y[:n1].detach().numpy(), 'k*')\n", + "# Predictive mean as blue line\n", + "y1_ax.plot(test_x.detach().numpy(), mean[::2].detach().numpy(), 'b')\n", + "# Shade in confidence\n", + "y1_ax.fill_between(test_x.detach().numpy(), lower[::2].detach().numpy(), upper[::2].detach().numpy(), alpha=0.5)\n", + "y1_ax.legend(['Observed Values', 'Mean', 'Confidence'])\n", + "y1_ax.set_title('Function values')\n", + "\n", + "# Predictive mean as blue line\n", + "y2_ax.plot(test_x.detach().numpy(), mean[1::2].detach().numpy(), 'b')\n", + "# Shade in confidence\n", + "y2_ax.fill_between(test_x.detach().numpy(), lower[1::2].detach().numpy(), upper[1::2].detach().numpy(), alpha=0.5)\n", + "y2_ax.legend(['Observed Derivatives', 'Mean', 'Confidence'])\n", + "y2_ax.set_title('Derivatives')\n", + "\n", + "plt.show()" + ] + } + ], + "metadata": { + "jupytext": { + "cell_metadata_filter": "-all", + "main_language": "python", + "notebook_metadata_filter": "-all" + }, + "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.9.16" + }, + "toc": { + "base_numbering": 1, + "nav_menu": {}, + "number_sections": true, + "sideBar": true, + "skip_h1_title": false, + "title_cell": "Table of Contents", + "title_sidebar": "Contents", + "toc_cell": false, + "toc_position": {}, + "toc_section_display": true, + "toc_window_display": false + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} From 69c85bb0d5956ff511ad2606c3c239ec9f0ff37b Mon Sep 17 00:00:00 2001 From: Ankush Aggarwal Date: Sun, 12 Feb 2023 22:17:34 +0000 Subject: [PATCH 3/4] Converted example file to python notebook (added in the previous commit) --- .../08_Advanced_Usage/variationalGP-derivs.py | 124 ------------------ 1 file changed, 124 deletions(-) delete mode 100644 examples/08_Advanced_Usage/variationalGP-derivs.py diff --git a/examples/08_Advanced_Usage/variationalGP-derivs.py b/examples/08_Advanced_Usage/variationalGP-derivs.py deleted file mode 100644 index ddccfc3af..000000000 --- a/examples/08_Advanced_Usage/variationalGP-derivs.py +++ /dev/null @@ -1,124 +0,0 @@ -import torch -import sys -from os.path import dirname, abspath -sys.path.insert(0,dirname(dirname(dirname(abspath(__file__))))) -import gpytorch -import math -from matplotlib import pyplot as plt -import numpy as np - -lb, ub = 0.0, 1. #5*math.pi -n1 = 40 #function values -freq = 0.4 #frequency of the size function -train_x1 = torch.linspace(lb, ub, n1)#.unsqueeze(-1) -train_y1 = torch.sin(freq*train_x1) + 0.005 * torch.randn(train_x1.size()) - -n2=50 #derivative values at different x locations -train_x2 = torch.linspace(lb, ub, n2)#.unsqueeze(-1) -train_y2 = freq*torch.cos(freq*train_x2) + 0.005 * torch.randn(train_x2.size()) - -train_x = torch.cat([train_x1 , train_x2]) -train_y = torch.cat([train_y1,train_y2]) - -ndata,ndim = train_x.shape.numel(),1 -train_index = torch.empty(ndata,ndim+1,dtype=bool) -train_index[:n1,0]=True -train_index[:n1,1]=False -train_index[n1:,0]=False -train_index[n1:,1]=True - -from gpytorch.models import ApproximateGP -from gpytorch.variational import CholeskyVariationalDistribution -from gpytorch.variational import VariationalStrategyIndexed - -class GPModel(ApproximateGP): - def __init__(self): - inducing_points = torch.rand(15)*ub - inducing_index = torch.ones(15,ndim+1,dtype=bool) - variational_distribution = CholeskyVariationalDistribution(torch.sum(inducing_index).item()) - variational_strategy = VariationalStrategyIndexed( - self, inducing_points, variational_distribution, inducing_index, learn_inducing_locations=True - ) - super(GPModel, self).__init__(variational_strategy) - self.mean_module = gpytorch.means.ConstantMeanGrad() - self.covar_module = gpytorch.kernels.ScaleKernel(gpytorch.kernels.RBFKernelGrad()) - - def forward(self, x, index): - index = index.reshape(-1) - mean_x = self.mean_module(x).reshape(-1)[index] - full_kernel = self.covar_module(x) - covar_x = full_kernel[..., index,:][...,:,index] - return gpytorch.distributions.MultivariateNormal(mean_x, covar_x) - -gpytorch.linear_operator.settings.debug._default = False - -likelihood = gpytorch.likelihoods.GaussianLikelihood() -model = GPModel() -# this is for running the notebook in our testing framework -import os -smoke_test = ('CI' in os.environ) -training_iter = 2 if smoke_test else 50 - -# Find optimal model hyperparameters -model.train() -likelihood.train() - -# Use the adam optimizer -optimizer = torch.optim.Adam([ - {'params': model.parameters()}, - {'params': likelihood.parameters()}, -], lr=0.1) - -# "Loss" for GPs - the marginal log likelihood -mll = gpytorch.mlls.ExactMarginalLogLikelihood(likelihood, model) -mll = gpytorch.mlls.VariationalELBO(likelihood, model, num_data=train_y.size(0)) -#print(train_y) -#output = model(train_x1,train_x2) -#loss = -mll(output, train_y) -#loss.backward() - -for i in range(training_iter): - optimizer.zero_grad() - output = model(train_x,x_index=train_index) - loss = -mll(output, train_y) - loss.backward() - print('Iter %d/%d - Loss: %.3f' % (i + 1, training_iter, loss.item())) - optimizer.step() - - -# Set into eval mode -model.eval() -likelihood.eval() - -# Initialize plots -f, (y1_ax, y2_ax) = plt.subplots(1, 2, figsize=(12, 6)) - -n11=200 -test_x = torch.linspace(lb, ub, n11) -test_index = torch.ones(test_x.shape[0],ndim+1,dtype=bool) - -# Make predictions -with torch.no_grad(), gpytorch.settings.max_cg_iterations(50): - predictions = likelihood(model(test_x,x_index=test_index)) - mean = predictions.mean - lower, upper = predictions.confidence_region() - -# Plot training data as black stars -y1_ax.plot(train_x[:n1].detach().numpy(), train_y[:n1].detach().numpy(), 'k*') -# Predictive mean as blue line -y1_ax.plot(test_x.detach().numpy(), mean[::2].detach().numpy(), 'b') -# Shade in confidence -y1_ax.fill_between(test_x.detach().numpy(), lower[::2].detach().numpy(), upper[::2].detach().numpy(), alpha=0.5) -y1_ax.legend(['Observed Values', 'Mean', 'Confidence']) -y1_ax.set_title('Function values') - -# Plot training data as black stars -y2_ax.plot(train_x[n1:].detach().numpy(), train_y[n1:].detach().numpy(), 'k*') -# Predictive mean as blue line -y2_ax.plot(test_x.detach().numpy(), mean[1::2].detach().numpy(), 'b') -# Shade in confidence -y2_ax.fill_between(test_x.detach().numpy(), lower[1::2].detach().numpy(), upper[1::2].detach().numpy(), alpha=0.5) -y2_ax.legend(['Observed Derivatives', 'Mean', 'Confidence']) -y2_ax.set_title('Derivatives') - -plt.show() From b5f47ff82dacf601ad668f440d46f0a30948e7c6 Mon Sep 17 00:00:00 2001 From: Ankush Aggarwal Date: Sun, 12 Feb 2023 22:31:45 +0000 Subject: [PATCH 4/4] Removed unnecessary importing of inspect --- gpytorch/variational/variational_strategy.py | 1 - 1 file changed, 1 deletion(-) diff --git a/gpytorch/variational/variational_strategy.py b/gpytorch/variational/variational_strategy.py index 8ba036b23..dbbe60bb4 100644 --- a/gpytorch/variational/variational_strategy.py +++ b/gpytorch/variational/variational_strategy.py @@ -1,5 +1,4 @@ #!/usr/bin/env python3 -import inspect import warnings import torch