torch.nn.SoftMarginLoss
class SoftMarginLoss extends Modulenew SoftMarginLoss(options?: SoftMarginLossOptions)
- readonly
reduction(Reduction)
Soft Margin Loss: smooth hinge loss for two-class classification.
Computes a soft (smooth) version of margin loss for binary classification. Similar to hinge loss but uses logarithm for smoothness and better numerical behavior. Takes raw unbounded outputs (not probabilities), making it more numerically stable than hinge loss. Less common than BCE or CrossEntropy but useful for margin-based binary classification.
When to use SoftMarginLoss:
- Binary classification with raw outputs (not probabilities)
- Smooth hinge loss for binary targets (-1, 1)
- Margin-based binary classification
- When you want a smooth approximation to SVM-style hinge loss
- Binary classification with noisy labels (log-loss behavior)
Trade-offs:
- vs HingeLoss: Smooth and differentiable everywhere; hinge has kink at 1
- vs BCELoss: Margin-based vs probability-based (SoftMargin doesn't need sigmoid)
- Numerical stability: Handled by log-sum-exp formulation
- Target format: Requires targets in {-1, 1}
- Gradient behavior: Smooth gradient flow compared to hard hinge loss
Algorithm: For each input x and target y ∈ {1, -1}: loss = log(1 + exp(-y * x))
This is a smooth approximation of max(0, 1 - y * x).
- Binary targets: Target must be 1 or -1, not 0 and 1
- Raw scores: Input should be unbounded logits, NOT probabilities
- Smoothness: Smooth alternative to hinge loss
- Relationship to Logistic Regression: Essentially binary logistic regression loss
- Optimization: Convex and smooth, easy to optimize
Examples
// Binary classification with SoftMarginLoss
const loss_fn = new torch.nn.SoftMarginLoss();
const predictions = torch.tensor([0.5, -2.0, 3.1, -0.2]);
const targets = torch.tensor([1.0, -1.0, 1.0, -1.0]);
const loss = loss_fn.forward(predictions, targets);
// For [0.5, 1.0]: log(1 + exp(-0.5)) \u2248 0.47
// For [-2.0, -1.0]: log(1 + exp(-2.0)) \u2248 0.12 (correctly predicted negative)// SoftMarginLoss with a simple classifier
class BinaryClassifier extends torch.nn.Module {
fc: torch.nn.Linear;
constructor() {
super();
this.fc = new torch.nn.Linear(10, 1);
}
forward(x: torch.Tensor): torch.Tensor {
return this.fc.forward(x).squeeze(-1); // Output: [batch]
}
}
const model = new BinaryClassifier();
const loss_fn = new torch.nn.SoftMarginLoss({ reduction: 'mean' });
const x = torch.randn([32, 10]);
const y = torch.cat([torch.ones([16]), torch.ones([16]).mul(-1)]); // targets in {-1, 1}
const scores = model.forward(x);
const loss = loss_fn.forward(scores, y);