(embeddings,
                         responsibilities,
                         damping=1e-7,
                         full_covariance=False)
Fits a unimodal Gaussian distribution `embeddings`.

  Args:
    embeddings: A [batch_size, embedding_dim] tf.Tensor of embeddings.
    responsibilities: The per-component responsibilities.
    damping: The scale of the covariance damping coefficient.
    full_covariance: Whether to use a full or diagonal covariance.

  Returns:
    Parameter estimates for a Gaussian mixture model.
Fits a unimodal Gaussian distribution `embeddings`.
Fits a unimodal Gaussian distribution embeddings .
def fit_gaussian_mixture(embeddings,
                         responsibilities,
                         damping=1e-7,
                         full_covariance=False):
  """Fits a unimodal Gaussian distribution `embeddings`.

  Args:
    embeddings: A [batch_size, embedding_dim] tf.Tensor of embeddings.
    responsibilities: The per-component responsibilities.
    damping: The scale of the covariance damping coefficient.
    full_covariance: Whether to use a full or diagonal covariance.

  Returns:
    Parameter estimates for a Gaussian mixture model.
  """

  num, dim = tf.split(tf.shape(input=embeddings), num_or_size_splits=2)
  num, dim = tf.squeeze(num), tf.squeeze(dim)
  num_classes = responsibilities.shape[1]

  mixing_proportion = tf.einsum('jk->k', responsibilities)
  mixing_proportion /= tf.cast(num, dtype=tf.float32)
  mixing_logits = tf.math.log(mixing_proportion)

  sample_mean = tf.einsum('ij,ik->jk', responsibilities, embeddings)
  sample_mean /= tf.reduce_sum(
      input_tensor=responsibilities, axis=0)[:, tf.newaxis]
  centered_embeddings = (
      embeddings[:, tf.newaxis, :] - sample_mean[tf.newaxis, :, :])

  if full_covariance:
    sample_covariance = tf.einsum('ijk,ijl->ijkl', centered_embeddings,
                                  centered_embeddings)  # Outer product.
    sample_covariance += damping * tf.eye(dim)  # Positive definiteness.
    weighted_covariance = tf.einsum('ij,ijkl->jkl', responsibilities,
                                    sample_covariance)
    weighted_covariance /= tf.reduce_sum(
        input_tensor=responsibilities, axis=0)[:, tf.newaxis, tf.newaxis]

    return (
        _split_and_squeeze(sample_mean, num_splits=num_classes),
        _split_and_squeeze(weighted_covariance, num_splits=num_classes),
        [mixing_logits],
    )
  else:
    avg_x_squared = (
        tf.matmul(responsibilities, embeddings**2, transpose_a=True) /
        tf.reduce_sum(input_tensor=responsibilities, axis=0)[:, tf.newaxis])
    avg_means_squared = sample_mean**2
    avg_x_means = (
        sample_mean *
        tf.matmul(responsibilities, embeddings, transpose_a=True) /
        tf.reduce_sum(input_tensor=responsibilities, axis=0)[:, tf.newaxis])
    sample_variances = (
        avg_x_squared - 2 * avg_x_means + avg_means_squared +
        damping * tf.ones(dim))
    log_variances = tf.math.log(sample_variances)
    return (
        _split_and_squeeze(sample_mean, num_splits=num_classes),
        _split_and_squeeze(log_variances, num_splits=num_classes),
        [mixing_logits],
    )
def fit_gaussian_mixture ( embeddings , responsibilities , damping = 1e-7 , full_covariance = False ) : num , dim = tf . split ( tf . shape ( input = embeddings ) , num_or_size_splits = 2 ) num , dim = tf . squeeze ( num ) , tf . squeeze ( dim ) num_classes = responsibilities . shape [ 1 ] mixing_proportion = tf . einsum ( 'jk->k' , responsibilities ) mixing_proportion /= tf . cast ( num , dtype = tf . float32 ) mixing_logits = tf . math . log ( mixing_proportion ) sample_mean = tf . einsum ( 'ij,ik->jk' , responsibilities , embeddings ) sample_mean /= tf . reduce_sum ( input_tensor = responsibilities , axis = 0 ) [ : , tf . newaxis ] centered_embeddings = ( embeddings [ : , tf . newaxis , : ] - sample_mean [ tf . newaxis , : , : ] ) if full_covariance : sample_covariance = tf . einsum ( 'ijk,ijl->ijkl' , centered_embeddings , centered_embeddings ) # Outer product. sample_covariance += damping * tf . eye ( dim ) # Positive definiteness. weighted_covariance = tf . einsum ( 'ij,ijkl->jkl' , responsibilities , sample_covariance ) weighted_covariance /= tf . reduce_sum ( input_tensor = responsibilities , axis = 0 ) [ : , tf . newaxis , tf . newaxis ] return ( _split_and_squeeze ( sample_mean , num_splits = num_classes ) , _split_and_squeeze ( weighted_covariance , num_splits = num_classes ) , [ mixing_logits ] , ) else : avg_x_squared = ( tf . matmul ( responsibilities , embeddings ** 2 , transpose_a = True ) / tf . reduce_sum ( input_tensor = responsibilities , axis = 0 ) [ : , tf . newaxis ] ) avg_means_squared = sample_mean ** 2 avg_x_means = ( sample_mean * tf . matmul ( responsibilities , embeddings , transpose_a = True ) / tf . reduce_sum ( input_tensor = responsibilities , axis = 0 ) [ : , tf . newaxis ] ) sample_variances = ( avg_x_squared - 2 * avg_x_means + avg_means_squared + damping * tf . ones ( dim ) ) log_variances = tf . math . log ( sample_variances ) return ( _split_and_squeeze ( sample_mean , num_splits = num_classes ) , _split_and_squeeze ( log_variances , num_splits = num_classes ) , [ mixing_logits ] , )