Add smooth l1 loss algorithm
diff --git a/machine_learning/loss_functions.py b/machine_learning/loss_functions.py
index 36a760326f3d..24d732fb0ed9 100644
--- a/machine_learning/loss_functions.py
+++ b/machine_learning/loss_functions.py
@@ -471,6 +471,62 @@ def perplexity_loss(
     return np.mean(perp_losses)
 
 
+def smooth_l1_loss(y_true: np.ndarray, y_pred: np.ndarray, beta: float = 1.0) -> float:
+    """
+    Calculate the Smooth L1 Loss between y_true and y_pred.
+
+    The Smooth L1 Loss is less sensitive to outliers than the L2 Loss and is often used
+    in regression problems, such as object detection.
+
+    Smooth L1 Loss =
+        0.5 * (x - y)^2 / beta, if |x - y| < beta
+        |x - y| - 0.5 * beta, otherwise
+
+    Reference:
+    https://pytorch.org/docs/stable/generated/torch.nn.SmoothL1Loss.html
+
+    Args:
+        y_true: Array of true values.
+        y_pred: Array of predicted values.
+        beta: Specifies the threshold at which to change between L1 and L2 loss.
+
+    Returns:
+        The calculated Smooth L1 Loss between y_true and y_pred.
+
+    Raises:
+        ValueError: If the length of the two arrays is not the same.
+
+    >>> y_true = np.array([3, 5, 2, 7])
+    >>> y_pred = np.array([2.9, 4.8, 2.1, 7.2])
+    >>> smooth_l1_loss(y_true, y_pred, 1.0)
+    0.012500000000000022
+
+    >>> y_true = np.array([2, 4, 6])
+    >>> y_pred = np.array([1, 5, 7])
+    >>> smooth_l1_loss(y_true, y_pred, 1.0)
+    0.5
+
+    >>> y_true = np.array([1, 3, 5, 7])
+    >>> y_pred = np.array([1, 3, 5, 7])
+    >>> smooth_l1_loss(y_true, y_pred, 1.0)
+    0.0
+
+    >>> y_true = np.array([1, 3, 5])
+    >>> y_pred = np.array([1, 3, 5, 7])
+    >>> smooth_l1_loss(y_true, y_pred, 1.0)
+    Traceback (most recent call last):
+    ...
+    ValueError: The length of the two arrays should be the same.
+    """
+
+    if len(y_true) != len(y_pred):
+        raise ValueError("The length of the two arrays should be the same.")
+
+    diff = np.abs(y_true - y_pred)
+    loss = np.where(diff < beta, 0.5 * diff**2 / beta, diff - 0.5 * beta)
+    return np.mean(loss)
+
+
 if __name__ == "__main__":
     import doctest
 

### Describe your change:

- The [Smooth L1 Loss](https://pytorch.org/docs/stable/generated/torch.nn.SmoothL1Loss.html#torch.nn.SmoothL1Loss) is less sensitive to outliers than the L2 Loss and is often used in regression problems, such as object detection.


* [x] Add an algorithm?
* [ ] Fix a bug or typo in an existing algorithm?
* [ ] Add or change doctests? -- Note: Please avoid changing both code and tests in a single pull request.
* [ ] Documentation change?

### Checklist:
* [x] I have read [CONTRIBUTING.md](https://github.com/TheAlgorithms/Python/blob/master/CONTRIBUTING.md).
* [x] This pull request is all my own work -- I have not plagiarized.
* [x] I know that pull requests will not be merged if they fail the automated tests.
* [x] This PR only changes one algorithm file.  To ease review, please open separate PRs for separate algorithms.
* [x] All new Python files are placed inside an existing directory.
* [x] All filenames are in all lowercase characters with no spaces or dashes.
* [x] All functions and variable names follow Python naming conventions.
* [x] All function parameters and return values are annotated with Python [type hints](https://docs.python.org/3/library/typing.html).
* [x] All functions have [doctests](https://docs.python.org/3/library/doctest.html) that pass the automated testing.
* [x] All new algorithms include at least one URL that points to Wikipedia or another similar explanation.
* [ ] If this pull request resolves one or more open issues then the description above includes the issue number(s) with a [closing keyword](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue): "Fixes #ISSUE-NUMBER".
