class_docstr: Applies learnable exponential moving average, as required by learnable PCEN layer
  
  Arguments
  ---------
  input_size : int
      The expected size of the input.
  coeff_init: float
      Initial smoothing coefficient value
  per_channel: bool
      Controls whether every smoothing coefficients are learned
      independently for every input channel
  trainable: bool
      whether to learn the PCEN parameters or use fixed
  skip_transpose : bool
      If False, uses batch x time x channel convention of speechbrain.
      If True, uses batch x channel x time convention.
  
  Example
  -------
  >>> inp_tensor = torch.rand([10, 50, 40])
  >>> pcen = ExponentialMovingAverage(40)
  >>> out_tensor = pcen(inp_tensor)
  >>> out_tensor.shape
  torch.Size([10, 50, 40])
class_docstr_tok: ["Applies","learnable","exponential","moving","average",",","as","required","by","learnable","PCEN","layer","Arguments","--","--","--","--","-","input_size",":","int","The","expected","size","of","the","input",".","coeff_init",":","float","Initial","smoothing","coefficient","value","per_channel",":","bool","Controls","whether","every","smoothing","coefficients","are","learned","independently","for","every","input","channel","trainable",":","bool","whether","to","learn","the","PCEN","parameters","or","use","fixed","skip_transpose",":","bool","If","False",",","uses","batch","x","time","x","channel","convention","of","speechbrain",".","If","True",",","uses","batch","x","channel","x","time","convention",".","Example","--","--","--","-",">",">",">","inp_tensor","=","torch.rand","(","[","10",",","50",",","40","]",")",">",">",">","pcen","=","ExponentialMovingAverage","(","40",")",">",">",">","out_tensor","=","pcen","(","inp_tensor",")",">",">",">","out_tensor.shape","torch.Size","(","[","10",",","50",",","40","]",")"]
docstr: Returns the normalized input tensor.
  
  Arguments
   ---------
   x : torch.Tensor (batch, time, channels)
       input to normalize.
   
docstr_tok: ["Returns","the","normalized","input","tensor",".","Arguments","--","--","--","--","-","x",":","torch.Tensor","(","batch",",","time",",","channels",")","input","to","normalize","."]
code: def forward(self, x):
      """Returns the normalized input tensor.
  
      Arguments
       ---------
       x : torch.Tensor (batch, time, channels)
           input to normalize.
      """
      if not self.skip_transpose:
          x = x.transpose(1, -1)
      w = torch.clamp(self._weights, min=0.0, max=1.0)
      initial_state = x[:, :, 0]
  
      def scan(init_state, x, w):
          """Loops and accumulates."""
          x = x.permute(2, 0, 1)
          acc = init_state
          results = []
          for ix in range(x.shape[0]):
              acc = (w * x[ix]) + ((1.0 - w) * acc)
              results.append(acc.unsqueeze(0))
          results = torch.cat(results, dim=0)
          results = results.permute(1, 2, 0)
          return results
  
      output = scan(initial_state, x, w)
      if not self.skip_transpose:
          output = output.transpose(1, -1)
      return output
  
imports: import torch
  import torch.nn
label_desc: Use image node_id 2 for calling the ExponentialMovingAverage obj's underlying member method code with example usage: obj.forward(x) and returns: output, results