class_docstr: SVM trainer that takes care of training (using k-fold cross validation),
  and evaluating the SVMs
class_docstr_tok: ["SVM","trainer","that","takes","care","of","training","(","using","k-fold","cross","validation",")",",","and","evaluating","the","SVMs"]
docstr: Train SVM on the input features and targets for a given class.
  The SVMs are trained for all costs values for the given class. We
  also save the cross-validation AP at each cost value for the given
  class.
docstr_tok: ["Train","SVM","on","the","input","features","and","targets","for","a","given","class",".","The","SVMs","are","trained","for","all","costs","values","for","the","given","class",".","We","also","save","the","cross-validation","AP","at","each","cost","value","for","the","given","class","."]
code: def train_cls(self, features, targets, cls_num):
      """
      Train SVM on the input features and targets for a given class.
      The SVMs are trained for all costs values for the given class. We
      also save the cross-validation AP at each cost value for the given
      class.
      """
      logging.info(f"Training cls: {cls_num}")
      for cost_idx in range(len(self.costs_list)):
          cost = self.costs_list[cost_idx]
          out_file, ap_out_file = self._get_svm_model_filename(
              cls_num, cost
          )
          if (
              g_pathmgr.exists(out_file)
              and g_pathmgr.exists(ap_out_file)
              and not self.config.force_retrain
          ):
              logging.info(f"SVM model exists: {out_file}")
              logging.info(f"AP file exists: {ap_out_file}")
              continue
  
          logging.info(
              f"Training model with the cost: {cost} cls: {cls_num}"
          )
          clf = LinearSVC(
              C=cost,
              class_weight={1: 2, -1: 1},
              intercept_scaling=1.0,
              verbose=1,
              penalty=self.config["penalty"],
              loss=self.config["loss"],
              tol=0.0001,
              dual=self.config["dual"],
              max_iter=self.config["max_iter"],
          )
          cls_labels = targets[:, cls_num].astype(
              dtype=np.int32, copy=True
          )
          # meaning of labels in VOC/COCO original loaded target files:
          # label 0 = not present, set it to -1 as svm train target
          # label 1 = present. Make the svm train target labels as -1, 1.
          cls_labels[np.where(cls_labels == 0)] = -1
          num_positives = len(np.where(cls_labels == 1)[0])
          num_negatives = len(cls_labels) - num_positives
          logging.info(
              f"cls: {cls_num} has +ve: {num_positives} -ve: {num_negatives} "
              f"ratio: {float(num_positives) / num_negatives} "
              f"features: {features.shape} cls_labels: {cls_labels.shape}"
          )
          ap_scores = cross_val_score(
              clf,
              features,
              cls_labels,
              cv=self.config["cross_val_folds"],
              scoring="average_precision",
          )
          self.train_ap_matrix[cls_num][cost_idx] = ap_scores.mean()
          clf.fit(features, cls_labels)
          logging.info(
              f"cls: {cls_num} cost: {cost} AP: {ap_scores} "
              f"mean:{ap_scores.mean()}"
          )
          logging.info(f"Saving cls cost AP to: {ap_out_file}")
          save_file(np.array([ap_scores.mean()]), ap_out_file)
          logging.info(f"Saving SVM model to: {out_file}")
          with g_pathmgr.open(out_file, "wb") as fwrite:
              pickle.dump(clf, fwrite)
  
imports: import logging
  import pickle
  import threading
  import numpy
  from iopath.common.file_io import g_pathmgr
  from sklearn.model_selection import cross_val_score
  from sklearn.svm import LinearSVC
  from vissl.utils.io import load_file, save_file
  from vissl.utils.svm_utils.evaluate import get_precision_recall
label_desc: Use image node_id 9 for calling the SVMTrainer obj's underlying member method code with example usage: obj.train_cls(features, targets, cls_num) without return types