class_docstr: YOLO anchor optimizer using k-means. Code refer to `AlexeyAB/darknet.
  <https://github.com/AlexeyAB/darknet/blob/master/src/detector.c>`_.
  
  Args:
      num_anchors (int) : Number of anchors.
      iters (int): Maximum iterations for k-means.
class_docstr_tok: ["YOLO","anchor","optimizer","using","k-means",".","Code","refer","to","`","AlexeyAB\/darknet",".","<","https",":","\/\/github.com\/AlexeyAB\/darknet\/blob\/master\/src\/detector.c",">","`","_",".","Args",":","num_anchors","(","int",")",":","Number","of","anchors",".","iters","(","int",")",":","Maximum","iterations","for","k-means","."]
code: def kmeans_anchors(self):
      self.logger.info(
          f"Start cluster {self.num_anchors} YOLO anchors with K-means..."
      )
      bboxes = self.get_zero_center_bbox_tensor()
      cluster_center_idx = torch.randint(
          0, bboxes.shape[0], (self.num_anchors,)
      ).to(self.device)
  
      assignments = torch.zeros((bboxes.shape[0],)).to(self.device)
      cluster_centers = bboxes[cluster_center_idx]
      if self.num_anchors == 1:
          cluster_centers = self.kmeans_maximization(
              bboxes, assignments, cluster_centers
          )
          anchors = (
              bbox_xyxy_to_cxcywh(cluster_centers)[:, 2:].cpu().numpy()
          )
          anchors = sorted(anchors, key=lambda x: x[0] * x[1])
          return anchors
  
      prog_bar = ProgressBar(self.iters)
      for i in range(self.iters):
          converged, assignments = self.kmeans_expectation(
              bboxes, assignments, cluster_centers
          )
          if converged:
              self.logger.info(
                  f"K-means process has converged at iter {i}."
              )
              break
          cluster_centers = self.kmeans_maximization(
              bboxes, assignments, cluster_centers
          )
          prog_bar.update()
      print("\n")
      avg_iou = (
          bbox_overlaps(bboxes, cluster_centers).max(1)[0].mean().item()
      )
  
      anchors = (
          bbox_xyxy_to_cxcywh(cluster_centers)[:, 2:].cpu().numpy()
      )
      anchors = sorted(anchors, key=lambda x: x[0] * x[1])
      self.logger.info(f"Anchor cluster finish. Average IOU: {avg_iou}")
  
      return anchors
  
imports: import argparse
  import os.path
  import numpy
  import torch
  from mmengine.config import Config
  from mmengine.fileio import dump
  from mmengine.logging import MMLogger
  from mmengine.registry import init_default_scope
  from mmengine.utils import ProgressBar
  from scipy.optimize import differential_evolution
  from mmdet.registry import DATASETS
  from mmdet.structures.bbox import bbox_cxcywh_to_xyxy, bbox_overlaps, bbox_xyxy_to_cxcywh
  from mmdet.utils import replace_cfg_vals, update_data_root
label_desc: Use image node_id 3 for calling the YOLOKMeansAnchorOptimizer obj's underlying member method code with example usage: obj.kmeans_anchors() and returns: anchors, anchors