class_docstr: Training pipeline for a hybrid recommendation model using a pre-trained matrix factorization
  model as its base.
  
  ``HybridPretrainedModel`` models contain dense layers that process item and/or user metadata,
  concatenate this embedding with the user and item embeddings copied from a trained
  ``MatrixFactorizationModel``, and send this concatenated embedding through more dense layers to
  output a single float ranking / rating. We add both user and item biases to this score before
  returning. This is the same architecture as the ``HybridModel``, but we are using the embeddings
  from a pre-trained model rather than training them up ourselves.
  
  All ``HybridPretrainedModel`` instances are subclasses of the ``LightningModule`` class
  provided by PyTorch Lightning. This means to train a model, you will need a
  ``collie.model.CollieTrainer`` object, but the model can be saved and loaded without this
  ``Trainer`` instance. Example usage may look like:
  
  .. code-block:: python
  
      from collie.model import CollieTrainer, HybridPretrainedModel, MatrixFactorizationModel
  
  
      # instantiate and fit a ``MatrixFactorizationModel`` as expected
      mf_model = MatrixFactorizationModel(train=train)
      mf_trainer = CollieTrainer(mf_model)
      mf_trainer.fit(mf_model)
  
      hybrid_model = HybridPretrainedModel(train=train,
                                           item_metadata=item_metadata,
                                           user_metadata=user_metadata,
                                           trained_model=mf_model)
      hybrid_trainer = CollieTrainer(hybrid_model)
      hybrid_trainer.fit(hybrid_model)
      hybrid_model.eval()
  
      # do evaluation as normal with ``hybrid_model``
  
      hybrid_model.save_model(path='model')
      new_hybrid_model = HybridPretrainedModel(load_model_path='model')
  
      # do evaluation as normal with ``new_hybrid_model``
  
  Parameters
  ----------
  item_metadata: torch.tensor, pd.DataFrame, or np.array, 2-dimensional
      The shape of the item metadata should be (num_items x metadata_features), and each item's
      metadata should be available when indexing a row by an item ID
  user_metadata: torch.tensor, pd.DataFrame, or np.array, 2-dimensional
      The shape of the user metadata should be (num_users x metadata_features), and each user's
      metadata should be available when indexing a row by an item ID
  trained_model: ``collie.model.MatrixFactorizationModel``
      Previously trained ``MatrixFactorizationModel`` model to extract embeddings from
  item_metadata_layers_dims: list
      List of linear layer dimensions to apply to the item metadata only, starting with the
      dimension directly following ``metadata_features`` and ending with the dimension to
      concatenate with the item embeddings
  user_metadata_layers_dims: list
      List of linear layer dimensions to apply to the user metadata only, starting with the
      dimension directly following ``metadata_features`` and ending with the dimension to
      concatenate with the user embeddings
  combined_layers_dims: list
      List of linear layer dimensions to apply to the concatenated item embeddings and item
      metadata, starting with the dimension directly following the shape of
      ``item_embeddings + metadata_features`` and ending with the dimension before the final
      linear layer to dimension 1
  freeze_embeddings: bool
      When initializing the model, whether or not to freeze ``trained_model``'s embeddings
  dropout_p: float
      Probability of dropout
  optimizer: torch.optim or str
      If a string, one of the following supported optimizers:
  
      * ``'sgd'`` (for ``torch.optim.SGD``)
  
      * ``'adam'`` (for ``torch.optim.Adam``)
