class_docstr: A smoothed classifier g 
docstr: Sample the base classifier's prediction under noisy corruptions of
  the input x.
  
  :param x: the input [width x height x channel]
  :param num: number of samples to collect
  :param batch_size:
  :return: an ndarray[int] of length num_classes containing the per-class
  counts
code: def _sample_noise(
      self, x: np.ndarray, num: int, batch_size: int
  ) -> np.ndarray:
      """Sample the base classifier's prediction under noisy corruptions of
      the input x.
  
      :param x: the input [width x height x channel]
      :param num: number of samples to collect
      :param batch_size:
      :return: an ndarray[int] of length num_classes containing the per-class
      counts
      """
      counts = np.zeros(self.num_classes, dtype=int)
      for _ in range(ceil(num / batch_size)):
          this_batch_size = min(batch_size, num)
          num -= this_batch_size
  
          batch = np.expand_dims(x, 0)
          batch = np.repeat(batch, this_batch_size, axis=0)
          noise = np.random.randn(*batch.shape) * self.sigma
          predictions = self.base_classifier.predict(
              batch + noise
          ).argmax(1)
          counts += self._count_arr(predictions, self.num_classes)
      return counts
  
file_path: neural-structured-learning/research/third_party/denoised_smoothing/scripts/certification_utils.py
imports: from math import ceil
  from statsmodels.stats.proportion import proportion_confint
  from scipy.stats import norm, binom_test
  import tensorflow
  import numpy
label_desc: Use image node_id 4 for calling the Smooth obj's underlying member method code with example usage: obj._sample_noise(x, num, batch_size) and returns: counts