class_docstr: Specifies the rank, dtype and shape of every input to a layer.
  
  Layers can expose (if appropriate) an `input_spec` attribute:
  an instance of `InputSpec`, or a nested structure of `InputSpec` instances
  (one per input tensor). These objects enable the layer to run input
  compatibility checks for input structure, input rank, input shape, and
  input dtype for the first argument of `Layer.__call__`.
  
  A `None` entry in a shape is compatible with any dimension.
  
  Args:
      dtype: Expected DataType of the input.
      shape: Shape tuple, expected shape of the input
          (may include None for unchecked axes). Includes the batch size.
      ndim: Integer, expected rank of the input.
      max_ndim: Integer, maximum rank of the input.
      min_ndim: Integer, minimum rank of the input.
      axes: Dictionary mapping integer axes to
          a specific dimension value.
      allow_last_axis_squeeze: If True, then allow inputs of rank N+1 as long
          as the last axis of the input is 1, as well as inputs of rank N-1
          as long as the last axis of the spec is 1.
      name: Expected key corresponding to this input when passing data as
          a dictionary.
  
  Example:
  
  ```python
  class MyLayer(Layer):
      def __init__(self):
          super(MyLayer, self).__init__()
          # The layer will accept inputs with
          # shape (*, 28, 28) & (*, 28, 28, 1)
          # and raise an appropriate error message otherwise.
          self.input_spec = InputSpec(
              shape=(None, 28, 28, 1),
              allow_last_axis_squeeze=True)
  ```
code: def __init__(
      self,
      dtype=None,
      shape=None,
      ndim=None,
      max_ndim=None,
      min_ndim=None,
      axes=None,
      allow_last_axis_squeeze=False,
      name=None,
  ):
      self.dtype = (
          backend.standardize_dtype(dtype)
          if dtype is not None
          else None
      )
      if shape is not None:
          self.shape = backend.standardize_shape(shape)
          self.ndim = len(shape)
      else:
          self.ndim = ndim
          self.shape = None
      self.max_ndim = max_ndim
      self.min_ndim = min_ndim
      self.name = name
      self.allow_last_axis_squeeze = allow_last_axis_squeeze
      try:
          axes = axes or {}
          self.axes = {int(k): axes[k] for k in axes}
      except (ValueError, TypeError):
          raise TypeError(
              "Argument `axes` must be a dict with integer keys. "
              f"Received: axes={axes}"
          )
  
      if self.axes and (
          self.ndim is not None or self.max_ndim is not None
      ):
          max_dim = (self.ndim if self.ndim else self.max_ndim) - 1
          max_axis = max(self.axes)
          if max_axis > max_dim:
              raise ValueError(
                  "Axis {} is greater than the maximum "
                  "allowed value: {}".format(max_axis, max_dim)
              )
  
file_path: keras/keras/layers/input_spec.py
imports: import tree
  from keras import backend
  from keras.api_export import keras_export
label_desc: Use image node_id 1 to create a new InputSpec object  with example: obj = InputSpec(dtype, shape, ndim, max_ndim, min_ndim, axes, allow_last_axis_squeeze, name)