Как я могу рассчитать градиенты сети с весами .rt для всех входов в PyTorch? - PullRequest
0 голосов
/ 06 мая 2019

Я пытаюсь выяснить, как я могу рассчитать градиент сети для каждого входа.И я немного растерялся.По сути, я бы хотел рассчитать d self.output / d weight1 и d self.output / d weight2 для всех значений ввода x.Итак, у меня была бы матрица размера (1000, 5), например.Где 1000 - это размер входного значения x, а 5 - количество весов в слое.

В приведенном ниже примере весы возвращаются как размер (1,5).Что именно здесь рассчитывается?Это d self.output / d weight1 для 1 входа по x или среднее значение по всем входам?

Во-вторых, будет ли матрица features.grad и weight1.grad такой же, как я спрашиваю?Матрица всех градиентов веса1 для всех значений x.

class Network(torch.nn.Module):

    def __init__(self, iNode, hNode, oNode):
        super(Network, self).__init__()

        print("Building Model...")

        iNode = int(iNode) ; self.iNode = iNode
        hNode = int(hNode) ; self.hNode = hNode
        oNode = int(oNode) ; self.oNode = oNode

        self.fc1 = nn.Linear(iNode, hNode, bias=False)
        self.fc2 = nn.Linear(hNode, oNode, bias=False)

    def forward(self, x):
        self.hidden_probs = self.fc1(x)
        self.hidden = self.actFunc1(self.hidden_probs)
        self.output_probs = self.fc2(self.hidden)
        self.output = self.actFunc2(self.output_probs)
        return self.output

    def actFunc1(self, x):
        return 1.0/(1.0+torch.exp(-x))

    def actFunc2(self, x):
        return x

    def trainData(self, features, labels, epochs, alpha, optimisation, verbose=False):

        for epoch in range(0,epochs):
            net_pred = self.forward(features)
            net_pred.backward(gradient=torch.ones(features.size())) #calc. dout/dw for all w
print(features.grad.size()) #returns (1000,1)



            with torch.no_grad():
                for name, param in self.named_parameters():
                    if(param.requires_grad):
                        param -= alpha*param.grad

                for name, param in self.named_parameters():
                    if(param.requires_grad):
                        param.grad.zero_()


            sys.stdout.write("Epoch: %06i\r" % (epoch))
            sys.stdout.flush()
        sys.stdout.write("\n")


1 Ответ

1 голос
/ 06 мая 2019

Я не уверен, что именно вы пытаетесь достичь, потому что обычно вы работаете только с суммой градиентов (d output) / (параметр d), а не с любыми другими градиентами между ними, поскольку autograd позаботится об этом, но пустья пытаюсь ответить.

Вопрос 1

Пример, который я включил ниже, возвращает веса как размер (1,5).Что именно здесь рассчитывается?Это d self.output / d weight1 для 1 ввода x или среднее значение для всех входов?

Вы получаете размер (1,5), потому что обучение выполняется в мини-пакетах, то есть градиентахдля каждой точки данных относительно (5) весовые коэффициенты рассчитываются и суммируются по мини-партии.Согласно документам:

Этот атрибут по умолчанию имеет значение None и становится тензором при первом обращении к backward () для вычисления градиентов для себя.Атрибут затем будет содержать вычисленные градиенты, и будущие вызовы backward () будут накапливать (добавлять) градиенты в него.

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

Вопрос 2

Пример может дать более глубокое понимание:

    import torch
    x = torch.tensor([1.5], requires_grad=True)
    a = torch.nn.Parameter(torch.tensor([2.]))
    b = torch.nn.Parameter(torch.tensor([10.]))
    y = x*a
    z = y+0.5*b
    temp = z.backward()
    print('gradients of a: %0.2f and b: %0.2f' % (a.grad.item(), b.grad.item()))

Я начинаю с двух параметров, a и b, и вычисляю z=a*x+0.5*b.Градиенты еще не рассчитаны, pytorch отслеживает только историю операций, поэтому все атрибуты .grad пусты.Когда вызывается z.backward(), вычисляются градиенты выходных данных относительно параметров, которые вы можете просмотреть, вызвав grad для параметров.

Обновление параметров может быть затем выполнено, как вы уже делаете a -= alpha*a.grad.

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