python
import numpy as np
class SGDMomentum:
def __init__(self, params, lr=0.01, momentum=0.9):
self.lr = lr
self.momentum = momentum
self.velocity = [np.zeros_like(p) for p in params]
def step(self, params, grads):
for i, (p, g) in enumerate(zip(params, grads)):
self.velocity[i] = self.momentum * self.velocity[i] - self.lr * g
p += self.velocity[i] # in-place update
return params
# toy quadratic loss: L(w) = (w - 3)^2, gradient = 2(w - 3)
w = np.array([0.0])
opt = SGDMomentum([w], lr=0.1, momentum=0.9)
for step in range(20):
grad = 2 * (w - 3)
opt.step([w], [grad])
print(w) # converges toward 3.0python
import numpy as np
class Adam:
def __init__(self, params, lr=0.001, beta1=0.9, beta2=0.999, eps=1e-8):
self.lr, self.b1, self.b2, self.eps = lr, beta1, beta2, eps
self.m = [np.zeros_like(p) for p in params]
self.v = [np.zeros_like(p) for p in params]
self.t = 0
def step(self, params, grads):
self.t += 1
for i, (p, g) in enumerate(zip(params, grads)):
self.m[i] = self.b1 * self.m[i] + (1 - self.b1) * g
self.v[i] = self.b2 * self.v[i] + (1 - self.b2) * (g ** 2)
m_hat = self.m[i] / (1 - self.b1 ** self.t) # bias correction
v_hat = self.v[i] / (1 - self.b2 ** self.t)
p -= self.lr * m_hat / (np.sqrt(v_hat) + self.eps)
return params