class_docstr: A middleware embedder is the middle part of the network. It takes the embeddings from the input embedders,
  after they were aggregated in some method (for example, concatenation) and passes it through a neural network
  which can be customizable but shared between the heads of the network
docstr: Wrapper for building the module graph including scoping and loss creation
  :param input_layer: the input to the graph
  :return: the input placeholder and the output of the last layer
docstr_tok: ["Wrapper","for","building","the","module","graph","including","scoping","and","loss","creation",":","param","input_layer",":","the","input","to","the","graph",":","return",":","the","input","placeholder","and","the","output","of","the","last","layer"]
code: def __call__(
      self, input_layer: tf.Tensor
  ) -> Tuple[tf.Tensor, tf.Tensor]:
      """
      Wrapper for building the module graph including scoping and loss creation
      :param input_layer: the input to the graph
      :return: the input placeholder and the output of the last layer
      """
      with tf.variable_scope(self.get_name()):
          self.input = input_layer
          self._build_module()
  
      return self.input, self.output
  
file_path: coach/rl_coach/architectures/tensorflow_components/middlewares/middleware.py
imports: import copy
  from typing import Union, Tuple
  import tensorflow
  from rl_coach.architectures.tensorflow_components.layers import BatchnormActivationDropout, convert_layer, Dense
  from rl_coach.base_parameters import MiddlewareScheme, NetworkComponentParameters
  from rl_coach.core_types import MiddlewareEmbedding
label_desc: Use image node_id 2 for calling the Middleware obj's underlying member method code with example usage: obj.__call__(input_layer) and returns: self,  self