code: def test_kernel_feature_map(self):
      d = 2
      m = 3
      weight = torch.rand(m, d, device=self.device)
      bias = torch.rand(m, device=self.device)
      kernel = MaternKernel(nu=2.5, batch_shape=Size([3])).to(
          self.device
      )
      feature_map = KernelFeatureMap(
          kernel=kernel,
          weight=weight,
          bias=bias,
          input_transform=MagicMock(side_effect=lambda x: x),
          output_transform=MagicMock(side_effect=lambda z: z.exp()),
      )
  
      X = torch.rand(2, d, device=self.device)
      features = feature_map(X)
      feature_map.input_transform.assert_called_once_with(X)
      feature_map.output_transform.assert_called_once()
      self.assertTrue(
          (X @ weight.transpose(-2, -1) + bias).exp().equal(features)
      )
  
      # Test batch_shape and num_outputs
      self.assertIs(feature_map.batch_shape, kernel.batch_shape)
      self.assertEqual(feature_map.num_outputs, weight.shape[-2])
      with patch.object(feature_map, "output_transform", new=None):
          self.assertEqual(feature_map.num_outputs, weight.shape[-2])
  
file_path: botorch/test/sampling/pathwise/features/test_maps.py
imports: from __future__ import annotations
  from unittest.mock import MagicMock, patch
  import torch
  from botorch.sampling.pathwise.features import KernelEvaluationMap, KernelFeatureMap
  from botorch.utils.testing import BotorchTestCase
  from gpytorch.kernels import MaternKernel
  from torch import Size
label_desc: Use image node_id 2 for calling the TestFeatureMaps obj's underlying member method code with example usage: obj.test_kernel_feature_map() without return types