class_docstr: HIST Model
  
  Parameters
  ----------
  lr : float
      learning rate
  d_feat : int
      input dimensions for each time step
  metric : str
      the evaluation metric used in early stop
  optimizer : str
      optimizer name
  GPU : str
      the GPU ID(s) used for training
code: def fit(
      self,
      dataset: DatasetH,
      evals_result=dict(),
      save_path=None,
  ):
      df_train, df_valid, df_test = dataset.prepare(
          ["train", "valid", "test"],
          col_set=["feature", "label"],
          data_key=DataHandlerLP.DK_L,
      )
      if df_train.empty or df_valid.empty:
          raise ValueError(
              "Empty data from dataset, please check your dataset config."
          )
  
      if not os.path.exists(self.stock2concept):
          url = "http://fintech.msra.cn/stock_data/downloads/qlib_csi300_stock2concept.npy"
          urllib.request.urlretrieve(url, self.stock2concept)
  
      stock_index = np.load(self.stock_index, allow_pickle=True).item()
      df_train["stock_index"] = 733
      df_train["stock_index"] = df_train.index.get_level_values(
          "instrument"
      ).map(stock_index)
      df_valid["stock_index"] = 733
      df_valid["stock_index"] = df_valid.index.get_level_values(
          "instrument"
      ).map(stock_index)
  
      x_train, y_train, stock_index_train = (
          df_train["feature"],
          df_train["label"],
          df_train["stock_index"],
      )
      x_valid, y_valid, stock_index_valid = (
          df_valid["feature"],
          df_valid["label"],
          df_valid["stock_index"],
      )
  
      save_path = get_or_create_path(save_path)
  
      stop_steps = 0
      best_score = -np.inf
      best_epoch = 0
      evals_result["train"] = []
      evals_result["valid"] = []
  
      # load pretrained base_model
      if self.base_model == "LSTM":
          pretrained_model = LSTMModel()
      elif self.base_model == "GRU":
          pretrained_model = GRUModel()
      else:
          raise ValueError(
              "unknown base model name `%s`" % self.base_model
          )
  
      if self.model_path is not None:
          self.logger.info("Loading pretrained model...")
          pretrained_model.load_state_dict(torch.load(self.model_path))
  
      model_dict = self.HIST_model.state_dict()
      pretrained_dict = {
          k: v
          for k, v in pretrained_model.state_dict().items()
          if k in model_dict  # pylint: disable=E1135
      }
      model_dict.update(pretrained_dict)
      self.HIST_model.load_state_dict(model_dict)
      self.logger.info("Loading pretrained model Done...")
  
      # train
      self.logger.info("training...")
      self.fitted = True
  
      for step in range(self.n_epochs):
          self.logger.info("Epoch%d:", step)
          self.logger.info("training...")
          self.train_epoch(x_train, y_train, stock_index_train)
  
          self.logger.info("evaluating...")
          train_loss, train_score = self.test_epoch(
              x_train, y_train, stock_index_train
          )
          val_loss, val_score = self.test_epoch(
              x_valid, y_valid, stock_index_valid
          )
          self.logger.info(
              "train %.6f, valid %.6f" % (train_score, val_score)
          )
          evals_result["train"].append(train_score)
          evals_result["valid"].append(val_score)
  
          if val_score > best_score:
              best_score = val_score
              stop_steps = 0
              best_epoch = step
              best_param = copy.deepcopy(self.HIST_model.state_dict())
          else:
              stop_steps += 1
              if stop_steps >= self.early_stop:
                  self.logger.info("early stop")
                  break
  
      self.logger.info(
          "best score: %.6lf @ %d" % (best_score, best_epoch)
      )
      self.HIST_model.load_state_dict(best_param)
      torch.save(best_param, save_path)
  
imports: from __future__ import division
  from __future__ import print_function
  import os
  import numpy
  import pandas
  from typing import Text, Union
  import urllib.request
  import copy
  from ...utils import get_or_create_path
  from ...log import get_module_logger
  import torch
  import torch.nn
  import torch.optim
  from .pytorch_utils import count_parameters
  from ...model.base import Model
  from ...data.dataset import DatasetH
  from ...data.dataset.handler import DataHandlerLP
  from ...contrib.model.pytorch_lstm import LSTMModel
  from ...contrib.model.pytorch_gru import GRUModel
label_desc: Use image node_id 9 for calling the HIST obj's underlying member method code with example usage: obj.fit(dataset, evals_result, save_path) without return types