{"record":{"id":"ccfee711ebbc8487","repo":"eriklindernoren/ML-From-Scratch","slug":"notimplementederror-ccfee7","errorCode":null,"errorMessage":"NotImplementedError()","messagePattern":"NotImplementedError\\(\\)","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"mlfromscratch/deep_learning/loss_functions.py","lineNumber":11,"sourceCode":"from __future__ import division\nimport numpy as np\nfrom mlfromscratch.utils import accuracy_score\nfrom mlfromscratch.deep_learning.activation_functions import Sigmoid\n\nclass Loss(object):\n    def loss(self, y_true, y_pred):\n        return NotImplementedError()\n\n    def gradient(self, y, y_pred):\n        raise NotImplementedError()\n\n    def acc(self, y, y_pred):\n        return 0\n\nclass SquareLoss(Loss):\n    def __init__(self): pass\n\n    def loss(self, y, y_pred):\n        return 0.5 * np.power((y - y_pred), 2)\n\n    def gradient(self, y, y_pred):\n        return -(y - y_pred)\n\nclass CrossEntropy(Loss):\n    def __init__(self): pass\n\n    def loss(self, y, p):\n        # Avoid division by zero","sourceCodeStart":1,"sourceCodeEnd":29,"githubUrl":"https://github.com/eriklindernoren/ML-From-Scratch/blob/a2806c6732eee8d27762edd6d864e0c179d8e9e8/mlfromscratch/deep_learning/loss_functions.py#L1-L29","documentation":"Loss.gradient is an abstract method on the Loss base class in mlfromscratch/deep_learning/loss_functions.py and raises NotImplementedError. During training, NeuralNetwork.backpropagate calls loss.gradient(y, y_pred) to get dL/dy_pred; if the loss object is the base Loss (or a custom subclass that didn't implement gradient), this stub raises. Note loss() on the base class returns NotImplementedError instead of raising — a related latent bug — but gradient() is the hard failure.","triggerScenarios":"Instantiating mlfromscratch.deep_learning.loss_functions.Loss and passing it as NeuralNetwork(loss=...), then calling fit; or defining a custom Loss subclass that implements loss/acc but not gradient(y, y_pred). The error occurs on the first backward pass of model.fit.","commonSituations":"Writing a custom loss (e.g. weighted cross-entropy) and forgetting the gradient method; assuming the library computes numerical gradients from loss() (it doesn't — gradients are analytic and must be supplied); version upgrades where the gradient method signature changed.","solutions":["Implement gradient(self, y, y_pred) in your Loss subclass returning the derivative of the loss w.r.t. y_pred (e.g. 0.5 * (y_pred - y) for SquareLoss in this library)","Use a built-in concrete loss (SquareLoss, CrossEntropy, etc.) instead of the base Loss class","Match the method exactly: def gradient(self, y, y_pred): — two arguments besides self","If prototyping, subclass an existing loss like SquareLoss and override only what changes"],"exampleFix":"// before\nclass MyLoss(Loss):\n    def loss(self, y, y_pred):\n        return np.mean((y - y_pred) ** 2)\n    # gradient missing -> NotImplementedError on first fit() backward pass\n\n// after\nclass MyLoss(Loss):\n    def loss(self, y, y_pred):\n        return np.mean((y - y_pred) ** 2)\n\n    def gradient(self, y, y_pred):\n        return 2 * (y_pred - y) / y.shape[0]  # dL/dy_pred\n\n    def acc(self, y, y_pred):\n        return 0","handlingStrategy":"validation","validationCode":"from mlfromscratch.deep_learning.loss_functions import Loss\n\nfn = getattr(type(model.loss_function), 'gradient', None)\nassert fn is not None and fn is not Loss.gradient, (\n    'Loss object does not implement gradient(y, y_pred); '\n    'use a built-in loss or implement gradient in your subclass')","typeGuard":"from mlfromscratch.deep_learning.loss_functions import Loss\n\ndef is_complete_loss(obj) -> bool:\n    if not isinstance(obj, Loss):\n        return False\n    for m in ('loss', 'gradient', 'acc'):\n        fn = getattr(type(obj), m, None)\n        if fn is None or fn is getattr(Loss, m, None):\n            return False\n    return True","tryCatchPattern":"try:\n    model.fit(X_train, y_train, n_epochs=10)\nexcept NotImplementedError as e:\n    raise TypeError(\n        f'Loss {type(model.loss_function).__name__} is incomplete; '\n        'implement gradient(y, y_pred) or use SquareLoss/CrossEntropy') from e","preventionTips":["Use built-in losses (SquareLoss, CrossEntropy) unless you truly need a custom one","A custom loss must implement loss, gradient, AND acc — gradient is what backprop consumes","Return the gradient w.r.t. y_pred, matching the shape of y_pred","Unit-test a new loss with model.fit on a few dummy samples before a full training run"],"tags":["python","deep-learning","loss-function","abstract-method","not-implemented"],"backgroundTag":"abstract-method-not-implemented","analyzedSha":"a2806c6732eee8d27762edd6d864e0c179d8e9e8","analyzedAt":"2026-08-27T20:30:03.909Z","schemaVersion":2},"datasetVersion":"2026-08-28T00:17:15.603Z"}