Skip to content

module autotuner

solverpy_learn.builder.autotuner

AutoTuner

Bases: Builder

Builder that trains a model by running Optuna-based hyperparameter tuning (autotune.prettytuner) over the training/development strategy files, then saves the best model.

Source code in packages/solverpy-learn/src/solverpy_learn/builder/autotuner.py
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
class AutoTuner(Builder):
   """
   [`Builder`][solverpy_learn.builder.builder.Builder] that trains a model by
   running Optuna-based hyperparameter tuning (`autotune.prettytuner`) over
   the training/development strategy files, then saves the best model.
   """

   def __init__(
      self,
      setup: Setup,
      tuneargs: (dict[str, Any] | None) = None,
      templates: (list[str] | None) = None,
   ):
      assert "evals" in setup
      assert "dataname" in setup["evals"]
      Builder.__init__(self, setup["evals"]["dataname"])
      self._setup = setup
      self._tuneargs: dict[str, Any] = TUNEARGS | (tuneargs or {})
      self._templates = templates or []

   def represent(self) -> dict[str, Any]:
      return dict(
         cls=f"{self.__class__.__module__}.{self.__class__.__name__}",
         dataname=self._dataname,
         tuneargs=self._tuneargs,
         templates=self._templates,
      )

   def path(self, modelfile: str = "model.lgb") -> str:
      if modelfile:
         return os.path.join(super().path(), modelfile)
      else:
         return super().path()

   def build(self, talker: Talker = Talker()) -> None:
      trains = self._setup["evals"]
      devels = self._setup["devels"] if "devels" in self._setup else trains
      assert "plugin" in trains
      assert "plugin" in devels
      assert "refs" in trains
      report = markdown.newline() + markdown.heading(f"Building model `{self._dataname}`", level=2)
      reporter.add(report)
      logger.info(f"Building model: {self._dataname}")
      logger.debug(f'using trains: {trains["plugin"].path()}')

      f_model = self.path()
      if os.path.exists(f_model):
         logger.info(f"Skipped model building; model {self._dataname} exists.")
         self._strats = self.applies(trains["refs"], self._dataname)
         return

      f_train = trains["plugin"].path()
      f_test = devels["plugin"].path()

      use_builder = ("atpeval" in self._tuneargs) and self._tuneargs["atpeval"]
      started_at = time.monotonic()

      logger.info(f"Tunning learning params: train={f_train} test={f_test}")
      logger.info(resource_summary("main", started_at))
      logger.debug(usage(f"before tuning: {self._dataname}"))
      try:
         ret = autotune.prettytuner(
            talker=talker,
            f_train=f_train,
            f_test=f_test,
            d_tmp=self.path("opt"),
            builder=self if use_builder else None,
            **self._tuneargs,
         )
      except KeyboardInterrupt:
         raise
      finally:
         logger.info(resource_summary("main", started_at))
         logger.debug(usage(f"after tuning: {self._dataname}"))

      #f_best = ret[3]
      (_, _, _, f_best, _, _, pos, neg) = ret
      (pos, neg) = (int(pos), int(neg))
      shutil.copyfile(f_best, f_model)
      #self._models = [f_model]
      self._strats = self.applies(trains["refs"], self._dataname)

      progress.build(self._dataname, *ret)
      logger.info(f"Model {self._dataname} built.")