class_docstr: Pure Pytorch implementation of block ablation.
docstr: Forward pass though the ablator. We insert a new channel to keep track of the ablation location.
  
  :param x: Input data
  :param column_pos: The start position of the albation
  :return: The albated input with an extra channel indicating the location of the ablation if running in
docstr_tok: ["Forward","pass","though","the","ablator",".","We","insert","a","new","channel","to","keep","track","of","the","ablation","location",".",":","param","x",":","Input","data",":","param","column_pos",":","The","start","position","of","the","albation",":","return",":","The","albated","input","with","an","extra","channel","indicating","the","location","of","the","ablation","if","running","in"]
code: def forward(
      self,
      x: Union[torch.Tensor, np.ndarray],
      column_pos: Optional[int] = None,
      row_pos: Optional[int] = None,
  ) -> torch.Tensor:
      """
      Forward pass though the ablator. We insert a new channel to keep track of the ablation location.
  
      :param x: Input data
      :param column_pos: The start position of the albation
      :return: The albated input with an extra channel indicating the location of the ablation if running in
      """
      if (
          self.original_shape is not None
          and x.shape[1] != self.original_shape[0]
          and self.algorithm == "salman2021"
      ):
          raise ValueError(
              f"Ablator expected {self.original_shape[0]} input channels. Recived shape of {x.shape[1]}"
          )
  
      if column_pos is None:
          column_pos = random.randint(0, x.shape[3])
  
      if row_pos is None:
          row_pos = random.randint(0, x.shape[2])
  
      if isinstance(x, np.ndarray):
          x = torch.from_numpy(x).to(self.device)
  
      if self.add_ablation_mask:
          ones = torch.torch.ones_like(x[:, 0:1, :, :]).to(self.device)
          x = torch.cat([x, ones], dim=1)
  
      if self.additional_channels:
          x = torch.cat([x, 1.0 - x], dim=1)
  
      if (
          self.original_shape is not None
          and x.shape[1] != self.original_shape[0]
          and self.additional_channels
      ):
          raise ValueError(
              f"Ablator expected {self.original_shape[0]} input channels. Recived shape of {x.shape[1]}"
          )
  
      ablated_x = self.ablate(x, column_pos=column_pos, row_pos=row_pos)
  
      if self.to_reshape:
          ablated_x = self.upsample(ablated_x)
      return ablated_x
  
imports: from typing import Optional, Union, Tuple
  import random
  import numpy
  import torch
  from art.estimators.certification.derandomized_smoothing.ablators.ablate import BaseAblator
label_desc: Use image node_id 3 for calling the BlockAblatorPyTorch obj's underlying member method code with example usage: obj.forward(x, column_pos, row_pos) and returns: ablated_x