Численная эквивалентность обратного распространения PyTorch - PullRequest
1 голос
/ 24 июня 2019

После того, как я написал простую нейронную сеть с numpy, я хотел сравнить ее численно с имплементацией PyTorch.Запуск в одиночку, кажется, моя реализация нейронной сети сходится, поэтому, похоже, нет ошибок.Также я проверил, что прямой проход соответствует PyTorch, поэтому базовая настройка верна.

Но при обратном проходе происходит нечто иное, потому что веса после одного обратного распространения отличаются.

Я не хочу размещать полный код здесь, потому что он связан с несколькими файлами .py, и большая часть кода не имеет отношения к вопросу.Я просто хочу знать, имеет ли PyTorch «базовый» градиентный спуск или что-то другое.

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

self.weight +=  self.learning_rate * hidden_layer.T.dot(output_delta )

, где

output_delta  = self.expected -  self.output

self.expected - ожидаемое значение, self.output - результат прямого прохода

Здесь нет активации или других действий.

Прошлый факел:

optimizer = torch.optim.SGD(nn.parameters() , lr = 1.0)

criterion = torch.nn.MSELoss(reduction='sum')   


output = nn.forward(x_train)


loss = criterion(output, y_train)

loss.backward()

optimizer.step()

optimizer.zero_grad()

Так что возможно, что с оптимизатором SGD и MSELoss он использует какую-то другую функцию дельты или обратного распространения, а не базовую, упомянутую выше?Если это так, мне бы хотелось узнать, как численно проверить моё решение с помощью pytorch.

1 Ответ

1 голос
/ 25 июня 2019

Я просто хочу знать, делает ли PyTorch "базовый" градиентный спуск или что-то другое.

Если вы установите torch.optim.SGD, это означает стохастический градиентный спуск. У вас есть разные реализации в GD, но та, которая используется в PyTorch, применяется к мини-пакетам.

Существуют реализации GD, которые оптимизируют параметры после полной эпохи. Как вы можете догадаться, они очень «медленные», это может быть полезно для тестирования суперкомпьютеров. Существуют реализации GD, которые работают для каждого образца, так как вы можете догадаться, что их несовершенство - это «огромные» градиентные флуктуации.

Это все относительные термины, поэтому я использую ""

Обратите внимание, что вы используете слишком большие скорости обучения, такие как lr = 1.0, что означает, что вы сначала не нормализовали свои данные, но это навык, который вы можете скальпировать со временем.

Так что возможно, что с оптимизатором SGD и MSELoss он использует какую-то другую функцию дельты или обратного распространения, а не базовую, упомянутую выше?

Использует то, что вы сказали.

Вот пример в PyTorch и в Python, чтобы показать, что обнаружение градиентов работает как ожидалось (используется в обратном распространении):

x = torch.tensor([5.], requires_grad=True);
print(x) # tensor([5.], requires_grad=True)

y = 3*x**2
y.backward()
print(x.grad) # tensor([30.]) 

Как бы вы получили это значение 30 в обычном питоне?

def y(x):
    return 3*x**2

x=5
e=0.01 #etha
g=(y(x+e)-y(x))/e 
print(g) # 30.0299

Как мы и ожидали, мы получили ~ 30, было бы еще лучше с меньшим etha.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...