class_docstr: Field-aware Factorization Machine base class.
class_docstr_tok: ["Field-aware","Factorization","Machine","base","class","."]
code: def _update_latents(self, x, g_loss):
      # For notational convenience
      v, l1, l2 = self.latents, self.l1_latent, self.l2_latent
      sign, field = utils.math.sign, self._field
  
      # Calculate each latent factor gradient before updating any
      latent_gradient = collections.defaultdict(
          lambda: collections.defaultdict(
              lambda: collections.defaultdict(float)
          )
      )
  
      for j1, j2 in itertools.combinations(x.keys(), 2):
          xj1_xj2 = x[j1] * x[j2]
          field_j1, field_j2 = field(j1), field(j2)
  
          for f in range(self.n_factors):
              latent_gradient[j1][field_j2][f] += (
                  xj1_xj2 * v[j2][field_j1][f]
              )
              latent_gradient[j2][field_j1][f] += (
                  xj1_xj2 * v[j1][field_j2][f]
              )
  
      # Finally update the latent weights
      for j in x.keys():
          for field in latent_gradient[j].keys():
              self.latents[j][field] = self.latent_optimizer.step(
                  w=v[j][field],
                  g={
                      f: g_loss * latent_gradient[j][field][f]
                      + l1 * sign(v[j][field][f])
                      + 2.0 * l2 * v[j][field][f]
                      for f in range(self.n_factors)
                  },
              )
  
imports: from __future__ import annotations
  import collections
  import functools
  import itertools
  import numpy
  from river import base, optim, utils
  from .base import BaseFM
label_desc: Use image node_id 8 for calling the FFM obj's underlying member method code with example usage: obj._update_latents(x, g_loss) without return types