code: def convert(in_file, out_file, num_classes):
      """Convert keys in checkpoints.
  
      There can be some breaking changes during the development of mmdetection,
      and this tool is used for upgrading checkpoints trained with old versions
      to the latest one.
      """
      checkpoint = torch.load(in_file)
      in_state_dict = checkpoint.pop("state_dict")
      out_state_dict = OrderedDict()
      meta_info = checkpoint["meta"]
      is_two_stage, is_ssd, is_retina, reg_cls_agnostic = parse_config(
          "#" + meta_info["config"]
      )
      if meta_info["mmdet_version"] <= "0.5.3" and is_retina:
          upgrade_retina = True
      else:
          upgrade_retina = False
  
      # MMDetection v2.5.0 unifies the class order in RPN
      # if the model is trained in version<v2.5.0
      # The RPN model should be upgraded to be used in version>=2.5.0
      if meta_info["mmdet_version"] < "2.5.0":
          upgrade_rpn = True
      else:
          upgrade_rpn = False
  
      for key, val in in_state_dict.items():
          new_key = key
          new_val = val
          if is_two_stage and is_head(key):
              new_key = "roi_head.{}".format(key)
  
          # classification
          if upgrade_rpn:
              m = re.search(
                  r"(conv_cls|retina_cls|rpn_cls|fc_cls|fcos_cls|"
                  r"fovea_cls).(weight|bias)",
                  new_key,
              )
          else:
              m = re.search(
                  r"(conv_cls|retina_cls|fc_cls|fcos_cls|"
                  r"fovea_cls).(weight|bias)",
                  new_key,
              )
          if m is not None:
              print(f"reorder cls channels of {new_key}")
              new_val = reorder_cls_channel(val, num_classes)
  
          # regression
          if upgrade_rpn:
              m = re.search(r"(fc_reg).(weight|bias)", new_key)
          else:
              m = re.search(r"(fc_reg|rpn_reg).(weight|bias)", new_key)
          if m is not None and not reg_cls_agnostic:
              print(f"truncate regression channels of {new_key}")
              new_val = truncate_reg_channel(val, num_classes)
  
          # mask head
          m = re.search(r"(conv_logits).(weight|bias)", new_key)
          if m is not None:
              print(f"truncate mask prediction channels of {new_key}")
              new_val = truncate_cls_channel(val, num_classes)
  
          m = re.search(r"(cls_convs|reg_convs).\d.(weight|bias)", key)
          # Legacy issues in RetinaNet since V1.x
          # Use ConvModule instead of nn.Conv2d in RetinaNet
          # cls_convs.0.weight -> cls_convs.0.conv.weight
          if m is not None and upgrade_retina:
              param = m.groups()[1]
              new_key = key.replace(param, f"conv.{param}")
              out_state_dict[new_key] = val
              print(f"rename the name of {key} to {new_key}")
              continue
  
          m = re.search(r"(cls_convs).\d.(weight|bias)", key)
          if m is not None and is_ssd:
              print(f"reorder cls channels of {new_key}")
              new_val = reorder_cls_channel(val, num_classes)
  
          out_state_dict[new_key] = new_val
      checkpoint["state_dict"] = out_state_dict
      torch.save(checkpoint, out_file)
  
file_path: mmdetection/tools/model_converters/upgrade_model_version.py
imports: import argparse
  import re
  import tempfile
  from collections import OrderedDict
  import torch
  from mmengine import Config
label_desc: Use image node_id 6 for calling a global function with example usage: convert(in_file, out_file, num_classes) without return types