Получение производной через torch.ge, или как явно определить производную в pytorch - PullRequest
0 голосов
/ 23 октября 2019

Я пытаюсь настроить сеть, в которой один слой отображается из действительных чисел в {0, 1} (т.е. выводит двоичные данные).

Что я пытался

Хотя я смог обнаружить, что torch.ge предоставляет такую ​​функциональность, всякий раз, когда я хочу обучить любой параметр, возникающий до того, как этот слой в сети PyTorch разрушится.

Я также пытался выяснить, есть ли какой-нибудь способ в PyTorch / autograd переопределить производную модуля вручную. В частности, в этом случае я просто хотел бы передать производную через torch.ge, не меняя ее.

Минимальный пример

Вот минимальный пример, который я создал, в котором используется типичный нейронныйСетевая обучающая структура в PyTorch.

import torch
import torch.nn as nn
import torch.optim as optim


class LinearGE(nn.Module):
    def __init__(self, features_in, features_out):
        super().__init__()
        self.fc = nn.Linear(features_in, features_out)

    def forward(self, x):
        return torch.ge(self.fc(x), 0)


x = torch.randn(size=(10, 30))
y = torch.randint(2, size=(10, 10))

# Define Model
m1 = LinearGE(30, 10)

opt = optim.SGD(m1.parameters(), lr=0.01)

crit = nn.MSELoss()

# Train Model
for x_batch, y_batch in zip(x, y):
    # zero the parameter gradients
    opt.zero_grad()

    # forward + backward + optimize
    pred = m1(x_batch)
    loss = crit(pred.float(), y_batch.float())
    loss.backward()
    opt.step()

С чем я столкнулся

При запуске приведенного выше кода возникает следующая ошибка:

File "__minimal.py", line 33, in <module>
    loss.backward()
...
RuntimeError: element 0 of tensors does not require grad and does not have a grad_fn

Эта ошибка имеет смысл, поскольку *Функция 1020 * не дифференцируется. Однако, поскольку MaxPool2D также нельзя дифференцировать, я считаю, что в PyTorch есть способы смягчения недифференцируемости.

Было бы замечательно, если бы кто-то мог указать мне на любой источник, который может помочь мне либо реализовать мойсобственный backprop для пользовательского модуля или любой способ избежать этого сообщения об ошибке.

Спасибо!

1 Ответ

1 голос
/ 23 октября 2019

Я заметил две вещи

  1. Если ваш вход x равен 10x30 (10 примеров, 30 функций), а номер узла вывода равен 10, тогда матрица параметров равна 30x10. Ожидаемая выходная матрица 10x10 (10 примеров 10 выходных узлов)

  2. ge = больше и равно. Как указано в коде, x> = 0 по элементам. Мы можем использовать relu.

class LinearGE(nn.Module):
    def __init__(self, features_in, features_out):
        super().__init__()
        self.fc = nn.Linear(features_in, features_out)
        self.relu = nn.ReLU(inplace=True)

    def forward(self, x):
        return self.relu(self.fc(x))

или torch.max

torch.max(self.fc(x), 0)[0]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...