class_docstr: Implement the thermometer encoding defence approach.
  
  | Paper link: https://openreview.net/forum?id=S18Su--CW
  
  | Please keep in mind the limitations of defences. For more information on the limitations of this defence,
      see https://arxiv.org/abs/1802.00420 . For details on how to evaluate classifier security in general, see
      https://arxiv.org/abs/1902.06705
docstr: Provide an estimate of the gradients of the defence for the backward pass. For thermometer encoding,
  the gradient estimate is the one used in https://arxiv.org/abs/1802.00420, where the thermometer encoding
  is replaced with a differentiable approximation:
  `g(x_{i,j,c})_k = min(max(x_{i,j,c} - k / self.num_space, 0), 1)`.
  
  :param x: Input data for which the gradient is estimated. First dimension is the batch size.
  :param grad: Gradient value so far.
  :return: The gradient (estimate) of the defence.
docstr_tok: ["Provide","an","estimate","of","the","gradients","of","the","defence","for","the","backward","pass",".","For","thermometer","encoding",",","the","gradient","estimate","is","the","one","used","in","https",":","\/\/arxiv.org\/abs\/1802.00420",",","where","the","thermometer","encoding","is","replaced","with","a","differentiable","approximation",":","`","g","(","x_","{","i",",","j",",","c","}",")","_k","=","min","(","max","(","x_","{","i",",","j",",","c","}","-","k","\/","self.num_space",",","0",")",",","1",")","`",".",":","param","x",":","Input","data","for","which","the","gradient","is","estimated",".","First","dimension","is","the","batch","size",".",":","param","grad",":","Gradient","value","so","far",".",":","return",":","The","gradient","(","estimate",")","of","the","defence","."]
code: def estimate_gradient(
      self, x: np.ndarray, grad: np.ndarray
  ) -> np.ndarray:
      """
      Provide an estimate of the gradients of the defence for the backward pass. For thermometer encoding,
      the gradient estimate is the one used in https://arxiv.org/abs/1802.00420, where the thermometer encoding
      is replaced with a differentiable approximation:
      `g(x_{i,j,c})_k = min(max(x_{i,j,c} - k / self.num_space, 0), 1)`.
  
      :param x: Input data for which the gradient is estimated. First dimension is the batch size.
      :param grad: Gradient value so far.
      :return: The gradient (estimate) of the defence.
      """
      if self.channels_first:
          x = np.transpose(
              x, (0,) + tuple(range(2, len(x.shape))) + (1,)
          )
          grad = np.transpose(
              grad, (0,) + tuple(range(2, len(x.shape))) + (1,)
          )
  
      thermometer_grad = np.zeros(
          x.shape[:-1] + (x.shape[-1] * self.num_space,)
      )
      mask = np.array(
          [x > k / self.num_space for k in range(self.num_space)]
      )
      mask = np.moveaxis(mask, 0, -1)
      mask = mask.reshape(thermometer_grad.shape)
      thermometer_grad[mask] = 1
  
      grad = grad * thermometer_grad
      grad = np.reshape(
          grad,
          grad.shape[:-1]
          + (grad.shape[-1] // self.num_space, self.num_space),
      )
      grad = np.sum(grad, -1)
  
      if self.channels_first:
          x = np.transpose(
              x,
              (0,)
              + (len(x.shape) - 1,)
              + tuple(range(1, len(x.shape) - 1)),
          )
          grad = np.transpose(
              grad,
              (0,)
              + (len(x.shape) - 1,)
              + tuple(range(1, len(x.shape) - 1)),
          )
  
      return grad / (self.clip_values[1] - self.clip_values[0])
  
file_path: adversarial-robustness-toolbox/art/defences/preprocessor/thermometer_encoding.py
imports: from __future__ import absolute_import, division, print_function, unicode_literals
  import logging
  from typing import Optional, Tuple, TYPE_CHECKING
  import numpy
  from art.config import ART_NUMPY_DTYPE
  from art.defences.preprocessor.preprocessor import Preprocessor
  from art.utils import to_categorical
label_desc: Use image node_id 4 for calling the ThermometerEncoding obj's underlying member method code with example usage: obj.estimate_gradient(x, grad) and returns: unknown