class_docstr_tok: ["Training","pipeline","for","a","hybrid","recommendation","model","using","a","pre-trained","matrix","factorization","model","as","its","base",".","``","HybridPretrainedModel","``","models","contain","dense","layers","that","process","item","and\/or","user","metadata",",","concatenate","this","embedding","with","the","user","and","item","embeddings","copied","from","a","trained","``","MatrixFactorizationModel","``",",","and","send","this","concatenated","embedding","through","more","dense","layers","to","output","a","single","float","ranking","\/","rating",".","We","add","both","user","and","item","biases","to","this","score","before","returning",".","This","is","the","same","architecture","as","the","``","HybridModel","``",",","but","we","are","using","the","embeddings","from","a","pre-trained","model","rather","than","training","them","up","ourselves",".","All","``","HybridPretrainedModel","``","instances","are","subclasses","of","the","``","LightningModule","``","class","provided","by","PyTorch","Lightning",".","This","means","to","train","a","model",",","you","will","need","a","``","collie.model.CollieTrainer","``","object",",","but","the","model","can","be","saved","and","loaded","without","this","``","Trainer","``","instance",".","Example","usage","may","look","like",":","..","code-block",":",":","python","from","collie.model","import","CollieTrainer",",","HybridPretrainedModel",",","MatrixFactorizationModel","#","instantiate","and","fit","a","``","MatrixFactorizationModel","``","as","expected","mf_model","=","MatrixFactorizationModel","(","train=train",")","mf_trainer","=","CollieTrainer","(","mf_model",")","mf_trainer.fit","(","mf_model",")","hybrid_model","=","HybridPretrainedModel","(","train=train",",","item_metadata=item_metadata",",","user_metadata=user_metadata",",","trained_model=mf_model",")","hybrid_trainer","=","CollieTrainer","(","hybrid_model",")","hybrid_trainer.fit","(","hybrid_model",")","hybrid_model.eval","(",")","#","do","evaluation","as","normal","with","``","hybrid_model","``","hybrid_model.save_model","(","path='model","'",")","new_hybrid_model","=","HybridPretrainedModel","(","load_model_path='model","'",")","#","do","evaluation","as","normal","with","``","new_hybrid_model","``","Parameters","--","--","--","--","--","item_metadata",":","torch.tensor",",","pd.DataFrame",",","or","np.array",",","2-dimensional","The","shape","of","the","item","metadata","should","be","(","num_items","x","metadata_features",")",",","and","each","item's","metadata","should","be","available","when","indexing","a","row","by","an","item","ID","user_metadata",":","torch.tensor",",","pd.DataFrame",",","or","np.array",",","2-dimensional","The","shape","of","the","user","metadata","should","be","(","num_users","x","metadata_features",")",",","and","each","user's","metadata","should","be","available","when","indexing","a","row","by","an","item","ID","trained_model",":","``","collie.model.MatrixFactorizationModel","``","Previously","trained","``","MatrixFactorizationModel","``","model","to","extract","embeddings","from","item_metadata_layers_dims",":","list","List","of","linear","layer","dimensions","to","apply","to","the","item","metadata","only",",","starting","with","the","dimension","directly","following","``","metadata_features","``","and","ending","with","the","dimension","to","concatenate","with","the","item","embeddings","user_metadata_layers_dims",":","list","List","of","linear","layer","dimensions","to","apply","to","the","user","metadata","only",",","starting","with","the","dimension","directly","following","``","metadata_features","``","and","ending","with","the","dimension","to","concatenate","with","the","user","embeddings","combined_layers_dims",":","list","List","of","linear","layer","dimensions","to","apply","to","the","concatenated","item","embeddings","and","item","metadata",",","starting","with","the","dimension","directly","following","the","shape","of","``","item_embeddings","+","metadata_features","``","and","ending","with","the","dimension","before","the","final","linear","layer","to","dimension","1","freeze_embeddings",":","bool","When","initializing","the","model",",","whether","or","not","to","freeze","``","trained_model","``","'s","embeddings","dropout_p",":","float","Probability","of","dropout","optimizer",":","torch.optim","or","str","If","a","string",",","one","of","the","following","supported","optimizers",":","*","``","'sgd","'","``","(","for","``","torch.optim.SGD","``",")","*","``","'adam","'","``","(","for","``","torch.optim.Adam","``",")"]
docstr: Save the model's state dictionary, hyperparameters, and user and/or item metadata.
  
  While PyTorch Lightning offers a way to save and load models, there are two main reasons
  for overriding these:
  
  1) To properly save and load a model requires the ``Trainer`` object, meaning that all
     deployed models will require Lightning to run the model, which is not actually needed
     for inference.
  
  2) In the v0.8.4 release, loading a model back in leads to a ``RuntimeError`` unable to load
     in weights.
  
  Parameters
  ----------
  path: str or Path
      Directory path to save model and data files
  overwrite: bool
      Whether or not to overwrite existing data
