code: def residual_group(
      x: tf.Tensor,
      n_filters: int,
      n_blocks: int,
      strides: Uninon[int, tuple[int, int]] = (2, 2),
      n: int = 2,
  ) -> tf.Tensor:
      """Construct a Residual Group
      x         : input into the group
      n_filters : number of filters for the group
      n_blocks  : number of residual blocks with identity link
      strides   : whether the projection block is a strided convolution
      n         : multiplier for the number of filters out
      """
      # Double the size of filters to fit the first Residual Group
      x = projection_block(x, n_filters, strides=strides, n=n)
  
      # Identity residual blocks
      for _ in range(n_blocks):
          x = identity_block(x, n_filters, n)
      return x
  
file_path: neural-structured-learning/research/third_party/denoised_smoothing/models/resnet20.py
imports: from typing import Union
  import tensorflow
  from tensorflow.keras import Model, Input
  from tensorflow.keras.layers import Conv2D, Dense, BatchNormalization, ReLU, Add, AveragePooling2D, GlobalAvgPool2D
  from tensorflow.keras.regularizers import l2
label_desc: Use image node_id 3 for calling a global function with example usage: residual_group(x, n_filters, n_blocks, strides, n) and returns: x