class_docstr: A Model is a network (more precisely, a directed acyclic graph) of Steps,
  and it is defined from the input/output specification of the pipeline.
  Models have fit and predict routines that, together with graph-based engine,
  allow the automatic (feed-forward) computation of each of the pipeline steps
  when fed with data.
  
  Parameters
  ----------
  inputs
      Inputs to the model.
  
  outputs
      Outputs of the model.
  
  targets
      Targets of the model.
  
  name
      Name of the model (optional). If no name is passed, a name will be
      automatically generated.
code: def _replace_step(self, step_key, new_step):
      # Transfer connectivity configuration from old step
      # to new step and rebuild the model graph
      # TODO: Add check for isinstance(new_step, Step) to fail early before messing things up
      old_step = self._steps[step_key]
  
      new_step._name = old_step._name
      new_step._nodes = old_step._nodes
      for node in new_step._nodes:
          node.step = new_step
  
      # Rebuild model
      self._build()
  
imports: from collections import defaultdict
  from typing import Union, List, Dict, Set, Iterable, Optional
  from baikal._core.data_placeholder import is_data_placeholder_list, DataPlaceholder
  from baikal._core.digraph import DiGraph
  from baikal._core.step import Step, InputStep, Node
  from baikal._core.typing import ArrayLike
  from baikal._core.utils import listify, safezip2, SimpleCache, unlistify
label_desc: Use image node_id 17 for calling the Model obj's underlying member method code with example usage: obj._replace_step(step_key, new_step) without return types