class_docstr: Adds TensorFlow specific functions.
docstr: Perform one training step over data in TensorFlow models.
  
  Returns
  -------
  (LP, LA) : tuple of (float, float)
      predictor loss and adversary loss.
docstr_tok: ["Perform","one","training","step","over","data","in","TensorFlow","models",".","Returns","--","--","--","-","(","LP",",","LA",")",":","tuple","of","(","float",",","float",")","predictor","loss","and","adversary","loss","."]
code: def train_step(self, X, Y, A):
      """
      Perform one training step over data in TensorFlow models.
  
      Returns
      -------
      (LP, LA) : tuple of (float, float)
          predictor loss and adversary loss.
      """
      with tensorflow.GradientTape(persistent=True) as tape:
          # training=True is only needed if there are layers with different
          # behavior during training versus inference (e.g. Dropout).
          Y_hat = self.predictor_model(X, training=True)
  
          LP = self.predictor_loss(Y, Y_hat)
  
          # For equalized odds
          if self.base.pass_y_:
              Y_hat = tensorflow.concat((Y_hat, Y), axis=1)
  
          A_hat = self.adversary_model(Y_hat)
  
          LA = self.adversary_loss(A, A_hat)
  
      dW_LP = tape.gradient(
          LP, self.predictor_model.trainable_variables
      )
      dU_LA = tape.gradient(
          LA, self.adversary_model.trainable_variables
      )
      dW_LA = tape.gradient(
          LA, self.predictor_model.trainable_variables
      )
  
      del tape  # Because persistent=True !
  
      for i in range(len(dW_LP)):
          # Normalize dW_LA
          unit_dW_LA = dW_LA[i] / (
              tensorflow.norm(dW_LA[i]) + finfo(float32).tiny
          )
          # Project
          proj = tensorflow.reduce_sum(
              tensorflow.multiply(dW_LP[i], unit_dW_LA)
          )
          # Calculate dW
          dW_LP[i] = (
              dW_LP[i]
              - (proj * unit_dW_LA)
              - (self.base.alpha * dW_LA[i])
          )
  
      self.predictor_optimizer.apply_gradients(
          zip(dW_LP, self.predictor_model.trainable_variables)
      )
      self.adversary_optimizer.apply_gradients(
          zip(dU_LA, self.adversary_model.trainable_variables)
      )
  
      return (LP.numpy().item(), LA.numpy().item())
  
file_path: fairlearn/fairlearn/adversarial/_tensorflow_engine.py
imports: from ._backend_engine import BackendEngine
  from numpy import finfo, float32
label_desc: Use image node_id 3 for calling the TensorflowEngine obj's underlying member method code with example usage: obj.train_step(X, Y, A) and returns: LP,  LA