text: Title: Default value for "training" parameter for BatchNorm custom layer call method
  Body: ```
  class BatchNorm(tf.keras.layers.Layer):
  .
  .
  .
      @tf.function
      def call(self, inputs, training):
          if training:
              axes = list(range(len(inputs.shape) - 1))
              batch_mean = tf.reduce_mean(inputs, axes, keepdims=True)
              batch_variance = tf.reduce_mean(tf.math.squared_difference(
                  inputs, tf.stop_gradient(batch_mean)), axes, keepdims=True)
              batch_mean = tf.squeeze(batch_mean, axes)
              batch_variance = tf.squeeze(batch_variance, axes)
            .
            .
            .
          else:
            .
            .
          return output
  ```
  
  [Above is the scratch implementation of Batch Normalization layer](https://d2l.ai/chapter_convolutional-modern/batch-norm.html#implementation-from-scratch). 
  
  The call method doesn't have a default training parameter( **None or True**). 
  
  [When this particular implementation is plugged into a Sequential model  as shown in D2l Lenet implementation, ](https://d2l.ai/chapter_convolutional-modern/batch-norm.html#applying-batch-normalization-in-lenet) 
  
  ```
  def net():
      return tf.keras.models.Sequential([
          tf.keras.layers.Conv2D(filters=6, kernel_size=5,
                                 input_shape=(28, 28, 1)),
          BatchNorm(),
          tf.keras.layers.Activation('sigmoid'),
          tf.keras.layers.AvgPool2D(pool_size=2, strides=2),
          tf.keras.layers.Conv2D(filters=16, kernel_size=5),
          BatchNorm(),
          tf.keras.layers.Activation('sigmoid'),
          tf.keras.layers.AvgPool2D(pool_size=2, strides=2),
          tf.keras.layers.Flatten(),
          tf.keras.layers.Dense(120),
          BatchNorm(),
          tf.keras.layers.Activation('sigmoid'),
          tf.keras.layers.Dense(84),
          BatchNorm(),
          tf.keras.layers.Activation('sigmoid'),
          tf.keras.layers.Dense(10)]
      )
  ```
  I get the **" tf__call() missing 1 required positional argument: 'training'"** error as shown below
  
  ```
  2022-03-31 06:14:37.125158: I tensorflow/stream_executor/platform/default/dso_loader.cc:44] Successfully opened dynamic library cublas64_10.dll
  Traceback (most recent call last):
    File "D:/codebase/d2l-2/MCN/exercises/GoogleNet/runner.py", line 11, in <module>
      X = layer(X)
    File "C:\Users\goofy\d2l\lib\site-packages\tensorflow\python\keras\engine\base_layer.py", line 968, in __call__
      outputs = self.call(cast_inputs, *args, **kwargs)
    File "D:\codebase\d2l-2\MCN\exercises\GoogleNet\blocks\B1.py", line 14, in call
      bridged_input = self.conv(bridged_input)
    File "C:\Users\goofy\d2l\lib\site-packages\tensorflow\python\keras\engine\base_layer.py", line 968, in __call__
      outputs = self.call(cast_inputs, *args, **kwargs)
    File "D:\codebase\d2l-2\MCN\exercises\GoogleNet\ConvBNRelu.py", line 22, in call
      bridged_input = self.batch_norm(bridged_input)
    File "C:\Users\goofy\d2l\lib\site-packages\tensorflow\python\keras\engine\base_layer.py", line 968, in __call__
      outputs = self.call(cast_inputs, *args, **kwargs)
    File "C:\Users\goofy\d2l\lib\site-packages\tensorflow\python\eager\def_function.py", line 580, in __call__
      result = self._call(*args, **kwds)
    File "C:\Users\goofy\d2l\lib\site-packages\tensorflow\python\eager\def_function.py", line 618, in _call
      results = self._stateful_fn(*args, **kwds)
    File "C:\Users\goofy\d2l\lib\site-packages\tensorflow\python\eager\function.py", line 2419, in __call__
      graph_function, args, kwargs = self._maybe_define_function(args, kwargs)
    File "C:\Users\goofy\d2l\lib\site-packages\tensorflow\python\eager\function.py", line 2777, in _maybe_define_function
      graph_function = self._create_graph_function(args, kwargs)
    File "C:\Users\goofy\d2l\lib\site-packages\tensorflow\python\eager\function.py", line 2667, in _create_graph_function
      capture_by_value=self._capture_by_value),
    File "C:\Users\goofy\d2l\lib\site-packages\tensorflow\python\framework\func_graph.py", line 981, in func_graph_from_py_func
      func_outputs = python_func(*func_args, **func_kwargs)
    File "C:\Users\goofy\d2l\lib\site-packages\tensorflow\python\eager\def_function.py", line 441, in wrapped_fn
      return weak_wrapped_fn().__wrapped__(*args, **kwds)
    File "C:\Users\goofy\d2l\lib\site-packages\tensorflow\python\eager\function.py", line 3299, in bound_method_wrapper
      return wrapped_fn(*args, **kwargs)
    File "C:\Users\goofy\d2l\lib\site-packages\tensorflow\python\framework\func_graph.py", line 968, in wrapper
      raise e.ag_error_metadata.to_exception(e)
  TypeError: in user code:
  
  
      TypeError: tf__call() missing 1 required positional argument: 'training'
  
  ```
  
  I have handled the unassigned training parameter for now as shown below 
  
  ```
  @tf.function
      def call(self, inputs, training= None):
          if training is None:
              training = tf.keras.backend.learning_phase()
          if training:
              axes = list(range(len(inputs.shape) - 1))
              batch_mean = tf.reduce_mean(inputs, axes, keepdims=True)
  ```
  
  Any other suggestions would be great.
  
  And the D2L code needs a change as the TensorFlow lenet with BN is still spitting out the above error.
  