parameters: (
      inputs,
      num_outputs,
      kernel_size,
      depth_multiplier,
      stride=1,
      padding='SAME',
      rate=1,
      activation_fn=nn.relu,
      normalizer_fn=None,
      normalizer_params=None,
      weights_initializer=initializers.xavier_initializer(),
      weights_regularizer=None,
      biases_initializer=init_ops.zeros_initializer(),
      biases_regularizer=None,
      reuse=None,
      variables_collections=None,
      outputs_collections=None,
      trainable=True,
      scope=None)
docstring: Adds a depth-separable 2D convolution with optional batch_norm layer.
  
    This op first performs a depthwise convolution that acts separately on
    channels, creating a variable called `depthwise_weights`. If `num_outputs`
    is not None, it adds a pointwise convolution that mixes channels, creating a
    variable called `pointwise_weights`. Then, if `normalizer_fn` is None,
    it adds bias to the result, creating a variable called 'biases', otherwise,
    the `normalizer_fn` is applied. It finally applies an activation function
    to produce the end result.
  
    Args:
      inputs: A tensor of size [batch_size, height, width, channels].
      num_outputs: The number of pointwise convolution output filters. If is
        None, then we skip the pointwise convolution stage.
      kernel_size: A list of length 2: [kernel_height, kernel_width] of
        of the filters. Can be an int if both values are the same.
      depth_multiplier: The number of depthwise convolution output channels for
        each input channel. The total number of depthwise convolution output
        channels will be equal to `num_filters_in * depth_multiplier`.
      stride: A list of length 2: [stride_height, stride_width], specifying the
        depthwise convolution stride. Can be an int if both strides are the same.
      padding: One of 'VALID' or 'SAME'.
      rate: A list of length 2: [rate_height, rate_width], specifying the dilation
        rates for atrous convolution. Can be an int if both rates are the same.
        If any value is larger than one, then both stride values need to be one.
      activation_fn: Activation function. The default value is a ReLU function.
        Explicitly set it to None to skip it and maintain a linear activation.
      normalizer_fn: Normalization function to use instead of `biases`. If
        `normalizer_fn` is provided then `biases_initializer` and
        `biases_regularizer` are ignored and `biases` are not created nor added.
        default set to None for no normalizer function
      normalizer_params: Normalization function parameters.
      weights_initializer: An initializer for the weights.
      weights_regularizer: Optional regularizer for the weights.
      biases_initializer: An initializer for the biases. If None skip biases.
      biases_regularizer: Optional regularizer for the biases.
      reuse: Whether or not the layer and its variables should be reused. To be
        able to reuse the layer scope must be given.
      variables_collections: Optional list of collections for all the variables or
        a dictionary containing a different list of collection per variable.
      outputs_collections: Collection to add the outputs.
      trainable: Whether or not the variables should be trainable or not.
      scope: Optional scope for variable_scope.
  
    Returns:
      A `Tensor` representing the output of the operation.
