code: def test_multiple_optimizers(self):
      optimizer_params = Params(
          {
              "type": "multi",
              "optimizers": {
                  "embedder": {"type": "adam", "lr": 2},
                  "encoder": {"type": "adam", "lr": 3},
                  "default": {"type": "adam", "lr": 1},
              },
              "parameter_groups": [
                  [
                      ["^text_field_embedder"],
                      {
                          "optimizer_name": "embedder",
                          "betas": (0.9, 0.98),
                          "lr": 2,
                          "weight_decay": 0.01,
                      },
                  ],
                  [
                      ["^encoder.*bias"],
                      {"optimizer_name": "encoder", "lr": 0.001},
                  ],
                  [
                      ["^encoder.*weight"],
                      {"optimizer_name": "encoder", "lr": 0.002},
                  ],
                  [["^tag_projection_layer.*.weight$"], {"lr": 5}],
              ],
          }
      )
      optimizer_params_copy = copy.deepcopy(optimizer_params)
  
      parameters = [
          [n, p]
          for n, p in self.model.named_parameters()
          if p.requires_grad
      ]
      optimizer = Optimizer.from_params(
          model_parameters=parameters, params=optimizer_params
      )
  
      # make sure that every parameter is assigned to exactly one optimizer
      regex_to_optimizer_name = {
          regex: params.get("optimizer_name", "default")
          for regexes, params in optimizer_params_copy[
              "parameter_groups"
          ]
          for regex in regexes
      }
      for parameter_name, parameter in parameters:
          optimizer_names_for_parameter = [
              optimizer_name
              for regex, optimizer_name in regex_to_optimizer_name.items()
              if re.search(regex, parameter_name)
          ]
          if len(optimizer_names_for_parameter) <= 0:
              optimizer_names_for_parameter = ["default"]
          assert (
              len(set(optimizer_names_for_parameter)) == 1
          ), f"Parameter {parameter_name} is assigned to more than one optimizer."
          assert (
              len(optimizer_names_for_parameter) == 1
          ), f"Parameter {parameter_name} is assigned to the same optimizer more than once."
  
          # make sure the parameter is really assigned to that optimizer
          inner_optimizer = optimizer.optimizers[
              optimizer_names_for_parameter[0]
          ]
          parameters_in_optimizer = [
              id(p)
              for pg in inner_optimizer.param_groups
              for p in pg["params"]
          ]
          assert id(parameter) in parameters_in_optimizer
  
      # make sure the optimizer parameters propagated properly
      for i, (name, inner_optimizer) in enumerate(
          optimizer.optimizers.items()
      ):
          if i == 0:
              assert (
                  name == "embedder"
              ), "Optimizers were not initialized in the same order as parameter groups."
              param_groups = inner_optimizer.param_groups
              assert (
                  len(param_groups) == 1 + 1
              )  # one extra for the empty default group
              assert (
                  len(param_groups[-1]["params"]) == 0
              )  # default group for an inner optimizer should be empty
              assert param_groups[0]["betas"] == (0.9, 0.98)
              assert param_groups[0]["lr"] == 2
              assert param_groups[0]["weight_decay"] == 0.01
          elif i == 1:
              assert (
                  name == "encoder"
              ), "Optimizers were not initialized in the same order as parameter groups."
              param_groups = inner_optimizer.param_groups
              # The optimizer can have sub-groups with different options.
              assert (
                  len(param_groups) == 2 + 1
              )  # one extra for the empty default group
              assert (
                  len(param_groups[-1]["params"]) == 0
              )  # default group for an inner optimizer should be empty
              for i, param_group in enumerate(param_groups):
                  if i == 0:
                      assert param_group["lr"] == 0.001
                  elif i == 1:
                      assert param_group["lr"] == 0.002
          elif i == 2:
              assert (
                  name == "default"
              ), "Optimizers were not initialized in the same order as parameter groups."
              param_groups = inner_optimizer.param_groups
              # Default group gets assigned any group without an 'optimizer_name' parameter in `parameter_groups`
              # as well as any parameters which didn't match one of the given regexes.
              assert len(param_groups) == 2
  
imports: import copy
  import re
  from allennlp.common.params import Params
  from allennlp.common.testing import AllenNlpTestCase
  from allennlp.data import Vocabulary
  from allennlp.data.dataset_readers import SequenceTaggingDatasetReader
  from allennlp.data.data_loaders import SimpleDataLoader
  from allennlp.models.simple_tagger import SimpleTagger
  from allennlp.training import GradientDescentTrainer
  from allennlp.training.optimizers import Optimizer
label_desc: Use image node_id 2 for calling the TestMultiOptimizer obj's underlying member method code with example usage: obj.test_multiple_optimizers() without return types