Files
2026-07-13 13:30:25 +08:00

68 lines
2.1 KiB
Python
Executable File

import numpy as np
from prml.nn.optimizer.optimizer import Optimizer
class Adam(Optimizer):
"""
Adam optimizer
initialization
m1 = 0 (Initial 1st moment of gradient)
m2 = 0 (Initial 2nd moment of gradient)
n_iter = 0
update rule
n_iter += 1
learning_rate *= sqrt(1 - beta2^n) / (1 - beta1^n)
m1 = beta1 * m1 + (1 - beta1) * gradient
m2 = beta2 * m2 + (1 - beta2) * gradient^2
param += learning_rate * m1 / (sqrt(m2) + epsilon)
"""
def __init__(self, parameter, learning_rate=0.001, beta1=0.9, beta2=0.999, epsilon=1e-8):
"""
construct Adam optimizer
Parameters
----------
parameters : list
list of parameters to be optimized
learning_rate : float
beta1 : float
exponential decay rate for the 1st moment
beta2 : float
exponential decay rate for the 2nd moment
epsilon : float
small constant to be added to denominator for numerical stability
Attributes
----------
n_iter : int
number of iterations performed
moment1 : dict
1st moment of each learnable parameter
moment2 : dict
2nd moment of each learnable parameter
"""
super().__init__(parameter, learning_rate)
self.beta1 = beta1
self.beta2 = beta2
self.epsilon = epsilon
self.moment1 = []
self.moment2 = []
for p in self.parameter:
self.moment1.append(np.zeros(p.shape))
self.moment2.append(np.zeros(p.shape))
def update(self):
"""
update parameter of the neural network
"""
self.increment_iteration()
lr = (
self.learning_rate
* (1 - self.beta2 ** self.n_iter) ** 0.5
/ (1 - self.beta1 ** self.n_iter))
for p, m1, m2 in zip(self.parameter, self.moment1, self.moment2):
if p.grad is None:
continue
m1 += (1 - self.beta1) * (p.grad - m1)
m2 += (1 - self.beta2) * (p.grad ** 2 - m2)
p.value += lr * m1 / (np.sqrt(m2) + self.epsilon)