Implementation of common loss functions in PyTorch and from scratch:
- PyTorch built-in losses
- Custom loss implementation
- Loss function selection
- Gradient computation
import torch
import torch.nn as nn
import torch.nn.functional as F
import numpy as np
# PyTorch built-in loss functions
class CommonLosses:
def __init__(self):
self.mse = nn.MSELoss()
self.mae = nn.L1Loss()
self.bce = nn.BCELoss()
self.ce = nn.CrossEntropyLoss()
def regression_loss(self, pred, target, loss_type='mse'):
if loss_type == 'mse':
return self.mse(pred, target)
elif loss_type == 'mae':
return self.mae(pred, target)
elif loss_type == 'huber':
return F.smooth_l1_loss(pred, target)
else:
raise ValueError(f"Unknown loss type: {loss_type}")
def classification_loss(self, pred, target, loss_type='ce'):
if loss_type == 'bce':
return self.bce(pred, target)
elif loss_type == 'ce':
return self.ce(pred, target)
else:
raise ValueError(f"Unknown loss type: {loss_type}")
# Custom loss function implementations
class CustomLosses:
@staticmethod
def focal_loss(pred, target, gamma=2.0):
'''Focal Loss implementation for binary classification'''
bce = F.binary_cross_entropy_with_logits(pred, target, reduction='none')
p_t = torch.exp(-bce)
focal_loss = (1 - p_t) ** gamma * bce
return focal_loss.mean()
@staticmethod
def contrastive_loss(pred1, pred2, target, margin=1.0):
'''Contrastive Loss for similarity learning'''
distance = F.pairwise_distance(pred1, pred2)
loss = target * torch.pow(distance, 2) + (1 - target) * torch.pow(torch.clamp(margin - distance, min=0.0), 2)
return loss.mean()
@staticmethod
def triplet_loss(anchor, positive, negative, margin=1.0):
'''Triplet Loss for metric learning'''
pos_dist = F.pairwise_distance(anchor, positive)
neg_dist = F.pairwise_distance(anchor, negative)
loss = torch.clamp(pos_dist - neg_dist + margin, min=0.0)
return loss.mean()