code: def test_one_hot_to_numeric(self) -> None:
      dim = 8
      # test exceptions
      categorical_features = {0: 2, 1: 3}
      with self.assertRaises(
          ValueError, msg="Categorical features overlap."
      ):
          OneHotToNumeric(
              dim=dim, categorical_features=categorical_features
          )
      dim = 3
      categorical_features = {0: 6}
      with self.assertRaises(
          ValueError,
          msg="Categorical features exceed the provided dimension.",
      ):
          OneHotToNumeric(
              dim=dim, categorical_features=categorical_features
          )
  
      # set seed to range where this is known to not be flaky
      torch.manual_seed(randint(0, 1000))
      for dtype in (torch.float, torch.double):
          # only categoricals
          dim = 5
          categorical_features = {0: 3, 3: 2}
          tf = OneHotToNumeric(
              dim=dim, categorical_features=categorical_features
          )
          tf.eval()
          self.assertEqual(tf.categorical_features, {0: 3, 3: 2})
          cat1_numeric = torch.randint(0, 3, (3,), device=self.device)
          cat1 = one_hot(cat1_numeric, num_classes=3)
          cat2_numeric = torch.randint(0, 2, (3,), device=self.device)
          cat2 = one_hot(cat2_numeric, num_classes=2)
          X = torch.cat([cat1, cat2], dim=-1)
          # test forward
          X_numeric = tf(X)
          expected = torch.cat(
              [
                  cat1_numeric.view(-1, 1).to(
                      dtype=dtype, device=self.device
                  ),
                  cat2_numeric.view(-1, 1).to(
                      dtype=dtype, device=self.device
                  ),
              ],
              dim=-1,
          )
          self.assertTrue(torch.equal(X_numeric, expected))
          X2 = tf.untransform(X_numeric)
          self.assertTrue(torch.equal(X2, X))
  
          # two categoricals at end
          dim = 8
          categorical_features = {6: 2, 3: 3}
          tf = OneHotToNumeric(
              dim=dim, categorical_features=categorical_features
          )
          tf.eval()
          self.assertEqual(tf.categorical_features, {3: 3, 6: 2})
          cat1_numeric = torch.randint(0, 3, (3,), device=self.device)
          cat1 = one_hot(cat1_numeric, num_classes=3)
          cat2_numeric = torch.randint(0, 2, (3,), device=self.device)
          cat2 = one_hot(cat2_numeric, num_classes=2)
          cont = torch.rand(3, 3, dtype=dtype, device=self.device)
          X = torch.cat([cont, cat1, cat2], dim=-1)
          # test forward
          X_numeric = tf(X)
          expected = torch.cat(
              [
                  cont,
                  cat1_numeric.view(-1, 1).to(cont),
                  cat2_numeric.view(-1, 1).to(cont),
              ],
              dim=-1,
          )
          self.assertTrue(torch.equal(X_numeric, expected))
          X2 = tf.untransform(X_numeric)
          self.assertTrue(torch.equal(X2, X))
  
          # three categoricals at end
          dim = 10
          categorical_features = {
              6: 2,
              3: 3,
              8: 2,
          }
          tf = OneHotToNumeric(
              dim=dim, categorical_features=categorical_features
          )
          tf.eval()
          self.assertEqual(tf.categorical_features, {3: 3, 6: 2, 8: 2})
          cat1_numeric = torch.randint(0, 3, (3,), device=self.device)
          cat1 = one_hot(cat1_numeric, num_classes=3)
          cat2_numeric = torch.randint(0, 2, (3,), device=self.device)
          cat2 = one_hot(cat2_numeric, num_classes=2)
          cat3_numeric = torch.randint(0, 2, (3,), device=self.device)
          cat3 = one_hot(cat3_numeric, num_classes=2)
          cont = torch.rand(3, 3, dtype=dtype, device=self.device)
          X = torch.cat([cont, cat1, cat2, cat3], dim=-1)
          # test forward
          X_numeric = tf(X)
          expected = torch.cat(
              [
                  cont,
                  cat1_numeric.view(-1, 1).to(cont),
                  cat2_numeric.view(-1, 1).to(cont),
                  cat3_numeric.view(-1, 1).to(cont),
              ],
              dim=-1,
          )
          self.assertTrue(torch.equal(X_numeric, expected))
          X2 = tf.untransform(X_numeric)
          self.assertTrue(torch.equal(X2, X))
  
          # three categoricals, one at start, two at end
          dim = 10
          categorical_features = {
              0: 3,
              6: 2,
              8: 2,
          }
          tf = OneHotToNumeric(
              dim=dim, categorical_features=categorical_features
          )
          tf.eval()
          self.assertEqual(tf.categorical_features, {0: 3, 6: 2, 8: 2})
          cat1_numeric = torch.randint(0, 3, (3,), device=self.device)
          cat1 = one_hot(cat1_numeric, num_classes=3)
          cat2_numeric = torch.randint(0, 2, (3,), device=self.device)
          cat2 = one_hot(cat2_numeric, num_classes=2)
          cat3_numeric = torch.randint(0, 2, (3,), device=self.device)
          cat3 = one_hot(cat3_numeric, num_classes=2)
          cont = torch.rand(3, 3, dtype=dtype, device=self.device)
          X = torch.cat([cat1, cont, cat2, cat3], dim=-1)
          # test forward
          X_numeric = tf(X)
          expected = torch.cat(
              [
                  cat1_numeric.view(-1, 1).to(cont),
                  cont,
                  cat2_numeric.view(-1, 1).to(cont),
                  cat3_numeric.view(-1, 1).to(cont),
              ],
              dim=-1,
          )
          self.assertTrue(torch.equal(X_numeric, expected))
          X2 = tf.untransform(X_numeric)
          self.assertTrue(torch.equal(X2, X))
  
          # test no
          tf = OneHotToNumeric(dim=dim, categorical_features={})
          tf.eval()
          X_tf = tf(X)
          self.assertTrue(torch.equal(X, X_tf))
          X2 = tf(X_tf)
          self.assertTrue(torch.equal(X2, X_tf))
  
      # test no transform on eval
      tf2 = OneHotToNumeric(
          dim=dim,
          categorical_features=categorical_features,
          transform_on_eval=False,
      )
      tf2.eval()
      X_tf = tf2(X)
      self.assertTrue(torch.equal(X, X_tf))
  
      # test no transform on train
      tf2 = OneHotToNumeric(
          dim=dim,
          categorical_features=categorical_features,
          transform_on_train=False,
      )
      X_tf = tf2(X)
      self.assertTrue(torch.equal(X, X_tf))
      tf2.eval()
      X_tf = tf2(X)
      self.assertFalse(torch.equal(X, X_tf))
  
      # test equals
      tf3 = OneHotToNumeric(
          dim=dim,
          categorical_features=categorical_features,
          transform_on_train=False,
      )
      self.assertTrue(tf3.equals(tf2))
      # test different transform_on_train
      tf3 = OneHotToNumeric(
          dim=dim,
          categorical_features=categorical_features,
          transform_on_train=True,
      )
      self.assertFalse(tf3.equals(tf2))
      # test categorical features
      tf3 = OneHotToNumeric(
          dim=dim, categorical_features={}, transform_on_train=False
      )
      self.assertFalse(tf3.equals(tf2))
  
imports: import itertools
  import warnings
  from copy import deepcopy
  from random import randint
  import torch
  from botorch import settings
  from botorch.exceptions.errors import BotorchTensorDimensionError
  from botorch.exceptions.warnings import UserInputWarning
  from botorch.models.transforms.input import AffineInputTransform, AppendFeatures, ChainedInputTransform, FilterFeatures, InputPerturbation, InputStandardize, InputTransform, Log10, Normalize, OneHotToNumeric, Round, Warp
  from botorch.models.transforms.utils import expand_and_copy_tensor
  from botorch.models.utils import fantasize
  from botorch.utils.testing import BotorchTestCase
  from gpytorch.priors import LogNormalPrior
  from torch import Tensor
  from torch.distributions import Kumaraswamy
  from torch.nn import Module
  from torch.nn.functional import one_hot
label_desc: Use image node_id 9 for calling the TestInputTransforms obj's underlying member method code with example usage: obj.test_one_hot_to_numeric() without return types