class_docstr: Hourglass network architecture.
  
  Attributes:
    heads: Dict, keys are head names, value for each key is a dict with {'dim':
      dim} where dim is the output dimensionality of the last convolution.
    features_dims: Integer list, feature dimensionality at the output of the
      input downsampling convolution block and at the output of each encoder
      stage.
    number_hourglasses: Integer, number of hourglasses to stack.
    depth: Integer, depth of the encoder.
    blocks_per_stage: Integer list, number of residual blocks at each encoder
      stage.
    name: String, name of the block.
code: def __init__(
      self,
      input_shape=gin.REQUIRED,
      heads=None,
      features_dims=(128, 256, 256, 384, 384, 384, 512),
      number_hourglasses=2,
      depth=5,
      blocks_per_stage=(2, 2, 2, 2, 2, 4),
      kernel_regularization=None,
      return_output_features=False,
      name="hourglass",
  ):
      super(Hourglass, self).__init__(name=name)
      norm_type = networks.NormType("batchnorm", {})
      kernel_regularizer = networks.Regularization(
          kernel_regularization
      )
  
      self.output_stride = 4
      self.heads = heads
      self.number_hourglasses = number_hourglasses
      self.return_output_features = return_output_features
  
      self.downsample_input = InputDownsampleBlock(
          input_shape, features_dims[:2], norm_type, kernel_regularizer
      )
      self.hourglass_network = []
      self.output_conv = []
      for _ in range(self.number_hourglasses):
          self.hourglass_network.append(
              EncoderDecoderBlock(
                  depth,
                  features_dims[1:],
                  blocks_per_stage,
                  norm_type,
                  kernel_regularizer,
              )
          )
          self.output_conv.append(
              network_cb.ConvolutionalBlock(
                  3, features_dims[1], norm_type, kernel_regularizer
              )
          )
      self.intermediate_conv1 = []
      self.intermediate_conv2 = []
      self.intermediate_residual = []
      for _ in range(self.number_hourglasses - 1):
          self.intermediate_conv1.append(
              network_cb.ConvolutionalBlock(
                  1,
                  features_dims[1],
                  norm_type,
                  kernel_regularizer,
                  relu=False,
              )
          )
          self.intermediate_conv2.append(
              network_cb.ConvolutionalBlock(
                  1,
                  features_dims[1],
                  norm_type,
                  kernel_regularizer,
                  relu=False,
              )
          )
          self.intermediate_residual.append(
              network_cb.ResidualBlock(
                  features_dims[1], norm_type, kernel_regularizer
              )
          )
      self.intermediate_relu = tf.keras.layers.ReLU()
  
      if self.heads is not None:
          for name, val in self.heads.items():
              self.__setattr__(name, [])
              for _ in range(self.number_hourglasses):
                  if "classification" in name:
                      self.__getattribute__(name).append(
                          ClassificationHead(
                              norm_type,
                              kernel_regularizer,
                              name=name,
                              **val,
                          )
                      )
                  else:
                      self.__getattribute__(name).append(
                          Head(
                              features_dims[1],
                              name=name,
                              norm_type=norm_type,
                              kernel_regularizer=kernel_regularizer,
                              **val,
                          )
                      )
  
imports: import gin
  import tensorflow
  from tensorflow_graphics.projects.points_to_3Dobjects.networks import networks
  import tensorflow_graphics.projects.points_to_3Dobjects.networks.custom_blocks
label_desc: Use image node_id 1 to create a new Hourglass object from inherited base classes: tf.keras with example: obj = Hourglass(input_shape, heads, features_dims, number_hourglasses, depth, blocks_per_stage, kernel_regularization, return_output_features, name)