From 9950370561a5a56765fc34ee504cefcbe8f382ee Mon Sep 17 00:00:00 2001 From: Morten Hjorth-Jensen Date: Mon, 31 Oct 2022 15:27:58 +0100 Subject: [PATCH] Create rmsprop.py --- doc/src/week39/rmsprop.py | 58 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 doc/src/week39/rmsprop.py diff --git a/doc/src/week39/rmsprop.py b/doc/src/week39/rmsprop.py new file mode 100644 index 000000000..66e01e257 --- /dev/null +++ b/doc/src/week39/rmsprop.py @@ -0,0 +1,58 @@ +# Using Autograd to calculate gradients using RMSprop and Stochastic Gradient descent +# OLS example +from random import random, seed +import numpy as np +import autograd.numpy as np +import matplotlib.pyplot as plt +from autograd import grad + +# Note change from previous example +def CostOLS(y,X,theta): + return np.sum((y-X @ theta)**2) + +n = 10000 +x = np.random.rand(n,1) +y = 2.0+3*x +4*x*x# +np.random.randn(n,1) + +X = np.c_[np.ones((n,1)), x, x*x] +XT_X = X.T @ X +theta_linreg = np.linalg.pinv(XT_X) @ (X.T @ y) +print("Own inversion") +print(theta_linreg) + + +# Note that we request the derivative wrt third argument (theta, 2 here) +training_gradient = grad(CostOLS,2) +# Define parameters for Stochastic Gradient Descent +n_epochs = 50 +M = 5 #size of each minibatch +m = int(n/M) #number of minibatches +# Guess for unknown parameters theta +theta = np.random.randn(3,1) + +# Value for learning rate +eta = 0.01 +# Value for parameter rho +rho = 0.99 +# Including AdaGrad parameter to avoid possible division by zero +delta = 1e-8 +for epoch in range(n_epochs): + Giter = np.zeros(shape=(3,3)) + for i in range(m): + random_index = M*np.random.randint(m) + xi = X[random_index:random_index+M] + yi = y[random_index:random_index+M] + gradients = (1.0/M)*training_gradient(yi, xi, theta) + # Previous value for the outer product of gradients + Previous = Giter + # Accumulated gradient +# Giter +=gradients @ gradients.T + # Scaling with rho the new and the previous results + Giter = (rho*Giter+(1-rho)*gradients*gradients) + # Taking the diagonal only and inverting + Ginverse = np.c_[eta/(delta+np.sqrt(np.diagonal(Giter)))] + # Hadamard product + update = np.multiply(Ginverse,gradients) + theta -= update +print("theta from own RMSprop") +print(theta)