class_docstr: This wrapper handles sklearn models for image classification.
class_docstr_tok: ["This","wrapper","handles","sklearn","models","for","image","classification","."]
docstr: Trains the model, evaluates it on val/test data and saves it to file.
docstr_tok: ["Trains","the","model",",","evaluates","it","on","val\/test","data","and","saves","it","to","file","."]
code: def _train(
      self,
      train_data,
      val_data,
      test_data,
      writer,
      experiment,
      dry_run: bool = False,
  ) -> None:
      """Trains the model, evaluates it on val/test data and saves it to file."""
  
      # Preprocess all datasets and log some stats about them.
      logger.info("Preprocessing datasets...")
      train_images, train_labels = self._preprocess_for_training(
          "train", train_data
      )
      val_images, val_labels = self._preprocess_for_training(
          "val", val_data
      )
      test_images, test_labels = self._preprocess_for_training(
          "test", test_data
      )
      logger.info("")
  
      # Create the model.
      logger.info("Creating model...")
      self._create_model()
      logger.info("")
  
      # Train the model
      if dry_run:
          # TODO: Ideally, this should only use one sample, but then there are errors
          #   further down (specifically when plotting samples) because there's only
          #   one class present in the training data.
          logger.info(f"Training model... (DRY RUN, only 100 samples)")
          self.model.fit(train_images[:100], train_labels[:100])
      elif "num_samples" in self.config:
          logger.info(
              f"Training model... (using {self.config['num_samples']} of "
              f"{len(train_images)} samples)"
          )
          self.model.fit(
              train_images[: self.config["num_samples"]],
              train_labels[: self.config["num_samples"]],
          )
      else:
          logger.info("Training model...")
          logger.info(
              "(if this takes too long, train on less data with the config "
              "parameter 'num_samples')"
          )
          self.model.fit(train_images, train_labels)
  
      # Evaluate and log accuracy on all datasets.
      def log_accuracy(name, images, labels):
          if images is None:
              return
          acc = self.model.score(images, labels)
          logger.info(
              f"{name.capitalize()} accuracy:".ljust(18) + str(acc)
          )
          writer.add_scalar(f"{name}_accuracy", acc)
          experiment.log_metric(f"{name}_accuracy", acc)
  
      log_accuracy("train", train_images, train_labels)
      log_accuracy("val", val_images, val_labels)
      log_accuracy("test", test_images, test_labels)
  
      # Plot a few samples from each dataset to tensorboard.
      num_samples_to_plot = self.config.get("num_samples_to_plot", 5)
  
      def plot_samples(name, images, labels):
          if images is None:
              return
          num = min(len(images), num_samples_to_plot)
          pred = self.model.predict_proba(images[:num])
          # TODO: Save sample images before shuffling train_data, and before
          #   preprocessing.
          original_images = images[:num].reshape(
              num, *self._original_image_size
          )
          visualization.plot_samples(
              writer,
              name,
              1,
              original_images,
              labels[:num],
              pred,
          )
  
      plot_samples("train-samples", train_images, train_labels)
      plot_samples("val-samples", val_images, val_labels)
      plot_samples("test-samples", test_images, test_labels)
  
      # Save model.
      self._save()
  
imports: import sklearn.preprocessing
  from sklearn.ensemble import RandomForestClassifier, GradientBoostingClassifier
  from sklearn.gaussian_process import GaussianProcessClassifier
  from sklearn.linear_model import LogisticRegression, SGDClassifier, Perceptron, PassiveAggressiveClassifier
  from sklearn.naive_bayes import GaussianNB
  from sklearn.neighbors import KNeighborsClassifier
  from sklearn.neural_network import MLPClassifier
  from sklearn.svm import SVC, LinearSVC
  from sklearn.tree import DecisionTreeClassifier, ExtraTreeClassifier
  from sklearn.utils import shuffle
  import joblib
  import numpy
  from loguru import logger
  from ..model_wrapper import ModelWrapper
  from .None import preprocessing, visualization
label_desc: Use image node_id 3 for calling the SklearnImageClassificationWrapper obj's underlying member method code with example usage: obj._train(train_data, val_data, test_data, writer, experiment, dry_run) without return types