docstr_tok: ["Save","the","model","'s","state","dictionary",",","hyperparameters",",","and","user","and\/or","item","metadata",".","While","PyTorch","Lightning","offers","a","way","to","save","and","load","models",",","there","are","two","main","reasons","for","overriding","these",":","1",")","To","properly","save","and","load","a","model","requires","the","``","Trainer","``","object",",","meaning","that","all","deployed","models","will","require","Lightning","to","run","the","model",",","which","is","not","actually","needed","for","inference",".","2",")","In","the","v0.8.4","release",",","loading","a","model","back","in","leads","to","a","``","RuntimeError","``","unable","to","load","in","weights",".","Parameters","--","--","--","--","--","path",":","str","or","Path","Directory","path","to","save","model","and","data","files","overwrite",":","bool","Whether","or","not","to","overwrite","existing","data"]
code: def save_model(
      self,
      path: Union[str, Path] = os.path.join(DATA_PATH / "model"),
      overwrite: bool = False,
  ) -> None:
      """
      Save the model's state dictionary, hyperparameters, and user and/or item metadata.
  
      While PyTorch Lightning offers a way to save and load models, there are two main reasons
      for overriding these:
  
      1) To properly save and load a model requires the ``Trainer`` object, meaning that all
         deployed models will require Lightning to run the model, which is not actually needed
         for inference.
  
      2) In the v0.8.4 release, loading a model back in leads to a ``RuntimeError`` unable to load
         in weights.
  
      Parameters
      ----------
      path: str or Path
          Directory path to save model and data files
      overwrite: bool
          Whether or not to overwrite existing data
  
      """
      path = str(path)
  
      if os.path.exists(path):
          if os.listdir(path) and overwrite is False:
              raise ValueError(
                  f"Data exists in ``path`` at {path} and ``overwrite`` is False."
              )
  
      Path(path).mkdir(parents=True, exist_ok=True)
      if self.item_metadata is not None:
          joblib.dump(
              self.item_metadata,
              os.path.join(path, "item_metadata.pkl"),
          )
  
      if self.user_metadata is not None:
          joblib.dump(
              self.user_metadata,
              os.path.join(path, "user_metadata.pkl"),
          )
  
      # preserve ordering while extracting the state dictionary without the ``_trained_model``
      # component
      state_dict_keys_to_save = [
          k
          for k, _ in self.state_dict().items()
          if "_trained_model" not in k
      ]
      state_dict_vals_to_save = [
          v
          for k, v in self.state_dict().items()
          if "_trained_model" not in k
      ]
      state_dict_to_save = OrderedDict(
          zip(state_dict_keys_to_save, state_dict_vals_to_save)
      )
  
      dict_to_save = {
          "state_dict": state_dict_to_save,
          "hparams": self.hparams,
      }
      torch.save(dict_to_save, os.path.join(path, "model.pth"))
  
imports: from collections import OrderedDict
  import copy
  from functools import partial
  import os
  from pathlib import Path
  from typing import Callable, Dict, Iterable, List, Optional, Union
  import warnings
  import joblib
  import numpy
  import pandas
  import torch
  from torch import nn
  import torch.nn.functional
  from torch.optim.lr_scheduler import ReduceLROnPlateau
  from collie.config import DATA_PATH
  from collie.model.base import BasePipeline, INTERACTIONS_LIKE_INPUT, ScaledEmbedding, ZeroEmbedding
  from collie.model.matrix_factorization import MatrixFactorizationModel
  from collie.utils import get_init_arguments, merge_docstrings
label_desc: Use image node_id 13 for calling the HybridPretrainedModel obj's underlying member method code with example usage: obj.save_model(path, overwrite) without return types