Отсоединить промежуточный модуль в Pytorch с учетом части потерь - PullRequest
0 голосов
/ 29 мая 2018

Допустим, у меня есть следующий проход вперед, который приводит к двум отдельным потерям:

forward(self, input)
    x = self.layer1(input)

    y = self.layer2(x)

    z = self.layer3(y)

    return y, z

Затем мы рассчитываем потери 1 (у) и потери 2 (г).Тогда мы можем оптимизировать loss = loss1 + loss2 с помощью одного оптимизатора.

Но у меня есть два предостережения: (1) я хочу, чтобы d_loss1 вычислялся только для layer2 (без layer1), и (2) я хочу d_loss2рассчитывается в отношении layer3 и layer1 - без layer2.По сути, я хочу обучать непоследовательные части сети отдельно с отдельными потерями.

Я полагаю, что могу решить (1), введя стоп-градиент на входе для layer2 следующим образом:

forward(self, input)
    x = self.layer1(input)

    y = self.layer2(x)
    y_stop_gradient = self.layer2(Variable(x.data))

    z = self.layer3(y)

    return y_stop_gradient, z

Но как я могу решить (2)?Другими словами, я хочу, чтобы градиенты loss2 «пропускали» layer2 , в то же время сохраняя layer2 обучаемым в отношении loss1.

1 Ответ

0 голосов
/ 30 мая 2018

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

Мое решение выглядит так:

import copy
forward(self, input)
    x = self.layer1(input)

    y = copy.deepcopy(self.layer2)(x)  # create a full copy of the layer
    y_stop_gradient = self.layer2(Variable(x.data))

    z = self.layer3(y)

    return y_stop_gradient, z

Это решение неэффективно, потому что (1) я думаю, что глубокое копирование излишне из-за того, что я пытаюсь сделать, и слишком дорого, и (2) градиенты для layer2 относительно z по-прежнему рассчитываются, онипросто не используются.

...