# AUTOGENERATED FILE! PLEASE DON'T EDIT
"""For not very complicated loss functions"""
from ..callbacks import Callback, Callbacks, Cbs
from typing import Callable, Tuple
import torch, k1lib, math, torch.nn.functional as F
__all__ = ["LossF", "LossNLLCross"]
LossFSig = Callable[[Tuple[torch.Tensor, torch.Tensor]], float]
[docs]@k1lib.patch(Cbs)
@k1lib.patch(Callback.lossCls)
class LossF(Callback):
" "
[docs] def __init__(self, lossF:LossFSig):
"""Creates a generic loss function that takes in ``y`` and
correct y ``yb`` and return a single loss float (still attached to graph)."""
super().__init__()
self.lossF = lossF
def inLoss(self):
self.l.lossG = self.lossF(self.l.y, self.l.yb)
self.l.loss = self.l.lossG.detach().item()
@k1lib.patch(Callbacks, docs=LossF.__init__)
def withLossF(self, lossF:LossFSig, name:str=None):
return self.append(LossF(lossF), name=name)
[docs]@k1lib.patch(Cbs)
@k1lib.patch(Callback.lossCls)
class LossNLLCross(Callback):
" "
[docs] def __init__(self, nll:bool, integrations:bool):
"""Adds a cross-entropy/negative-likelihood loss function.
:param nll: if True, then use :class:`torch.nn.NLLLoss`, else use :class:`torch.nn.CrossEntropyLoss`
:param integrations: whether to integrate with :class:`~k1lib.callbacks.accuracy.AccF` callback"""
super().__init__(); self.integrations = integrations; self.ownsAccCb = False
self.order = 11 # to make sure it's after AccF
self.lossF = torch.nn.NLLLoss() if nll else torch.nn.CrossEntropyLoss()
def appended(self): # delayed initialization, so that learner and cbs has already been attached
if self.integrations:
if "AccF" not in self.cbs:
self.accuracyCb = Cbs.AccF()
self.cbs.append(self.accuracyCb)
self.ownsAccCb = True
else: self.accuracyCb = self.cbs.AccF
def inLoss(self):
self.l.lossG = self.lossF(self.l.y, self.l.yb)
self.l.loss = self.l.lossG.detach().item()
[docs] def detach(self):
super().detach()
if self.accuracyCb != None:
if self.ownsAccCb: self.accuracyCb.detach()
self.accuracyCb = None
@k1lib.patch(Callbacks, docs=LossNLLCross.__init__)
def withLossNLL(self, integrations:bool=True, name:str=None):
return self.append(LossNLLCross(True, integrations), name=name or "LossNLL")
@k1lib.patch(Callbacks, docs=LossNLLCross.__init__)
def withLossCrossEntropy(self, integrations:bool=True, name:str=None):
return self.append(LossNLLCross(False, integrations), name=name or "LossCrossEntropy")