Skip to content
Huber vs. Squared Loss

Huber vs. Squared Loss

huber_loss.py
import matplotlib.pyplot as plt
import numpy as np

x = np.arange(-100, 101, 1, dtype=float) / 100.0
y = x.copy()
y[-1] = 100

delta = 1

def grad_squared_loss(x, w, y):
    return np.dot(-x, y - w*x) / len(x)

def grad_huber_loss(x, w, y):
    mask = np.abs(y - x*w) <= delta
    sum = 0.0
    sum += np.dot(-x[mask], y[mask] - w*x[mask])
    sum += np.dot(-x[mask^True], np.sign(x[mask^True])) * delta
    return sum / len(x)

def gdesc(start, gradient, eta):
    last = start
    for i in range(200):
        start -= gradient(x, start, y) * eta
        if(np.abs(last - start) < 1e-5):
            break
        last = start
    
    return start

res_huber = gdesc(0, grad_huber_loss, 0.5)
res_squared = gdesc(0, grad_squared_loss, 0.5)

evalp = np.linspace(-1, 1, 100)
plt.plot(evalp, evalp*res_huber, label="Huber Loss")
plt.plot(evalp, evalp*res_squared, label="Squared Loss")
plt.plot(x, y, label="Data")
plt.plot(evalp, evalp, label="x=y")
plt.legend()
plt.show()