code: def make_siamese(
      query_config: DictConfig,
      response_config: DictConfig,
      single_models: Dict,
      query_fusion_model: Union[nn.Module, functools.partial],
      response_fusion_model: Union[nn.Module, functools.partial],
      share_fusion: bool,
      initialized: Optional[bool] = False,
  ):
      """
      Build a siamese network, in which the query and response share the same encoders for the same modalities.
  
      Parameters
      ----------
      query_config
          The query config.
      response_config
          The response config.
      single_models
          A dict of single models used in the late-fusion.
      query_fusion_model
          The fusion piece of the query model.
      response_fusion_model
          The fusion piece of the response model.
      share_fusion
          Whether the query and response share the fusion piece.
      initialized
          Whether the fusion piece is initialized.
  
      Returns
      -------
      The query and response models satisfying the siamese constraint.
      """
      query_model_names = [
          n
          for n in query_config.model.names
          if not n.lower().startswith(FUSION)
      ]
      query_fusion_model_name = [
          n
          for n in query_config.model.names
          if n.lower().startswith(FUSION)
      ]
      assert len(query_fusion_model_name) <= 1
      if len(query_fusion_model_name) == 1:
          query_fusion_model_name = query_fusion_model_name[0]
      response_model_names = [
          n
          for n in response_config.model.names
          if not n.lower().startswith(FUSION)
      ]
      response_fusion_model_name = [
          n
          for n in response_config.model.names
          if n.lower().startswith(FUSION)
      ]
      assert len(response_fusion_model_name) <= 1
      if len(response_fusion_model_name) == 1:
          response_fusion_model_name = response_fusion_model_name[0]
  
      logger.debug(f"single model names: {list(single_models.keys())}")
      logger.debug(
          f"query fusion model name: {query_fusion_model_name}"
      )
      logger.debug(
          f"response fusion model name: {response_fusion_model_name}"
      )
  
      # use shallow copy to create query single models
      query_single_models = []
      for model_name in query_model_names:
          model = copy.copy(
              single_models[model_name[:-6]]
          )  # cut off _query
          model.prefix = model_name
          query_single_models.append(model)
  
      # use shallow copy to create response single models
      response_single_models = []
      for model_name in response_model_names:
          model = copy.copy(
              single_models[model_name[:-9]]
          )  # cut off _response
          model.prefix = model_name
          response_single_models.append(model)
  
      if len(query_single_models) == 1:
          query_model = query_single_models[0]
      else:
          if initialized:
              query_model = query_fusion_model
              query_model.model = nn.ModuleList(query_single_models)
          else:
              query_model = query_fusion_model(
                  models=query_single_models
              )
  
          query_model.prefix = query_fusion_model_name
  
      if len(response_single_models) == 1:
          response_model = response_single_models[0]
      else:
          if share_fusion:
              response_model = copy.copy(
                  query_model
              )  # copy query_model rather than query_fusion_model
              response_model.model = nn.ModuleList(
                  response_single_models
              )
          else:
              if initialized:
                  response_model = response_fusion_model
                  response_model.model = nn.ModuleList(
                      response_single_models
                  )
              else:
                  response_model = response_fusion_model(
                      models=response_single_models
                  )
  
          response_model.prefix = response_fusion_model_name
  
      return query_model, response_model
  
imports: import copy
  import functools
  import heapq
  import logging
  from typing import Dict, List, Optional, Union
  import pandas
  import torch
  from omegaconf import DictConfig
  from torch import nn
  from torch.nn import functional
  from ..constants import FUSION, QUERY, RESPONSE
  from .data import data_to_df
  from .model import create_model
label_desc: Use image node_id 3 for calling a global function with example usage: make_siamese(query_config, response_config, single_models, query_fusion_model, response_fusion_model, share_fusion, initialized) and returns: query_model,  response_model