docstring_summary: Adds a depth-separable 2D convolution with optional batch_norm layer.
docstring_tokens: Adds a depth - separable 2D convolution with optional batch_norm layer .
function: def separable_convolution2d(
      inputs,
      num_outputs,
      kernel_size,
      depth_multiplier,
      stride=1,
      padding='SAME',
      rate=1,
      activation_fn=nn.relu,
      normalizer_fn=None,
      normalizer_params=None,
      weights_initializer=initializers.xavier_initializer(),
      weights_regularizer=None,
      biases_initializer=init_ops.zeros_initializer(),
      biases_regularizer=None,
      reuse=None,
      variables_collections=None,
      outputs_collections=None,
      trainable=True,
      scope=None):
    """Adds a depth-separable 2D convolution with optional batch_norm layer.
  
    This op first performs a depthwise convolution that acts separately on
    channels, creating a variable called `depthwise_weights`. If `num_outputs`
    is not None, it adds a pointwise convolution that mixes channels, creating a
    variable called `pointwise_weights`. Then, if `normalizer_fn` is None,
    it adds bias to the result, creating a variable called 'biases', otherwise,
    the `normalizer_fn` is applied. It finally applies an activation function
    to produce the end result.
  
    Args:
      inputs: A tensor of size [batch_size, height, width, channels].
      num_outputs: The number of pointwise convolution output filters. If is
        None, then we skip the pointwise convolution stage.
      kernel_size: A list of length 2: [kernel_height, kernel_width] of
        of the filters. Can be an int if both values are the same.
      depth_multiplier: The number of depthwise convolution output channels for
        each input channel. The total number of depthwise convolution output
        channels will be equal to `num_filters_in * depth_multiplier`.
      stride: A list of length 2: [stride_height, stride_width], specifying the
        depthwise convolution stride. Can be an int if both strides are the same.
      padding: One of 'VALID' or 'SAME'.
      rate: A list of length 2: [rate_height, rate_width], specifying the dilation
        rates for atrous convolution. Can be an int if both rates are the same.
        If any value is larger than one, then both stride values need to be one.
      activation_fn: Activation function. The default value is a ReLU function.
        Explicitly set it to None to skip it and maintain a linear activation.
      normalizer_fn: Normalization function to use instead of `biases`. If
        `normalizer_fn` is provided then `biases_initializer` and
        `biases_regularizer` are ignored and `biases` are not created nor added.
        default set to None for no normalizer function
      normalizer_params: Normalization function parameters.
      weights_initializer: An initializer for the weights.
      weights_regularizer: Optional regularizer for the weights.
      biases_initializer: An initializer for the biases. If None skip biases.
      biases_regularizer: Optional regularizer for the biases.
      reuse: Whether or not the layer and its variables should be reused. To be
        able to reuse the layer scope must be given.
      variables_collections: Optional list of collections for all the variables or
        a dictionary containing a different list of collection per variable.
      outputs_collections: Collection to add the outputs.
      trainable: Whether or not the variables should be trainable or not.
      scope: Optional scope for variable_scope.
  
    Returns:
      A `Tensor` representing the output of the operation.
    """
    layer_variable_getter = _build_variable_getter(
        {'bias': 'biases',
         'depthwise_kernel': 'depthwise_weights',
         'pointwise_kernel': 'pointwise_weights'})
  
    with variable_scope.variable_scope(
        scope, 'SeparableConv2d', [inputs], reuse=reuse,
        custom_getter=layer_variable_getter) as sc:
      inputs = ops.convert_to_tensor(inputs)
  
      if num_outputs is not None:
        # Apply separable conv using the SeparableConvolution2D layer.
        layer = convolutional_layers.SeparableConvolution2D(
            filters=num_outputs,
            kernel_size=kernel_size,
            strides=stride,
            padding=padding,
            data_format='channels_last',
            dilation_rate=utils.two_element_tuple(rate),
            activation=None,
            depth_multiplier=depth_multiplier,
            use_bias=not normalizer_fn and biases_initializer,
            depthwise_initializer=weights_initializer,
            pointwise_initializer=weights_initializer,
            bias_initializer=biases_initializer,
            depthwise_regularizer=weights_regularizer,
            pointwise_regularizer=weights_regularizer,
            bias_regularizer=biases_regularizer,
            activity_regularizer=None,
            trainable=trainable,
            name=sc.name,
            dtype=inputs.dtype.base_dtype,
            _scope=sc,
            _reuse=reuse)
        outputs = layer.apply(inputs)
  
        # Add variables to collections.
        _add_variable_to_collections(layer.depthwise_kernel,
                                     variables_collections, 'weights')
        _add_variable_to_collections(layer.pointwise_kernel,
                                     variables_collections, 'weights')
        if layer.bias:
          _add_variable_to_collections(layer.bias,
                                       variables_collections, 'biases')
  
        if normalizer_fn is not None:
          normalizer_params = normalizer_params or {}
          outputs = normalizer_fn(outputs, **normalizer_params)
      else:
        # Actually apply depthwise conv instead of separable conv.
        dtype = inputs.dtype.base_dtype
        kernel_h, kernel_w = utils.two_element_tuple(kernel_size)
        stride_h, stride_w = utils.two_element_tuple(stride)
        num_filters_in = utils.last_dimension(inputs.get_shape(), min_rank=4)
        weights_collections = utils.get_variable_collections(
            variables_collections, 'weights')
  
        depthwise_shape = [kernel_h, kernel_w,
                           num_filters_in, depth_multiplier]
        depthwise_weights = variables.model_variable(
            'depthwise_weights',
            shape=depthwise_shape,
            dtype=dtype,
            initializer=weights_initializer,
            regularizer=weights_regularizer,
            trainable=trainable,
            collections=weights_collections)
        strides = [1, stride_h, stride_w, 1]
  
        outputs = nn.depthwise_conv2d(inputs, depthwise_weights, strides, padding,
                                      rate=utils.two_element_tuple(rate))
        num_outputs = depth_multiplier * num_filters_in
  
        if normalizer_fn is not None:
          normalizer_params = normalizer_params or {}
          outputs = normalizer_fn(outputs, **normalizer_params)
        else:
          if biases_initializer is not None:
            biases_collections = utils.get_variable_collections(
                variables_collections, 'biases')
            biases = variables.model_variable('biases',
                                              shape=[num_outputs,],
                                              dtype=dtype,
                                              initializer=biases_initializer,
                                              regularizer=biases_regularizer,
                                              trainable=trainable,
                                              collections=biases_collections)
            outputs = nn.bias_add(outputs, biases)
  
      if activation_fn is not None:
        outputs = activation_fn(outputs)
      return utils.collect_named_outputs(outputs_collections,
                                         sc.original_name_scope, outputs)
