code: def get_loss_fn(
      self, model: Model, labels: ep.Tensor
  ) -> Callable[[ep.Tensor], ep.Tensor]:
      # can be overridden by users
      def loss_fn(inputs: ep.Tensor) -> ep.Tensor:
          logits = model(inputs)
          return ep.crossentropy(logits, labels).sum()
  
      return loss_fn
  
imports: from typing import Union, Any, Optional, Callable, Tuple
  from abc import ABC, abstractmethod
  import eagerpy
  from ..devutils import flatten
  from ..devutils import atleast_kd
  from ..types import Bounds
  from ..models.base import Model
  from ..criteria import Misclassification, TargetedMisclassification
  from ..distances import l1, l2, linf
  from .base import FixedEpsilonAttack
  from .base import T
  from .base import get_criterion
  from .base import raise_if_kwargs
  from .base import verify_input_bounds
label_desc: Use image node_id 2 for calling the BaseGradientDescent obj's underlying member method code with example usage: obj.get_loss_fn(model, labels) and returns: loss_fn, ep