class_docstr: EM algorithm used to quantize the columns of W to minimize
  
                       ||W - W_hat||^2
  
  Args:
      - W: weight matrix of size (in_features x out_features)
      - n_iter: number of k-means iterations
      - n_centroids: number of centroids (size of codebook)
      - eps: for cluster reassignment when an empty cluster is found
      - max_tentatives for cluster reassignment when an empty cluster is found
      - verbose: print error after each iteration
  
  Remarks:
      - If one cluster is empty, the most populated cluster is split into
        two clusters
      - All the relevant dimensions are specified in the code
code: def __init__(
      self,
      W,
      n_centroids=256,
      n_iter=20,
      eps=1e-6,
      max_tentatives=30,
      verbose=True,
  ):
      self.W = W
      self.n_centroids = n_centroids
      self.n_iter = n_iter
      self.eps = eps
      self.max_tentatives = max_tentatives
      self.verbose = verbose
      self.centroids = torch.Tensor()
      self.assignments = torch.Tensor()
      self.objective = []
  
file_path: fairseq/fairseq/modules/quantization/pq/em.py
imports: import logging
  import os
  import random
  from collections import Counter
  import torch
label_desc: Use image node_id 1 to create a new EM object  with example: obj = EM(W, n_centroids, n_iter, eps, max_tentatives, verbose)