在 Python 中实施 Adagrad
Implementing Adagrad in Python
我正在尝试在 Python 中实施 Adagrad。出于学习目的,我以矩阵分解为例。我将使用 Autograd 来计算梯度。
我的主要问题是执行是否正常。
问题描述
给定一个矩阵 A (M x N) 缺少一些条目,分解为大小分别为 (M x k) 和 (k X N) 的 W 和 H。目标是使用 Adagrad 学习 W 和 H。我会关注 this guide 的 Autograd 实施。
注意:我非常清楚基于 ALS 的实现非常适合。我使用 Adagrad 只是为了学习目的
习惯进口
import autograd.numpy as np
import pandas as pd
正在创建要分解的矩阵
A = np.array([[3, 4, 5, 2],
[4, 4, 3, 3],
[5, 5, 4, 3]], dtype=np.float32).T
屏蔽一个条目
A[0, 0] = np.NAN
定义代价函数
def cost(W, H):
pred = np.dot(W, H)
mask = ~np.isnan(A)
return np.sqrt(((pred - A)[mask].flatten() ** 2).mean(axis=None))
分解参数
rank = 2
learning_rate=0.01
n_steps = 10000
成本梯度 wrt 参数 W 和 H
from autograd import grad, multigrad
grad_cost= multigrad(cost, argnums=[0,1])
主要 Adagrad 例程(需要检查)
shape = A.shape
# Initialising W and H
H = np.abs(np.random.randn(rank, shape[1]))
W = np.abs(np.random.randn(shape[0], rank))
# gt_w and gt_h contain accumulation of sum of gradients
gt_w = np.zeros_like(W)
gt_h = np.zeros_like(H)
# stability factor
eps = 1e-8
print "Iteration, Cost"
for i in range(n_steps):
if i%1000==0:
print "*"*20
print i,",", cost(W, H)
# computing grad. wrt W and H
del_W, del_H = grad_cost(W, H)
# Adding square of gradient
gt_w+= np.square(del_W)
gt_h+= np.square(del_H)
# modified learning rate
mod_learning_rate_W = np.divide(learning_rate, np.sqrt(gt_w+eps))
mod_learning_rate_H = np.divide(learning_rate, np.sqrt(gt_h+eps))
W = W-del_W*mod_learning_rate_W
H = H-del_H*mod_learning_rate_H
当问题收敛并得到合理的解决方案时,我想知道实现是否正确。具体来说,梯度求和然后计算自适应学习率的理解是否正确?
粗略看一下,您的代码与 https://github.com/benbo/adagrad/blob/master/adagrad.py
中的代码非常匹配
del_W, del_H = grad_cost(W, H)
匹配
grad=f_grad(w,sd,*args)
gt_w+= np.square(del_W)
gt_h+= np.square(del_H)
匹配
gti+=grad**2
mod_learning_rate_W = np.divide(learning_rate, np.sqrt(gt_w+eps))
mod_learning_rate_H = np.divide(learning_rate, np.sqrt(gt_h+eps))
匹配
adjusted_grad = grad / (fudge_factor + np.sqrt(gti))
W = W-del_W*mod_learning_rate_W
H = H-del_H*mod_learning_rate_H
匹配
w = w - stepsize*adjusted_grad
因此,假设 adagrad.py
是正确的并且翻译是正确的,那么您的代码就会正确。 (共识并不能证明你的代码是正确的,但它可能是一个提示)
我正在尝试在 Python 中实施 Adagrad。出于学习目的,我以矩阵分解为例。我将使用 Autograd 来计算梯度。
我的主要问题是执行是否正常。
问题描述
给定一个矩阵 A (M x N) 缺少一些条目,分解为大小分别为 (M x k) 和 (k X N) 的 W 和 H。目标是使用 Adagrad 学习 W 和 H。我会关注 this guide 的 Autograd 实施。
注意:我非常清楚基于 ALS 的实现非常适合。我使用 Adagrad 只是为了学习目的
习惯进口
import autograd.numpy as np
import pandas as pd
正在创建要分解的矩阵
A = np.array([[3, 4, 5, 2],
[4, 4, 3, 3],
[5, 5, 4, 3]], dtype=np.float32).T
屏蔽一个条目
A[0, 0] = np.NAN
定义代价函数
def cost(W, H):
pred = np.dot(W, H)
mask = ~np.isnan(A)
return np.sqrt(((pred - A)[mask].flatten() ** 2).mean(axis=None))
分解参数
rank = 2
learning_rate=0.01
n_steps = 10000
成本梯度 wrt 参数 W 和 H
from autograd import grad, multigrad
grad_cost= multigrad(cost, argnums=[0,1])
主要 Adagrad 例程(需要检查)
shape = A.shape
# Initialising W and H
H = np.abs(np.random.randn(rank, shape[1]))
W = np.abs(np.random.randn(shape[0], rank))
# gt_w and gt_h contain accumulation of sum of gradients
gt_w = np.zeros_like(W)
gt_h = np.zeros_like(H)
# stability factor
eps = 1e-8
print "Iteration, Cost"
for i in range(n_steps):
if i%1000==0:
print "*"*20
print i,",", cost(W, H)
# computing grad. wrt W and H
del_W, del_H = grad_cost(W, H)
# Adding square of gradient
gt_w+= np.square(del_W)
gt_h+= np.square(del_H)
# modified learning rate
mod_learning_rate_W = np.divide(learning_rate, np.sqrt(gt_w+eps))
mod_learning_rate_H = np.divide(learning_rate, np.sqrt(gt_h+eps))
W = W-del_W*mod_learning_rate_W
H = H-del_H*mod_learning_rate_H
当问题收敛并得到合理的解决方案时,我想知道实现是否正确。具体来说,梯度求和然后计算自适应学习率的理解是否正确?
粗略看一下,您的代码与 https://github.com/benbo/adagrad/blob/master/adagrad.py
中的代码非常匹配del_W, del_H = grad_cost(W, H)
匹配
grad=f_grad(w,sd,*args)
gt_w+= np.square(del_W) gt_h+= np.square(del_H)
匹配
gti+=grad**2
mod_learning_rate_W = np.divide(learning_rate, np.sqrt(gt_w+eps)) mod_learning_rate_H = np.divide(learning_rate, np.sqrt(gt_h+eps))
匹配
adjusted_grad = grad / (fudge_factor + np.sqrt(gti))
W = W-del_W*mod_learning_rate_W H = H-del_H*mod_learning_rate_H
匹配
w = w - stepsize*adjusted_grad
因此,假设 adagrad.py
是正确的并且翻译是正确的,那么您的代码就会正确。 (共识并不能证明你的代码是正确的,但它可能是一个提示)