class_docstr: AlphaBeta advanced as proposed by Alexander Binder.
class_docstr_tok: ["AlphaBeta","advanced","as","proposed","by","Alexander","Binder","."]
code: def apply(
      self,
      Xs: list[Tensor],
      _Ys: list[Tensor],
      Rs: list[Tensor],
      _reverse_state: dict,
  ):
      # this method is correct, but wasteful
      times_alpha0 = klayers.Lambda(lambda x: x * self._alpha[0])
      # times_alpha1 = klayers.Lambda(lambda x: x * self._alpha[1]) # unused
      times_beta0 = klayers.Lambda(lambda x: x * self._beta[0])
      times_beta1 = klayers.Lambda(lambda x: x * self._beta[1])
      keep_positives = klayers.Lambda(
          lambda x: x
          * kbackend.cast(kbackend.greater(x, 0), kbackend.floatx())
      )
      keep_negatives = klayers.Lambda(
          lambda x: x
          * kbackend.cast(kbackend.less(x, 0), kbackend.floatx())
      )
  
      def fn_tmp(layer: Layer, Xs: OptionalList[Tensor]):
          Zs = ibackend.apply(layer, Xs)
          # Divide incoming relevance by the activations.
          tmp = [ibackend.safe_divide(a, b) for a, b in zip(Rs, Zs)]
          # Propagate the relevance to the input neurons
          # using the gradient
          grads = ibackend.gradients(Xs, Zs, tmp)
          # Re-weight relevance with the input values.
          return [klayers.Multiply()([a, b]) for a, b in zip(Xs, grads)]
  
      # Distinguish postive and negative inputs.
      Xs_pos = ibackend.apply(keep_positives, Xs)
      Xs_neg = ibackend.apply(keep_negatives, Xs)
  
      # xpos*wpos
      r_pp = fn_tmp(self._layer_wo_act_positive, Xs_pos)
      # xneg*wneg
      r_nn = fn_tmp(self._layer_wo_act_negative, Xs_neg)
      # a0 * r_pp + a1 * r_nn
      r_pos = [
          klayers.Add()([times_alpha0(pp), times_beta1(nn)])
          for pp, nn in zip(r_pp, r_nn)
      ]
  
      # xpos*wneg
      r_pn = fn_tmp(self._layer_wo_act_negative, Xs_pos)
      # xneg*wpos
      r_np = fn_tmp(self._layer_wo_act_positive, Xs_neg)
      # b0 * r_pn + b1 * r_np
      r_neg = [
          klayers.Add()([times_beta0(pn), times_beta1(np)])
          for pn, np in zip(r_pn, r_np)
      ]
  
      return [klayers.Subtract()([a, b]) for a, b in zip(r_pos, r_neg)]
  
imports: from __future__ import annotations
  import numpy
  import tensorflow.keras.backend
  import tensorflow.keras.layers
  import innvestigate.analyzer.relevance_based.utils
  import innvestigate.backend
  import innvestigate.backend.graph
  import innvestigate.layers
  from innvestigate.backend.types import Layer, OptionalList, Tensor
label_desc: Use image node_id 2 for calling the AlphaBetaXRule obj's underlying member method code with example usage: obj.apply(Xs, _Ys, Rs, _reverse_state) and returns: unknown, unknown