I'm attempting to perform multi-task Gaussian process regression using GPyTorch. I have, for each of N training examples, its corresponding (T x T) cross-task noise covariance matrix. I aim to implement a multi-task version of GPyTorch's FixedNoiseGaussianLikelihood class, which accepts a scalar variance (since it's for one-task GPR). I'm told I must define a subclass of FixedGaussianNoise which accepts this (N x T x T) noise tensor, and modifies its forward pass
def forward(
self, *params: Any, shape: Optional[torch.Size] = None, noise: Optional[Tensor] = None,
**kwargs: Any
) -> DiagLinearOperator:
if shape is None:
p = params[0] if torch.is_tensor(params[0]) else params[0][0]
shape = p.shape if len(p.shape) == 1 else p.shape[:-1]
if noise is not None:
return DiagLinearOperator(noise)
elif shape[-1] == self.noise.shape[-1]:
return DiagLinearOperator(self.noise)
else:
return ZeroLinearOperator()
such that it returns a BlockDiagLinearOperator rather than a DiagLinearOperator, then use this new class as the noise_covar argument to initialize a _MultitaskGaussianLikelihoodBase. My implementation is this:
class MyNoise(gpytorch.likelihoods.noise_models.FixedGaussianNoise):
def forward(self, *params, shape=None, noise=None, **kwargs):
return linear_operator.operators.BlockDiagLinearOperator(self.noise)
I'll be making predictions solely on my training inputs. However, I encounter the error below. BlockDiagLinearOperator assumes my self.noise is itself a LinearOperator. What should I do about this? Is there something I'm not understanding? I'm new to GPyTorch, and any help is greatly appreciated!
[/usr/local/lib/python3.12/dist-packages/linear_operator/operators/block_diag_linear_operator.py](https://localhost:8080/#) in _diagonal(self)
92
93 def _diagonal(self: Float[LinearOperator, "... M N"]) -> Float[torch.Tensor, "... N"]:
---> 94 res = self.base_linear_op._diagonal().contiguous()
95 return res.view(*self.batch_shape, self.size(-1))
96
AttributeError: 'Tensor' object has no attribute '_diagonal'