вопрос с fast.ai курс урок 8 г атрибут - PullRequest
0 голосов
/ 25 апреля 2020

В курсе fast.ai 2019, урок 8, есть странный атрибут g , используемый при обратном распространении, который я проверяю на наличие факела. Тензор этого атрибута не существует. Я попытался напечатать значение inp.g / out.g в методе вызова, но я получил AttributeError: у объекта 'Tensor' нет атрибута 'g', но я могу получить значение inp.g / out.g до того, как задание в обратном направлении, как работает этот атрибут g ?

class Linear():
    def __init__(self, w, b):
        self.w, self.b = w, b

    def __call__(self, inp):
        print('in lin call')
        self.inp = inp
        self.out = inp@self.w + self.b
        try:
            print('out.g', self.out.g)
        except Exception as e:
            print('out.g dne yet')
        return self.out

    def backward(self):
        print('out.g', self.out.g)
        self.inp.g = self.out.g @ self.w.t()
        self.w.g = (self.inp.unsqueeze(-1) * self.out.g.unsqueeze(1)).sum(0)
        self.b.g = self.out.g.sum(0)

ссылка на полный код курса

-update-

Я могу понять, что значение self.out.g точно такое же, как функция стоимости MSE self.inp.g, но все еще не могу понять, как значение передается в последний линейный слой.

class MSE():
    def __call__(self, inp, targ):
        self.inp = inp
        self.targ = targ
        self.out = (inp.squeeze() - targ).pow(2).mean()
        return self.out

    def backward(self):
        self.inp.g = 2. * (self.inp.squeeze() - self.targ).unsqueeze(-1) \
                        / self.targ.shape[0]
        print('in mse backward', self.inp.g)

class Model():
    def __init__(self, w1, b1, w2, b2):
        self.layers = [Lin(w1, b1), Relu(), Lin(w2, b2)]
        self.loss = Mse()

    def __call__(self, x, targ):
        for l in self.layers:
            x = l(x)
        return self.loss(x, targ)

    def backward(self):
        self.loss.backward()
        for l in reversed(self.layers):
            l.backward()

1 Ответ

0 голосов
/ 26 апреля 2020

в основном это связано с тем, как работают python назначения (указатели, аналогично тому, как C указатели работают). После отслеживания переменных с идентификатором ( имя переменной ) я могу выяснить, как обстоят дела с атрибутом g .

# ... in model (forward pass)...
    x = layer(x) # from linear layer >> return self.out and is assigned to x

# ...
    return self.loss(x, targ) # x is the same x (id) obtained from the model

# ========

# ... in model (backward pass) ...
    self.loss.backward() # this is how the self.inp.g came by 

# ... in linear ...
    self.inp.g = self.out.g @ self.w.t() 
    # this self.out.g is the same instance as self.inp.g from loss 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...