code: def test_optimizer_params(self):
      optimizer_params = Params(
          {
              "type": "multi",
              "optimizers": {
                  "default": {"type": "adam", "lr": 1},
                  "embedder": {"type": "adam", "lr": 2},
                  "encoder": {"type": "adam", "lr": 3},
              },
              "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}],
              ],
          }
      )
  
      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
      )
  
      # When the MultiOptimizer is initialized, `optimizer.param_groups` stores the parameter groups.
      # These parameter groups are assigned to their own optimizer by the MultiOptimizer.
      # Check that changes to the parameters in optimizer.param_groups affect the parameters in
      # optimizer._grouped_optimizers.
      regex_optimizer_params = set()
      regex_optimizer_grouped_optimizer_params = set()
  
      for param_group in optimizer.param_groups:
          # Each param_group should have optimizer options visible so they can be used by schedulers.
          lr = param_group["lr"]
          assert lr > 0
          params = param_group["params"]
          for param in params:
              param.data.zero_()
              regex_optimizer_params.add(id(param))
  
      # Check that the parameters of the sub-optimizers were also changed.
      for optimizer in optimizer.optimizers.values():
          for param_group in optimizer.param_groups:
              params = param_group["params"]
              for param in params:
                  regex_optimizer_grouped_optimizer_params.add(
                      id(param)
                  )
                  assert param.sum() == 0, "Param has non-zero values."
  
      assert (
          regex_optimizer_params
          == regex_optimizer_grouped_optimizer_params
      )
  
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 3 for calling the TestMultiOptimizer obj's underlying member method code with example usage: obj.test_optimizer_params() without return types