code: def fit(
      self,
      X,
      shuffle=True,
      display_step=500,
      n_jobs=1,
      max_steps=None,
      verbose=0,
      **kwargs,
  ):
      with self.graph.as_default():
          # Verify data dimension
          validate_dim(X, max_dim=2, min_dim=2, var_name="X")
  
          # Get data size
          num_samples = get_num_sample(X)
  
          # Set batch size
          if "batch_size" in kwargs.keys():
              batch_size = kwargs["batch_size"]
          else:
              batch_size = num_samples
  
              # Build Tree Graph
          self._build_estimator(X)
  
          # Generate Data Tensors. Be aware that every fit with different
          # data will re-create a data tensor.
          if (
              self._train.get_params("X") != hex(id(X))
              or self._train.get_params("batch_size") != batch_size
              or not self._train.is_ready
          ):
              # TODO: raise Exception("Fitting different data not supported")
  
              X, _, cr = generate_data_tensor(
                  X,
                  X,
                  batch_size=batch_size,
                  shuffle=shuffle,
                  num_threads=8,
              )
              X, _, spec = data_ops.ParseDataTensorOrDict(X)
  
              self._train_op = tf.group(
                  self._train_op,
                  state_ops.assign_add(self.global_step, 1),
              )
              self._loss_op = self.avg_distance
              self._build_fit(X, X, batch_size)
  
              # Start QueueRunners
              tf.train.start_queue_runners(sess=self.session)
              if cr:
                  cr.launch_threads(self.session)
  
          gstep = self.global_step.eval(session=self.session)
  
          last_loss = []
          loss_val = None
          step = 0
  
          # Set step to -1 to exit training
          while True:
              # Monitor loss
              if loss_val:
                  last_loss.append(loss_val)
              if len(last_loss) > 10:
                  last_loss.pop(0)
  
              start_time = time.time()
              if (step) % display_step == 0:
                  _, loss_val, idx = self.session.run(
                      [self._train_op, self._loss_op, self._cluster_idx]
                  )
              else:
                  _, loss_val, idx = self.session.run(
                      [self._train_op, self._loss_op, self._cluster_idx]
                  )
              duration = time.time() - start_time
  
              if (step) % display_step == 0:
                  examples_per_sec = batch_size / duration
                  sec_per_batch = duration
                  if self.metric:
                      format_str = (
                          "%s: step %d, loss = %.2f, acc = %.2f, "
                          "(%.1f examples/sec; %.3f sec/batch)"
                      )
                      print(
                          format_str
                          % (
                              datetime.now(),
                              step + gstep,
                              loss_val,
                              examples_per_sec,
                              sec_per_batch,
                          )
                      )
                  else:
                      format_str = (
                          "%s: step %d, loss = %.2f, "
                          "(%.1f examples/sec; %.3f sec/batch)"
                      )
                      print(
                          format_str
                          % (
                              datetime.now(),
                              step + gstep,
                              loss_val,
                              examples_per_sec,
                              sec_per_batch,
                          )
                      )
  
              step += 1
  
              # Automatic stop after ten flat loss
              # TODO(aymeric): better stopping.
              if (
                  len(last_loss) == 10
                  and np.var(last_loss) <= 0.01
                  and not max_steps
              ):
                  break
  
              # Max Steps stop
              if max_steps:
                  if step == max_steps:
                      break
  
imports: from __future__ import division, print_function, absolute_import
  from datetime import datetime
  import os
  import math
  import numpy
  import time
  import tensorflow.compat.v1
  from tensorflow.contrib.factorization.python.ops import clustering_ops
  from tensorflow.contrib.tensor_forest.python.ops import data_ops
  from tensorflow.python.ops import state_ops, array_ops, math_ops
  from ...utils import validate_dim, read_tensor_in_checkpoint, prepare_X
  from ...data_utils import get_num_features, get_num_sample
  from ...data_flow import generate_data_tensor
  from ...distances import euclidean, cosine
  from ..base import BaseEstimator
label_desc: Use image node_id 12 for calling the KMeansBase obj's underlying member method code with example usage: obj.fit(X, shuffle, display_step, n_jobs, max_steps, verbose) without return types