PyTorch Gradient Descent - PullRequest
       8

PyTorch Gradient Descent

0 голосов
/ 07 сентября 2018

Я пытаюсь вручную реализовать градиентный спуск в PyTorch как учебное упражнение.У меня есть следующее для создания моего синтетического набора данных:

import torch
torch.manual_seed(0)
N = 100
x = torch.rand(N,1)*5
# Let the following command be the true function
y = 2.3 + 5.1*x
# Get some noisy observations
y_obs = y + 2*torch.randn(N,1)

Затем я создаю свою прогностическую функцию (y_pred), как показано ниже.

w = torch.randn(1, requires_grad=True)
b = torch.randn(1, requires_grad=True)
y_pred = w*x+b
mse = torch.mean((y_pred-y_obs)**2)

, которая использует MSE для выведения весовw,b.Я использую блок ниже, чтобы обновить значения в соответствии с градиентом.

gamma = 1e-2
for i in range(100):
  w = w - gamma *w.grad
  b = b - gamma *b.grad
  mse.backward()

Однако цикл работает только в первой итерации. Вторая итерация вперед w.grad установлена ​​на None. Я вполне уверен, что причина этого в том, что я устанавливаю w как функцию самого себя (я могу ошибаться).

Вопрос в том, как правильно обновить веса с помощью информации о градиенте?

1 Ответ

0 голосов
/ 07 сентября 2018
  1. Перед применением градиентного спуска следует вызвать метод backward.
  2. Вам нужно использовать новый вес для расчета потерь на каждой итерации.
  3. Создание нового тензора без градиентной ленты на каждой итерации.

Следующий код отлично работает на моем компьютере и получает w = 5.1 & b = 2.2 после 500 итераций.

Код:

import torch
torch.manual_seed(0)
N = 100
x = torch.rand(N,1)*5
# Let the following command be the true function
y = 2.3 + 5.1*x
# Get some noisy observations
y_obs = y + 0.2*torch.randn(N,1)

w = torch.randn(1, requires_grad=True)
b = torch.randn(1, requires_grad=True)


gamma = 0.01
for i in range(500):
    print(i)
    # use new weight to calculate loss
    y_pred = w * x + b
    mse = torch.mean((y_pred - y_obs) ** 2)

    # backward
    mse.backward()
    print('w:', w)
    print('b:', b)
    print('w.grad:', w.grad)
    print('b.grad:', b.grad)

    # gradient descent, don't track
    with torch.no_grad():
        w = w - gamma * w.grad
        b = b - gamma * b.grad
    w.requires_grad = True
    b.requires_grad = True

Выход:

499
w: tensor([5.1095], requires_grad=True)
b: tensor([2.2474], requires_grad=True)
w.grad: tensor([0.0179])
b.grad: tensor([-0.0576])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...