code: def create_duplicate_branch(nn, path, keep_layer_with_prob=0.5):
      """Creates a new network which creates a new branch between path[0] and path[-1] and
      copies all layers between. It keeps a layer in between with probability 0.5. If
      in CNNs, the layer shrinks the size of the image, then we keep it with prob 1.
      """
      (
          layer_labels,
          num_units_in_each_layer,
          conn_mat,
          mandatory_child_attributes,
      ) = get_copies_from_old_nn(nn)
      # First decide which nodes in the path to keep
      branched_path = [path[0]]
      fc_encountered = False
      for idx in path[1:-1]:
          if idx == path[1] and nn.get_ip_layer_idx() == path[0]:
              branched_path.append(
                  idx
              )  # Append if the branch starts at ip and this is a child.
          elif idx == path[-2] and len(branched_path) == 1:
              branched_path.append(
                  idx
              )  # If this is the last layer and we have not appended yet.
          elif (
              is_a_pooling_layer_label(nn.layer_labels[idx])
              or nn.layer_labels[idx] in ["linear", "softmax"]
              or (hasattr(nn, "strides") and nn.strides[idx] == 2)
          ):
              branched_path.append(idx)
          elif nn.layer_labels[idx] == "fc" and not fc_encountered:
              branched_path.append(idx)
              fc_encountered = True
          elif np.random.random() < keep_layer_with_prob:
              branched_path.append(idx)
      branched_path.append(path[-1])
      # Now create additional nodes
      num_new_nodes = len(branched_path) - 2
      layer_labels.extend(
          [nn.layer_labels[idx] for idx in branched_path[1:-1]]
      )
      num_units_in_each_layer = np.concatenate(
          (
              num_units_in_each_layer,
              [
                  nn.num_units_in_each_layer[idx]
                  for idx in branched_path[1:-1]
              ],
          )
      )
      # Add edges
      new_idxs = list(
          range(nn.num_layers, nn.num_layers + num_new_nodes)
      )
      conn_mat = add_layers_to_end_of_conn_mat(conn_mat, num_new_nodes)
      if num_new_nodes == 0:
          conn_mat[branched_path[0], branched_path[1]] = 1
      else:
          conn_mat[branched_path[0], new_idxs[0]] = 1
          conn_mat[new_idxs[-1], branched_path[-1]] = 1
          for new_idx in new_idxs[:-1]:
              conn_mat[new_idx, new_idx + 1] = 1
      # Add strides
      if nn.nn_class == "cnn":
          mandatory_child_attributes.strides.extend(
              [nn.strides[idx] for idx in branched_path[1:-1]]
          )
      return get_new_nn(
          nn,
          layer_labels,
          num_units_in_each_layer,
          conn_mat,
          mandatory_child_attributes,
      )
  
imports: from argparse import Namespace
  from copy import deepcopy
  import numpy
  from .neural_network import ConvNeuralNetwork, MultiLayerPerceptron, MLP_RECTIFIERS, MLP_SIGMOIDS, is_a_pooling_layer_label, is_a_conv_layer_label, CNNImageSizeMismatchException, CNNNoConvAfterIPException
  from ..utils.general_utils import reorder_list_or_array, reorder_rows_and_cols_in_matrix
  from ..utils.option_handler import get_option_specs, load_options
  from ..utils.reporters import get_reporter
label_desc: Use image node_id 10 for calling a global function with example usage: create_duplicate_branch(nn, path, keep_layer_with_prob) and returns: get_new_nn