class_docstr: Computes similarities as k(x,y) = (1-eps)*k_a(proj(x), proj(y)) + eps*k_b(x,y).
  A forward pass takes a batch of instances x [Nx, features] and y [Ny, features] and returns
  the kernel matrix [Nx, Ny].
  
  Parameters
  ----------
  proj
      The projection to be applied to the inputs before applying kernel_a
  kernel_a
      The kernel to apply to the projected inputs. Defaults to a Gaussian RBF with trainable bandwidth.
  kernel_b
      The kernel to apply to the raw inputs. Defaults to a Gaussian RBF with trainable bandwidth.
      Set to None in order to use only the deep component (i.e. eps=0).
  eps
      The proportion (in [0,1]) of weight to assign to the kernel applied to raw inputs. This can be
      either specified or set to 'trainable'. Only relavent if kernel_b is not None.
code: def __init__(
      self,
      proj: nn.Module,
      kernel_a: Union[nn.Module, str] = "rbf",
      kernel_b: Optional[Union[nn.Module, str]] = "rbf",
      eps: Union[float, str] = "trainable",
  ) -> None:
      super().__init__()
      self.config = {
          "proj": proj,
          "kernel_a": kernel_a,
          "kernel_b": kernel_b,
          "eps": eps,
      }
      if kernel_a == "rbf":
          kernel_a = GaussianRBF(trainable=True)
      if kernel_b == "rbf":
          kernel_b = GaussianRBF(trainable=True)
      self.kernel_a = kernel_a
      self.kernel_b = kernel_b
      self.proj = proj
      if kernel_b is not None:
          self._init_eps(eps)
  
imports: import numpy
  import torch
  from torch import nn
  from .None import distance
  from typing import Optional, Union, Callable
  from alibi_detect.utils.frameworks import Framework
label_desc: Use image node_id 1 to create a new DeepKernel object from inherited base classes: nn with example: obj = DeepKernel(proj, kernel_a, kernel_b, eps)