class_docstr: Inverse synthesis model (ddsp-inv).
  
  EXPERIMENTAL
  
  Builds a hierarchical model of audio:
  Audio -> Sinusoid -> Harmonic -> Sinusoid -> Audio.
  
  Unlike other models, the processor group is defined in the constructor, as
  there are many synthesizer specific regularizers and self-supervised losses.
class_docstr_tok: ["Inverse","synthesis","model","(","ddsp-inv",")",".","EXPERIMENTAL","Builds","a","hierarchical","model","of","audio",":","Audio","-",">","Sinusoid","-",">","Harmonic","-",">","Sinusoid","-",">","Audio",".","Unlike","other","models",",","the","processor","group","is","defined","in","the","constructor",",","as","there","are","many","synthesizer","specific","regularizers","and","self-supervised","losses","."]
docstr: Compute losses from outputs and append to self._losses_dict.
docstr_tok: ["Compute","losses","from","outputs","and","append","to","self._losses_dict","."]
code: def append_losses(self, outputs, self_supervised_features=None):
      """Compute losses from outputs and append to self._losses_dict."""
      # Aliases.
      o = outputs
      f = self_supervised_features
  
      # Unsupervised losses.
      if f is None:
          # Sinusoidal autoencoder loss.
          for loss_obj in self.audio_loss_objs:
              name = "sin_{}".format(loss_obj.name)
              self._losses_dict[name] = loss_obj(
                  o["audio"], o["sin_audio"]
              )
  
          if self.harmonic_encoder is not None:
              # Add prior regularization on harmonic distribution.
              self._update_losses_dict(
                  self.harmonic_distribution_prior, o["harm_dist"]
              )
  
              # Harmonic autoencoder loss.
              for loss_obj in self.audio_loss_objs:
                  name = "harm_{}".format(loss_obj.name)
                  self._losses_dict[name] = loss_obj(
                      o["audio"], o["harm_audio"]
                  )
  
              # Sinusoidal<->Harmonic consistency loss.
              if self.sinusoidal_consistency_losses:
                  sin_amps = o["sin_amps"]
                  sin_freqs = o["sin_freqs"]
                  if self.stop_gradient:
                      # Don't propagate harmonic errors to sinusoidal predictions.
                      sin_amps = tf.stop_gradient(sin_amps)
                      sin_freqs = tf.stop_gradient(sin_freqs)
                  self._update_losses_dict(
                      self.sinusoidal_consistency_losses,
                      sin_amps,
                      sin_freqs,
                      o["harm_amps"],
                      o["harm_freqs"],
                  )
  
          # Two-way mismatch loss between sinusoids and harmonics.
          if self.twm_loss is not None:
              f0_c = (
                  o["sin_freqs"]
                  if self.harmonic_encoder is None
                  else o["f0_hz"]
              )
              self._update_losses_dict(
                  self.twm_loss, f0_c, o["sin_freqs"], o["sin_amps"]
              )
  
      # Self-supervised Losses.
      else:
          # Sinusoidal self-supervision.
          if self.sinusoidal_consistency_losses:
              for loss_obj in self.sinusoidal_consistency_losses:
                  name = "ss_" + loss_obj.name
                  self._losses_dict[name] = loss_obj(
                      o["sin_amps"],
                      o["sin_freqs"],
                      f["sin_amps"],
                      f["sin_freqs"],
                  )
  
          # Filtered noise self-supervision.
          fncl = self.filtered_noise_consistency_loss
          if fncl is not None:
              name = "ss_" + fncl.name
              self._losses_dict[name] = fncl(
                  o["noise_magnitudes"], f["noise_magnitudes"]
              )
  
          # Harmonic self-supervision.
          if self.harmonic_consistency_losses:
              for loss_obj in self.harmonic_consistency_losses:
                  if isinstance(
                      loss_obj, ddsp.losses.HarmonicConsistencyLoss
                  ):
                      # L1 loss of harmonic synth controls.
                      losses = loss_obj(
                          o["harm_amp"],
                          f["harm_amp"],
                          o["harm_dist"],
                          f["harm_dist"],
                          o["f0_hz"],
                          f["f0_hz"],
                      )
                      losses = {"ss_" + k: v for k, v in losses.items()}
                      self._losses_dict.update(losses)
                  else:
                      # Same consistency loss as sinusoidal models.
                      name = "ss_harm_" + loss_obj.name
                      self._losses_dict[name] = loss_obj(
                          o["harm_amp"],
                          o["f0_hz"],
                          f["harm_amp"],
                          f["f0_hz"],
                      )
  
file_path: ddsp/ddsp/training/models/inverse_synthesis.py
imports: import functools
  import ddsp
  from ddsp.training.models.model import Model
  import tensorflow
label_desc: Use image node_id 6 for calling the InverseSynthesis obj's underlying member method code with example usage: obj.append_losses(outputs, _supervised_features) without return types