Реализация Adagrad в Python

Я пытаюсь реализовать Adagrad в Python. Для целей обучения я использую матричную факторизацию в качестве примера. Я бы использовал Автоград для вычисления градиентов.

мой главный вопрос заключается в том, если реализация в порядке.

описание

учитывая матрицу A (M x N), имеющую некоторые отсутствующие записи, разложите на W и H, имеющие размеры (M x k) и (k X N) соответственно. Цель бы узнать W и H используя Adagrad. Я бы после данное руководство для реализации Autograd.

NB: я очень хорошо знаю, что реализация на основе 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))

разложение params

rank = 2
learning_rate=0.01
n_steps = 10000

градиент стоимости wrt params 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

в то время как проблема сходится, и я получаю разумное решение, мне было интересно, правильна ли реализация. В частности, правильно ли понимание суммы градиентов, а затем вычисление адаптивной скорости обучения или нет?

1 ответов


на беглый взгляд, ваш код близко соответствует этому в 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 правильно и перевод правильно, сделает ваш код правильный. (консенсус не доказывает, что ваш код прав, но это может быть подсказка)