function_tokens: def separable_convolution2d ( inputs , num_outputs , kernel_size , depth_multiplier , stride = 1 , padding = 'SAME' , rate = 1 , activation_fn = nn . relu , normalizer_fn = None , normalizer_params = None , weights_initializer = initializers . xavier_initializer ( ) , weights_regularizer = None , biases_initializer = init_ops . zeros_initializer ( ) , biases_regularizer = None , reuse = None , variables_collections = None , outputs_collections = None , trainable = True , scope = None ) : layer_variable_getter = _build_variable_getter ( { 'bias' : 'biases' , 'depthwise_kernel' : 'depthwise_weights' , 'pointwise_kernel' : 'pointwise_weights' } ) with variable_scope . variable_scope ( scope , 'SeparableConv2d' , [ inputs ] , reuse = reuse , custom_getter = layer_variable_getter ) as sc : inputs = ops . convert_to_tensor ( inputs ) if num_outputs is not None : # Apply separable conv using the SeparableConvolution2D layer. layer = convolutional_layers . SeparableConvolution2D ( filters = num_outputs , kernel_size = kernel_size , strides = stride , padding = padding , data_format = 'channels_last' , dilation_rate = utils . two_element_tuple ( rate ) , activation = None , depth_multiplier = depth_multiplier , use_bias = not normalizer_fn and biases_initializer , depthwise_initializer = weights_initializer , pointwise_initializer = weights_initializer , bias_initializer = biases_initializer , depthwise_regularizer = weights_regularizer , pointwise_regularizer = weights_regularizer , bias_regularizer = biases_regularizer , activity_regularizer = None , trainable = trainable , name = sc . name , dtype = inputs . dtype . base_dtype , _scope = sc , _reuse = reuse ) outputs = layer . apply ( inputs ) # Add variables to collections. _add_variable_to_collections ( layer . depthwise_kernel , variables_collections , 'weights' ) _add_variable_to_collections ( layer . pointwise_kernel , variables_collections , 'weights' ) if layer . bias : _add_variable_to_collections ( layer . bias , variables_collections , 'biases' ) if normalizer_fn is not None : normalizer_params = normalizer_params or { } outputs = normalizer_fn ( outputs , * * normalizer_params ) else : # Actually apply depthwise conv instead of separable conv. dtype = inputs . dtype . base_dtype kernel_h , kernel_w = utils . two_element_tuple ( kernel_size ) stride_h , stride_w = utils . two_element_tuple ( stride ) num_filters_in = utils . last_dimension ( inputs . get_shape ( ) , min_rank = 4 ) weights_collections = utils . get_variable_collections ( variables_collections , 'weights' ) depthwise_shape = [ kernel_h , kernel_w , num_filters_in , depth_multiplier ] depthwise_weights = variables . model_variable ( 'depthwise_weights' , shape = depthwise_shape , dtype = dtype , initializer = weights_initializer , regularizer = weights_regularizer , trainable = trainable , collections = weights_collections ) strides = [ 1 , stride_h , stride_w , 1 ] outputs = nn . depthwise_conv2d ( inputs , depthwise_weights , strides , padding , rate = utils . two_element_tuple ( rate ) ) num_outputs = depth_multiplier * num_filters_in if normalizer_fn is not None : normalizer_params = normalizer_params or { } outputs = normalizer_fn ( outputs , * * normalizer_params ) else : if biases_initializer is not None : biases_collections = utils . get_variable_collections ( variables_collections , 'biases' ) biases = variables . model_variable ( 'biases' , shape = [ num_outputs , ] , dtype = dtype , initializer = biases_initializer , regularizer = biases_regularizer , trainable = trainable , collections = biases_collections ) outputs = nn . bias_add ( outputs , biases ) if activation_fn is not None : outputs = activation_fn ( outputs ) return utils . collect_named_outputs ( outputs_collections , sc . original_name_scope , outputs )