class_docstr: Training pipeline for the collaborative metric learning model.
  
  ``CollaborativeMetricLearningModel`` models have an embedding layer for both users and items. A
  single float, prediction is retrieved by taking the pairwise distance between the two
  embeddings.
  
  The implementation here is meant to mimic its original implementation as specified here:
  https://arxiv.org/pdf/1803.00202.pdf [1]_
  
  All ``CollaborativeMetricLearningModel`` 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 CollaborativeMetricLearningModel, CollieTrainer
  
      model = CollaborativeMetricLearningModel(train=train)
      trainer = CollieTrainer(model)
      trainer.fit(model)
      model.eval()
  
      # do evaluation as normal with ``model``
  
      model.save_model(filename='model.pth')
      new_model = CollaborativeMetricLearningModel(load_model_path='model.pth')
  
      # do evaluation as normal with ``new_model``
  
  Parameters
  ----------
  embedding_dim: int
      Number of latent factors to use for user and item embeddings
  sparse: bool
      Whether or not to treat embeddings as sparse tensors. If ``True``, cannot use weight decay
      on the optimizer
  y_range: tuple
      Specify as ``(min, max)`` to apply a sigmoid layer to the output score of the model to get
      predicted ratings within the range of ``min`` and ``max``
  
  References
  ----------
  .. [1] Campo, Miguel, et al. "Collaborative Metric Learning Recommendation System: Application
      to Theatrical Movie Releases." ArXiv.org, 1 Mar. 2018, arxiv.org/abs/1803.00202.
code: def __init__(
      self,
      train: INTERACTIONS_LIKE_INPUT = None,
      val: INTERACTIONS_LIKE_INPUT = None,
      embedding_dim: int = 30,
      sparse: bool = False,
      lr: float = 1e-3,
      lr_scheduler_func: Optional[
          torch.optim.lr_scheduler._LRScheduler
      ] = partial(ReduceLROnPlateau, patience=1, verbose=True),
      weight_decay: float = 0.0,
      optimizer: Union[str, torch.optim.Optimizer] = "adam",
      loss: Union[str, Callable[..., torch.tensor]] = "hinge",
      metadata_for_loss: Optional[Dict[str, torch.tensor]] = None,
      metadata_for_loss_weights: Optional[Dict[str, float]] = None,
      y_range: Optional[Tuple[float, float]] = None,
      load_model_path: Optional[str] = None,
      map_location: Optional[str] = None,
  ):
      super().__init__(**get_init_arguments())
  
file_path: collie/collie/model/collaborative_metric_learning.py
imports: from functools import partial
  from typing import Callable, Dict, Optional, Tuple, Union
  import torch
  import torch.nn.functional
  from torch.optim.lr_scheduler import ReduceLROnPlateau
  from collie.model.base import BasePipeline, INTERACTIONS_LIKE_INPUT, ScaledEmbedding
  from collie.utils import get_init_arguments, merge_docstrings
label_desc: Use image node_id 1 to create a new CollaborativeMetricLearningModel object from inherited base classes: BasePipeline with example: obj = CollaborativeMetricLearningModel(train, val, embedding_dim, sparse, lr, lr_scheduler_func, weight_decay, optimizer, loss, metadata_for_loss, metadata_for_loss_weights, y_range, load_model_path, map_location)